/// <summary> /// 移动指定距离是否可通行 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="distanceX"></param> /// <param name="distanceY"></param> /// <returns></returns> public bool isPassableByDistance(float x, float y, DIRS dir, float distanceX, float distanceY) { Intersection.Polygon testPolygon = Intersection.polygonMove(this.colliderPolygon, x, y); //this.currCollider(); // Debug.Log(testPolygon.points[0].x); // Debug.Log(testPolygon.points[0].y); if (dir == DIRS.DOWN) { testPolygon = Intersection.polygonMove(testPolygon, 0, -distanceY); } if (dir == DIRS.LEFT) { testPolygon = Intersection.polygonMove(testPolygon, -distanceX, 0); } if (dir == DIRS.RIGHT) { testPolygon = Intersection.polygonMove(testPolygon, distanceX, 0); } if (dir == DIRS.UP) { testPolygon = Intersection.polygonMove(testPolygon, 0, distanceY); } // Debug.Log(testPolygon.points[0].x); // Debug.Log(testPolygon.points[0].y); // Debug.Log(string.Format("GameTemp.gameMap.isPassable(testPolygon, this) {0}, {1}, {2}, {3}, {4}, {5}", // GameTemp.gameMap.isPassable(testPolygon, this), testPolygon, this.currCollider(), distanceX, distanceY, dir)); return(GameTemp.gameMap.isPassable(testPolygon, this) && GameTemp.gameMap.isPreOtherEventsPassable(testPolygon, this)); }
public GameCharacterBase() { this.originalDirection = DIRS.DOWN; // 原方向 this.originalPattern = 1; // 原图案 this.animeCount = 0; // 动画计数 this.stopCount = 0; // 停止计数 this.locked = false; // 锁的标志 this.prelockDirection = DIRS.NONE; // 被锁上前的方向 this.loopAnimNames = new List <string>(); // 循环的动画 this.moveSucceed = true; // 移动成功的标志 this.moveRoute = null; this.moveByRouteIndex = -1; this.moveWaitCount = 0; this.lastHit = new List <GameCharacterBase>(); List <Vector2> points = new List <Vector2>(); points.Add(new Vector2(0, 0)); points.Add(new Vector2(0, (Util.GRID_WIDTH - 1) / Util.PPU)); points.Add(new Vector2((Util.GRID_WIDTH - 1) / Util.PPU, (Util.GRID_WIDTH - 1) / Util.PPU)); points.Add(new Vector2((Util.GRID_WIDTH - 1) / Util.PPU, 0)); this.colliderPolygon = new Intersection.Polygon(points); }
/// <summary> /// 判定是否对于其他事件可通行,会处理事件的目标位置 /// </summary> /// <returns><c>true</c>, if pre passable was ised, <c>false</c> otherwise.</returns> /// <param name="polygon">Polygon.</param> /// <param name="character">Character.</param> public bool isPreOtherEventsPassable(Intersection.Polygon polygon, GameCharacterBase character) { if (character.through) { return(true); } // 检测事件通行 foreach (GameEvent e in this.events) { Intersection.Polygon eventTargetCollider = e.targetCollider(); if (e.through == false && Intersection.polygonPolygon(eventTargetCollider, polygon)) { if (character.GetType() == typeof(GameEvent)) { GameEvent eChar = (GameEvent)character; if (!e.erased && !e.through && e.priorityType == GameCharacterBase.PRIORITIES.SAME && e.isPageActive() && character != e && !eChar.erased && !eChar.through && eChar.priorityType == GameCharacterBase.PRIORITIES.SAME) { return(false); } } else { if (!e.erased && !e.through && e.priorityType == GameCharacterBase.PRIORITIES.SAME && e.isPageActive() && character != e) { return(false); } } } } return(true); }
/// <summary> /// 是否和人物重合 /// </summary> /// <returns><c>true</c>, if over char, <c>false</c> otherwise.</returns> /// <param name="character">Character.</param> public virtual bool isOverChar(GameCharacterBase character) { Intersection.Polygon eventCollider = character.currMidCollider(); if (Intersection.polygonPolygon(eventCollider, this.currMidCollider())) { return(true); } return(false); }
/// <summary> /// 返回面向的格子事件ID /// </summary> /// <returns></returns> public int getFaceToEventId(GameCharacterBase character) { GameEvent result = null; float step = GameTemp.gamePlayer.getStep() * 2; Intersection.Polygon testPolygon = character.currCollider(); GameCharacterBase.DIRS dir = character.direction; if (dir == GameCharacterBase.DIRS.DOWN) { testPolygon = Intersection.polygonMove(testPolygon, 0, -step); } if (dir == GameCharacterBase.DIRS.LEFT) { testPolygon = Intersection.polygonMove(testPolygon, -step, 0); } if (dir == GameCharacterBase.DIRS.RIGHT) { testPolygon = Intersection.polygonMove(testPolygon, step, 0); } if (dir == GameCharacterBase.DIRS.UP) { testPolygon = Intersection.polygonMove(testPolygon, 0, step); } List <GameEvent> events = new List <GameEvent>(); foreach (GameEvent e in this.events) { Intersection.Polygon eventCollider = e.currCollider(); if (Intersection.polygonPolygon(eventCollider, testPolygon)) { if (!e.erased && !e.Equals(character)) { events.Add(e); } } } if (events.Count > 0) { result = events[(new System.Random()).Next(events.Count)]; return(result.eventId); } return(0); }
/// <summary> /// 返回主角面向的确认键启动格子事件 /// </summary> /// <returns></returns> public GameEvent getPlayerFaceToConfirmEvent() { GameEvent result = null; float step = GameTemp.gamePlayer.getStep() * 2; Intersection.Polygon testPolygon = GameTemp.gamePlayer.currCollider(); GameCharacterBase.DIRS dir = GameTemp.gamePlayer.direction; if (dir == GameCharacterBase.DIRS.DOWN) { testPolygon = Intersection.polygonMove(testPolygon, 0, -step); } if (dir == GameCharacterBase.DIRS.LEFT) { testPolygon = Intersection.polygonMove(testPolygon, -step, 0); } if (dir == GameCharacterBase.DIRS.RIGHT) { testPolygon = Intersection.polygonMove(testPolygon, step, 0); } if (dir == GameCharacterBase.DIRS.UP) { testPolygon = Intersection.polygonMove(testPolygon, 0, step); } List <GameEvent> events = new List <GameEvent>(); foreach (GameEvent e in this.events) { Intersection.Polygon eventCollider = e.currCollider(); if (Intersection.polygonPolygon(eventCollider, testPolygon)) { if (!e.erased && e.priorityType == GameCharacterBase.PRIORITIES.SAME) { events.Add(e); } } } if (events.Count > 0) { result = events[(new System.Random()).Next(events.Count)]; } return(result); }
/// <summary> /// 朝指定方向移动是否可通行 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="dir"></param> /// <returns></returns> private bool isPassable(float x, float y, DIRS dir) { float step = this.getStep(); Intersection.Polygon testPolygon = Intersection.polygonMove(this.colliderPolygon, x, y); //this.currCollider(); if (dir == DIRS.DOWN) { testPolygon = Intersection.polygonMove(testPolygon, 0, -step); } if (dir == DIRS.LEFT) { testPolygon = Intersection.polygonMove(testPolygon, -step, 0); } if (dir == DIRS.RIGHT) { testPolygon = Intersection.polygonMove(testPolygon, step, 0); } if (dir == DIRS.UP) { testPolygon = Intersection.polygonMove(testPolygon, 0, step); } return(GameTemp.gameMap.isPassable(testPolygon, this) && GameTemp.gameMap.isPreOtherEventsPassable(testPolygon, this)); }
protected override void updateRender() { base.updateRender(); // 检测截屏 if (this.prepareFreeze) { this.prepareFreeze = false; GameObject.Destroy(this.snap.sprite); Texture2D texture = snapScreen(); Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); this.snap.sprite = sprite; return; } if (this.isInTransition()) { // 刷新渐变 if (this._transitionProgress > 0) { this._transitionProgress = Mathf.Max(this._transitionProgress - 1, 0); // Debug.Log(string.Format("this._transitionProgress {0}", this._transitionProgress)); if (this._transitionProgress == 0) { this._transitionProgress = -1; if (this.transitionFinishCallback != null) { transitionFinishCallback.Invoke(); } } } switch (this._transitionType) { case TransitionType.SNAP: this.snap.color = new Color(1, 1, 1, this.transitionProgress); break; case TransitionType.BLACK: this.transBlack.color = new Color(0, 0, 0, this.transitionProgress); break; case TransitionType.WHITE: this.transWhite.color = new Color(1, 1, 1, this.transitionProgress); break; } } if (this.isUIRunning()) { return; } // 检测切换地图 if (!"".Equals(this.mapToLoad)) { this.loadMap(this.mapToLoad); this.mapToLoad = ""; } // 刷新角色 this.player.GetComponent <SpritePlayer>().update(); // 刷新事件 foreach (GameEvent e in GameTemp.gameMap.events) { e.getEventSprite().update(); } // 刷新图片 foreach (GamePicture pic in GameTemp.gameScreen.pictures.Values) { Image img = this.pictures[pic.num]; GameObject imgObj = img.gameObject; imgObj.GetComponent <RectTransform>().localPosition = new Vector3(pic.x, pic.y, pic.num); // 位置 imgObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, pic.rotation)); // 旋转 img.color = new Color(1, 1, 1, pic.opacity / 255.0f); // 透明 imgObj.transform.localScale = new Vector3(pic.zoomX, pic.zoomY, 1); // 缩放 } // 刷新视野 GameObject.Find("Main Camera").GetComponent <Camera>().orthographicSize = GameTemp.gameScreen.currView; // 刷新摄像机 GameObject.Find("Main Camera").GetComponent <CameraControl>().update(); // 刷新对话 windowMessage.update(); // 刷新选择项 windowChoice.update(); #if UNITY_EDITOR Intersection.Polygon testPolygon = GameTemp.gamePlayer.currCollider(); Vector2 start = testPolygon.points[0]; foreach (Vector2 point in testPolygon.points) { Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(point.x, point.y, this.player.transform.position.z), Color.blue); start = point; } start = testPolygon.points[0]; Vector2 end = testPolygon.points[testPolygon.length - 1]; Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(end.x, end.y, this.player.transform.position.z), Color.blue); testPolygon = GameTemp.gamePlayer.currMidCollider(); start = testPolygon.points[0]; foreach (Vector2 point in testPolygon.points) { Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(point.x, point.y, this.player.transform.position.z), Color.yellow); start = point; } start = testPolygon.points[0]; end = testPolygon.points[testPolygon.length - 1]; Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(end.x, end.y, this.player.transform.position.z), Color.yellow); foreach (Intersection.Polygon polygon in GameTemp.gameMap.mapInfo.passageColliders) { start = polygon.points[0]; foreach (Vector2 point in polygon.points) { Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(point.x, point.y, this.player.transform.position.z), Color.red); start = point; } start = polygon.points[0]; end = polygon.points[polygon.length - 1]; Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(end.x, end.y, this.player.transform.position.z), Color.red); } foreach (GameEvent e in GameTemp.gameMap.events) { Intersection.Polygon polygon = e.currCollider(); start = polygon.points[0]; foreach (Vector2 point in polygon.points) { Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(point.x, point.y, this.player.transform.position.z), Color.green); start = point; } start = polygon.points[0]; end = polygon.points[polygon.length - 1]; Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(end.x, end.y, this.player.transform.position.z), Color.green); polygon = e.currMidCollider(); start = polygon.points[0]; foreach (Vector2 point in polygon.points) { Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(point.x, point.y, this.player.transform.position.z), Color.green); start = point; } start = polygon.points[0]; end = polygon.points[polygon.length - 1]; Debug.DrawLine(new Vector3(start.x, start.y, this.player.transform.position.z), new Vector3(end.x, end.y, this.player.transform.position.z), Color.green); } #endif }
/// <summary> /// 读取地图信息 /// </summary> /// <param name="tilemapNode"></param> public void setupMap(GameObject tilemapNode, bool isLoad = false) { this.mapName = tilemapNode.name; tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().CompressBounds(); int minX = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().cellBounds.xMin; int minY = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().cellBounds.yMin; int maxX = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().cellBounds.xMax; int maxY = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().cellBounds.yMax; foreach (string layerName in layers) { tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().CompressBounds(); minX = Mathf.Min(minX, tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().cellBounds.xMin); minY = Mathf.Min(minY, tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().cellBounds.yMin); maxX = Mathf.Max(maxX, tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().cellBounds.xMax); maxY = Mathf.Max(maxY, tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().cellBounds.yMax); Debug.Log(string.Format("min x {0}, layer:{1}", tilemapNode.transform.Find(layerName).GetComponent <Tilemap>().cellBounds.xMin, layerName)); } bool isNew = this.mapInfo == null || !tilemapNode.name.Equals(this.mapInfo.name); if (isNew) { this.mapInfo = new MapInfo(); this.mapInfo.name = tilemapNode.name; this.mapInfo.minTile = new Vector3Int(minX, minY, 0); this.mapInfo.maxTile = new Vector3Int(maxX, maxY, 0); this.mapInfo.width = maxX - minX; this.mapInfo.height = maxY - minY; this.mapInfo.minTileWorld = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().CellToWorld(new Vector3Int(minX, minY, 0)); this.mapInfo.maxTileWorld = tilemapNode.transform.Find(layers[0]).GetComponent <Tilemap>().CellToWorld(new Vector3Int(maxX, maxY, 0)); } // 读取碰撞信息 Tilemap passageLayer = tilemapNode.transform.Find(getLayerName(Layers.LayerPassage)).GetComponent <Tilemap>(); passageLayer.color = new Color(0, 0, 0, 0); passageLayer.CompressBounds(); Vector3Int min = passageLayer.cellBounds.min; Vector3Int max = passageLayer.cellBounds.max; this.mapInfo.passageColliders.Clear(); for (int x = min.x; x < max.x; x += 1) { for (int y = min.y; y < max.y; y += 1) { if (passageLayer.GetTile(new Vector3Int(x, y, min.z)) != null) { Vector3 worldPos = passageLayer.CellToWorld(new Vector3Int(x, y, min.z)); Vector3 size = passageLayer.cellSize; List <Vector2> points = new List <Vector2>(); points.Add(new Vector2(worldPos.x, worldPos.y)); points.Add(new Vector2(worldPos.x, worldPos.y + size.y)); points.Add(new Vector2(worldPos.x + size.x, worldPos.y + size.y)); points.Add(new Vector2(worldPos.x + size.x, worldPos.y)); Intersection.Polygon polygon = new Intersection.Polygon(points); this.mapInfo.passageColliders.Add(polygon); } } } if (!isLoad) // 读取事件信息 { Tilemap eventLayer = tilemapNode.transform.Find(getLayerName(Layers.LayerEvents)).GetComponent <Tilemap>(); SpriteEvent[] spriteEvents = eventLayer.GetComponentsInChildren <SpriteEvent>(); if (isNew) { this.events = new List <GameEvent>(); int i = 0; foreach (SpriteEvent s in spriteEvents) { this.events.Add((GameEvent)s.character); ((GameEvent)s.character).setup(this.mapName, i + 1); i += 1; } } else { int i = 0; foreach (SpriteEvent s in spriteEvents) { s.setEvent(this.events[i]); i += 1; } } // 初始化事件解释器 this.interpreter = new GameInterpreter(0, true); this.refresh(); } else { // 读档处理,使用读取的数据重置精灵内事件数据 Tilemap eventLayer = tilemapNode.transform.Find(getLayerName(Layers.LayerEvents)).GetComponent <Tilemap>(); SpriteEvent[] spriteEvents = eventLayer.GetComponentsInChildren <SpriteEvent>(); int i = 0; foreach (SpriteEvent s in spriteEvents) { Debug.Log(string.Format("load event {0}", i + 1)); s.setEvent(this.events[i]); this.events[i].loadInitSprite(); // 恢复事件解释器 if (i + 1 == this.interpreter.eventId) { Debug.Log(string.Format("reset interpreter for event {0}, page {1}", this.interpreter.eventId, this.interpreter.eventPageForList)); this.events[i].loadCommands(this.interpreter.eventPageForList); this.interpreter.loadList(this.events[i].list); } else { this.events[i].loadCommands(this.events[i].page); } // 重置事件的并行解释器调用公共事件部分的数据 this.events[i].loadInterpreterCommonEventList(); i += 1; } // 读档后重置公共事件解释器数据 if (this.interpreter.childInterpreter != null) { this.interpreter.childInterpreter.loadList( ((SceneMap)SceneManager.Scene).getCommonEventCmd(this.interpreter.childInterpreter.eventPageForList) ); } } Debug.Log(string.Format("setup map {0}", this.mapInfo)); }
/// <summary> /// 判断碰撞盒是否可通行 /// </summary> /// <param name="polygon"></param> /// <param name="character"></param> /// <param name="isPlayerStep">判定玩家的行走</param> /// <returns></returns> public bool isPassable(Intersection.Polygon polygon, GameCharacterBase character) { if (character.through) { return(true); } // 检测图块通行 foreach (Intersection.Polygon mapCollider in this.mapInfo.passageColliders) { if (Intersection.polygonPolygon(mapCollider, polygon)) { return(false); } } // 检测事件通行 character.lastHit.Clear(); foreach (GameEvent e in this.events) { Intersection.Polygon eventCollider = e.currCollider(); if (e.through == false && Intersection.polygonPolygon(eventCollider, polygon)) { if (character != null && character != e && !e.erased && !character.lastHit.Contains(e)) { character.lastHit.Add(e); } if (character.GetType() == typeof(GameEvent)) { GameEvent eChar = (GameEvent)character; if (!e.erased && !e.through && e.priorityType == GameCharacterBase.PRIORITIES.SAME && e.isPageActive() && character != e && !eChar.erased && !eChar.through && eChar.priorityType == GameCharacterBase.PRIORITIES.SAME) { return(false); } } else { if (!e.erased && !e.through && e.priorityType == GameCharacterBase.PRIORITIES.SAME && e.isPageActive() && character != e) { return(false); } } } } // 检查事件碰到主角 if (character.GetType() == typeof(GameEvent)) { Intersection.Polygon playerCollider = GameTemp.gamePlayer.currCollider(); GameEvent e = (GameEvent)character; if (e.through == false && Intersection.polygonPolygon(playerCollider, polygon)) { if (e != null && !e.erased && !e.lastHit.Contains(GameTemp.gamePlayer)) { e.lastHit.Add(GameTemp.gamePlayer); if (!GameTemp.gamePlayer.lastHit.Contains(e)) { GameTemp.gamePlayer.lastHit.Add(e); // 给玩家碰撞数据加上本事件 } } if (!e.erased && !e.through && e.isPageActive() && e.priorityType == GameCharacterBase.PRIORITIES.SAME) { return(false); } } } return(true); }