public virtual void Move(MoveEventArgs e) { if (e.distance == 0) { return; } lock (privateLock) { if (!this._movable) { return; } if ((DateTime.Now - lastMoveTime).TotalSeconds < 1 / _frameRate) { return; } MoveStart?.Invoke(this); XYPosition previousPosition = _position; _position = _position + new XYPosition(e.distance * Math.Cos(e.angle), e.distance * Math.Sin(e.angle)); Debug(this, "Move from " + previousPosition.ToString() + " angle : " + e.angle + " distance : " + e.distance + " aim : " + _position.ToString()); OnMove?.Invoke(this, e, previousPosition); Debug(this, "Move result poition : " + this._position.ToString()); MoveComplete?.Invoke(this); } }
//检查childrenGameObject的位置是否合法 //目前只能检查边长为1的方块 //检查规则:任何方块的任何部分不能超出地图边界 //如果方块为可碰撞的,则方块不能与其他可碰撞方块有重叠部分。 public bool XYPositionIsLegal(XYPosition position, int objectWidth = 0, int objectHeight = 0, Layer?objectLayer = null) { DebugWithoutEndline(this, "Checking position : " + position.ToString() + " width : " + objectWidth + " height : " + objectHeight + " layer : " + objectLayer); if (!XIsLegal(position.x, objectWidth) || !YIsLegal(position.y, objectHeight)) { DebugWithoutID(this, "false"); return(false); } if (objectLayer != null && !_layerSet.ContainsKey(objectLayer)) { throw new Exception("Does not contain layer"); } for (int x = (int)position.x - 1; x <= (int)position.x + 1; x++) { for (int y = (int)position.y - 1; y <= (int)position.y + 1; y++) { if (!XIsLegal(x) || !YIsLegal(y)) { continue; } if (objectLayer != null) { foreach (var layer in objectLayer.CollisionLayers.Keys) { if (!_grid[x, y].Layers.ContainsKey(layer)) { continue; } foreach (var gameObject in _grid[x, y].Layers[layer].Keys) { if (Math.Abs(gameObject.Position.x - position.x) < 1 && Math.Abs(gameObject.Position.y - position.y) < 1) { DebugWithoutID(this, "false"); return(false); } } } } } } DebugWithoutID(this, "true"); return(true); }
//调整方块到合法位置 //目前只能调整边长为1的方块 //此函数内不可调用childrenGameObject的Position Setter,否则会触发死循环 //输入:一个GameObject(不一定是地图的子GameObject) protected XYPosition CorrectPosition(XYPosition position, int objectWidth = 1, int objectHeight = 1, Layer?objectLayer = null) { Debug(this, "Correcting Position : " + position.ToString() + " width : " + objectWidth + " height : " + objectHeight + " layer : " + objectLayer); if (XYPositionIsLegal(position, objectWidth, objectHeight, objectLayer)) { return(position); } XYPosition newCenterPosition = position.GetMid(); if (newCenterPosition.x < 0.5) { newCenterPosition = new XYPosition(0.5, newCenterPosition.y); } else if (newCenterPosition.x > (double)this._width - 0.5) { newCenterPosition = new XYPosition((double)this._width - 0.5, newCenterPosition.y); } if (newCenterPosition.y < 0.5) { newCenterPosition = new XYPosition(newCenterPosition.x, 0.5); } else if (newCenterPosition.y > (double)this._height - 0.5) { newCenterPosition = new XYPosition(newCenterPosition.x, (double)this._height - 0.5); } if (XYPositionIsLegal(newCenterPosition, objectWidth, objectHeight, objectLayer)) { return(newCenterPosition); } XYPosition testPosition = newCenterPosition; for (int round = 1; round < Math.Max(this._width, this._height); round++) { //Debug(this,"round : " + round); for (double ySearch = newCenterPosition.y - (double)round; ySearch <= newCenterPosition.y + (double)round + 0.1; ySearch += 2 * (double)round) { if (!YIsLegal(ySearch)) { continue; } for (double xSearch = newCenterPosition.x - (double)round; xSearch <= newCenterPosition.x + (double)round + 0.1; xSearch++) { if (!XIsLegal(xSearch)) { continue; } testPosition = new XYPosition(xSearch, ySearch); if (XYPositionIsLegal(testPosition, objectWidth, objectHeight, objectLayer)) { return(testPosition); } } } for (double xSearch = newCenterPosition.x - round; xSearch <= newCenterPosition.x + round + 0.1; xSearch += 2 * round) { if (!XIsLegal(xSearch)) { continue; } for (double ySearch = newCenterPosition.y - (round - 1); ySearch <= newCenterPosition.y + (round - 1) + 0.1; ySearch++) { if (!YIsLegal(ySearch)) { continue; } testPosition = new XYPosition(xSearch, ySearch); if (XYPositionIsLegal(testPosition, objectWidth, objectHeight, objectLayer)) { return(testPosition); } } } } return(new XYPosition(0, 0));//找不到合法位置,返回无效值 }
protected override void OnChildrenPositionChanged(GameObject childrenGameObject, XYPosition previousPosition, XYPosition targetPosition) { Debug(this, "Children object " + childrenGameObject.ID + " position change. from : " + previousPosition.ToString() + " aim : " + targetPosition.ToString()); //base.OnChildrenPositionChanged(childrenGameObject, e, out eOut); if (XIsLegal((int)previousPosition.x) && YIsLegal((int)previousPosition.y)) { this._grid[(int)previousPosition.x, (int)previousPosition.y].DeleteGameObject(childrenGameObject);//如果需要把childrenGameObject从Grid上拿掉且可以拿掉 } childrenGameObject._position = CorrectPosition(targetPosition, childrenGameObject.Width, childrenGameObject.Height, childrenGameObject.Layer); _grid[(int)childrenGameObject.Position.x, (int)childrenGameObject.Position.y].AddGameObject(childrenGameObject); TryToTrigger(childrenGameObject); }