public NodeRecordArray(List<NavigationGraphNode> nodes, BoundingBox mapSize) { //this method creates and initializes the NodeRecordArray for all nodes in the Navigation Graph this.NodeRecords = new NodeRecord[nodes.Count]; for (int i = 0; i < nodes.Count; i++) { var node = nodes[i]; #pragma warning disable 0618 //NodeIndex is deprecated node.NodeIndex = i; //we're setting the node Index because RAIN does not do this automatically #pragma warning restore 0618 NodeRecord nodeRecord = new NodeRecord { node = node, status = NodeStatus.Unvisited }; nodeRecord.edgeBounds = new BoundingBox[node.OutEdgeCount]; for (int j = 0; j < nodeRecord.edgeBounds.Length; j++) { BoundingBox boundingBox = new BoundingBox(); boundingBox.maxX = mapSize.minX; boundingBox.maxZ = mapSize.minZ; boundingBox.minX = mapSize.maxX; boundingBox.minZ = mapSize.maxZ; nodeRecord.edgeBounds[j] = boundingBox; } this.NodeRecords[i] = nodeRecord; } this.SpecialCaseNodes = new List<NodeRecord>(); this.Open = new NodePriorityHeap(); }
public GoalBounding(NavMeshPathGraph navMesh, BoundingBox mapSize) { //Hack to access private field with all the nodes of the mesh List<NavigationGraphNode> nodeList = (List<NavigationGraphNode>)Utils.Reflection.GetInstanceField( typeof(RAINNavigationGraph), navMesh, "_pathNodes"); nodeInfos = new NodeRecordArray(nodeList, mapSize); }
public bool isCharacterOnTile(Point2 tilePos) { BoundingBox tile = new BoundingBox(); BoundingSphere character = new BoundingSphere(); character.Center.X = m_position.X; character.Center.Y = m_position.Y; character.Radius = m_characterRadius; tile.Min.X = Map.m_staticMapInstance.getTileWidth() * tilePos.X; tile.Min.Y = Map.m_staticMapInstance.getTileHeight() * tilePos.Y; tile.Max.X = tile.Min.X + Map.m_staticMapInstance.getTileWidth(); tile.Max.Y = tile.Min.Y + Map.m_staticMapInstance.getTileHeight(); return tile.Intersects(character); }
public bool movePosition(float frameTime, Map _theMap, Character[] _characterArray, bool slideAgainstWalls, bool canUseSlides) { bool movingOnSlide = false; bool slideAgainstDiagonalWalls = slideAgainstWalls && true; bool environmentCollision = false; // todo this shouldnt be assigned here each frame m_characterRadius = m_tileSet.getTileWidth() / 2 * 8 / 10; Point2 change = new Point2(); int tileIndexX = m_position.X / _theMap.getTileWidth(); int tileIndexY = m_position.Y / _theMap.getTileHeight(); TileType tileTypeStoodOn = _theMap.getMapTileType(tileIndexX, tileIndexY); Boolean onSlide = Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides; int SLIDE_EXIT_LENGTH = 10; // If not sliding (on slide exit) then allow movement if (!onSlide) { float moveSpeed = m_moveSpeedPerSecond * frameTime; float cos = (float)Math.Cos(m_rotation); float sin = (float)Math.Sin(m_rotation); change.X = (int)( sin * moveSpeed); change.Y = (int)(-cos * moveSpeed); } Point2 newPos = new Point2(); // Velocity is only for slide movement if (m_velocity.Length() > MAX_VELOCITY) { m_velocity.Normalize(); m_velocity *= MAX_VELOCITY; } change.X += (int)(m_velocity.X * frameTime); newPos.X = m_position.X + change.X; change.Y += (int)(m_velocity.Y * frameTime); newPos.Y = m_position.Y + change.Y; if (Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides) { Vector2 targetPoint = new Vector2(); Vector2 charPoint = new Vector2(m_position.X, m_position.Y); targetPoint.X = tileIndexX * _theMap.getTileWidth() + m_tileSet.getTileWidth() / 2; targetPoint.Y = tileIndexY * _theMap.getTileHeight() + m_tileSet.getTileHeight() / 2; if (tileTypeStoodOn == TileType.SLIDE_DOWN) { targetPoint.Y += m_tileSet.getTileHeight(); } else if (tileTypeStoodOn == TileType.SLIDE_UP) { targetPoint.Y -= m_tileSet.getTileHeight(); } else if (tileTypeStoodOn == TileType.SLIDE_LEFT) { targetPoint.X -= m_tileSet.getTileWidth(); } else if (tileTypeStoodOn == TileType.SLIDE_RIGHT) { targetPoint.X += m_tileSet.getTileWidth(); } Vector2 vector = targetPoint - charPoint; // Its important this is high to keep the player in the center of the slide // So they dont come out off-center and get stuck in collision const float VELOCITY_INCREASE = 200.0f; m_velocity += vector * VELOCITY_INCREASE * frameTime; movingOnSlide = true; } else if (m_velocity.Length() > 0) { // dubious code to reduce velocity m_velocity *= (25 * frameTime); change.X += (int)(m_velocity.X * frameTime); change.Y += (int)(m_velocity.Y * frameTime); newPos.X = m_position.X + change.X; newPos.Y = m_position.Y + change.Y; if (m_velocity.Length() < SLIDE_EXIT_LENGTH) { m_velocity.X = 0; m_velocity.Y = 0; stopMovement(); } } else { newPos.X = m_position.X + change.X; newPos.Y = m_position.Y + change.Y; } Point2 lastPos = new Point2(newPos); // check per tile here if (Map.isTileTypeSlide(tileTypeStoodOn) == false && BuildConstants.COLLISION_OFF == false)// && onSlide == false)// && m_teleporting == false) { // Check against the very boundarys of the map newPos.X = capValue(newPos.X, m_characterRadius, _theMap.getWidth() - m_characterRadius); newPos.Y = capValue(newPos.Y, m_characterRadius, _theMap.getHeight() - m_characterRadius); if (lastPos.X != newPos.X || lastPos.Y != newPos.Y) { environmentCollision = true; } int minX = capValue(tileIndexX - 1, 0, _theMap.getWidth() / _theMap.getTileWidth()); int maxX = capValue(tileIndexX + 2, 0, _theMap.getWidth() / _theMap.getTileWidth()); int minY = capValue(tileIndexY - 1, 0, _theMap.getHeight() / _theMap.getTileHeight()); int maxY = capValue(tileIndexY + 2, 0, _theMap.getHeight() / _theMap.getTileHeight()); m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0); m_boundingCharCircle.Radius = m_characterRadius; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { if (x >= _theMap.getWidth() / _theMap.getTileWidth() && y >= _theMap.getHeight() / _theMap.getTileHeight()) { continue; } TileType tileType = _theMap.getMapTileType(x, y); Point2 pixel = new Point2( x * _theMap.getTileWidth(), y * _theMap.getTileHeight()); bool intersects = false; int pixelCenX = pixel.X + _theMap.getTileWidth() / 2; int pixelCenY = pixel.Y + _theMap.getTileHeight() / 2; m_boundingTileCircle.Center = new Vector3(pixelCenX, pixelCenY, 0); m_boundingTileCircle.Radius = _theMap.getTileWidth() / 2; if (Map.isTileTypeSquareBlock(tileType, m_frameIndexRendering) || (canUseSlides == false && Map.isTileTypeSlide(tileType))) { m_boundingTileBox = BoundingBox.CreateFromSphere(m_boundingTileCircle); bool localIntersects = m_boundingCharCircle.Intersects(m_boundingTileBox); if(localIntersects) { if (slideAgainstWalls) { if (GetSlidePositionOffBlock(m_position, newPos, new Point2(pixelCenX, pixelCenY), _theMap.getTileWidth(), m_characterRadius, ref newPos)) { environmentCollision = true; } } else { intersects = true; } } } else if (Map.isTileTypeCircle(tileType)) { intersects = m_boundingCharCircle.Intersects(m_boundingTileCircle); } else if (_theMap.isTileTypePixelCollision(tileType)) { TileType pixelCheckType = _theMap.GetTileTypePixelCollision(tileType); Point2 topLeft = new Point2( newPos.X - m_tileSet.getTileWidth() / 2, newPos.Y - m_tileSet.getTileHeight() / 2); bool localIntersects = m_tileSet.checkForCollision(_theMap.getTileSet(), m_frameIndexCollision, topLeft, (int)pixelCheckType, pixel); if (localIntersects && (!Map.isTileTypeDiagonalWall(tileType) || slideAgainstDiagonalWalls == false)) { intersects = localIntersects; } } if (intersects) { environmentCollision = true; newPos = new Point2(m_position); } } } // 2nd pass for diagonal walls if (slideAgainstDiagonalWalls) { TestPositionAgainDiagonalWalls(_theMap, minX, minY, maxX, maxY, ref environmentCollision, ref newPos); } m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0); m_boundingCharCircle.Radius = m_characterRadius; if (_characterArray != null) { // Check against other characters for (int c = 0; c < _characterArray.Length; c++) { if (_characterArray[c] == this || _characterArray[c].m_health <= 0 || _characterArray[c].m_finishedLevel) { continue; } BoundingSphere otherCharBounding = new BoundingSphere(); otherCharBounding.Center = new Vector3(_characterArray[c].m_position.X, _characterArray[c].m_position.Y, 0); otherCharBounding.Radius = m_characterRadius; if (m_boundingCharCircle.Intersects(otherCharBounding)) { if (m_frameIndexRendering == (int)CharacterTile.BADDY) { _characterArray[c].applyDamageDrain(frameTime, GameConstants.baddyDrainAmountPerSec); continue; } // characters are facing each other // This means if characters do occupy the same space (via resurrection or teleport) then they can still move appart else if (IsFacing(_characterArray[c])) { newPos = new Point2(m_position); } } } } } if (slideAgainstWalls) { m_position.X = newPos.X; m_position.Y = newPos.Y; } else { int realChangeX = newPos.X - m_position.X; int percentageX = 100; // This will let user get stuck on things instead of just sliding around if (change.X * change.X > realChangeX * realChangeX) { percentageX = 100 * realChangeX / change.X; } int realChangeY = newPos.Y - m_position.Y; int percentageY = 100; // This will let user get stuck on things instead of just sliding around if (change.Y * change.Y > realChangeY * realChangeY) { percentageY = 100 * realChangeY / change.Y; } int lowestPercentage = percentageX < percentageY ? percentageX : percentageY; // Calculate final position m_position.X += change.X * lowestPercentage / 100; m_position.Y += change.Y * lowestPercentage / 100; } SetMovingOnSlideState(movingOnSlide); return environmentCollision; }