/// <summary> /// Checks if two lines intersect, and if they do, gives the point at which they intersect. /// </summary> /// <param name="lineB">The line to check against.</param> /// <param name="outIntersectPoint">The point on the line where they intersect (if they do).</param> /// <returns>True if the lines intersect.</returns> /// <remarks> /// See: http://paulbourke.net/geometry/lineline2d/Helpers.cs /// </remarks> public Boolean Intersects(LineSegment lineB, ref Vector2 outIntersectPoint) { // Denominator for ua and ub are the same, so store this calculation Single d = (lineB.mPointB.Y - lineB.mPointA.Y) * (mPointB.X - mPointA.X) - (lineB.mPointB.X - lineB.mPointA.X) * (mPointB.Y - mPointA.Y); //n_a and n_b are calculated as seperate values for readability Single n_a = (lineB.mPointB.X - lineB.mPointA.X) * (mPointA.Y - lineB.mPointA.Y) - (lineB.mPointB.Y - lineB.mPointA.Y) * (mPointA.X - lineB.mPointA.X); Single n_b = (mPointB.X - mPointA.X) * (mPointA.Y - lineB.mPointA.Y) - (mPointB.Y - mPointA.Y) * (mPointA.X - lineB.mPointA.X); // Make sure there is not a division by zero - this also indicates that // the lines are parallel. // If n_a and n_b were both equal to zero the lines would be on top of each // other (coincidental). This check is not done because it is not // necessary for this implementation (the parallel check accounts for this). if (d == 0) return false; // Calculate the intermediate fractional point that the lines potentially intersect. Single ua = n_a / d; Single ub = n_b / d; // The fractional point will be between 0 and 1 inclusive if the lines // intersect. If the fractional calculation is larger than 1 or smaller // than 0 the lines would need to be longer to intersect. if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d) { outIntersectPoint.X = mPointA.X + (ua * (mPointB.X - mPointA.X)); outIntersectPoint.Y = mPointA.Y + (ua * (mPointB.Y - mPointA.Y)); return true; } return false; }
/// <summary> /// Call this to initialize a Behaviour with data supplied in a file. /// </summary> /// <param name="fileName">The file to load from.</param> public override void LoadContent(String fileName) { base.LoadContent(fileName); PlayerDefinition def = GameObjectManager.pInstance.pContentManager.Load<PlayerDefinition>(fileName); mCurrentState = State.WaitForMenu; mCollisionWall = new LineSegment(); mMovementLine = new LineSegment(); mBallClassifications = new List<MBHEngineContentDefs.GameObjectDefinition.Classifications>(1); mBallClassifications.Add(MBHEngineContentDefs.GameObjectDefinition.Classifications.VOLLEY_BALL); mCollisionResults = new List<GameObject>(16); mStateTimer = StopWatchManager.pInstance.GetNewStopWatch(); mTopLeft = new Vector2(-90.0f, -80.0f); mBottomRight = new Vector2(90.0f, 0.0f); mFramesInAir = 0; mFxJump = GameObjectManager.pInstance.pContentManager.Load<SoundEffect>("Audio\\FX\\Jump"); mFxSpikeHit = GameObjectManager.pInstance.pContentManager.Load<SoundEffect>("Audio\\FX\\SpikeHit"); mFxSpikeMiss = GameObjectManager.pInstance.pContentManager.Load<SoundEffect>("Audio\\FX\\SpikeMiss"); mFxBump = GameObjectManager.pInstance.pContentManager.Load<SoundEffect>("Audio\\FX\\Bump"); mStartingRenderPriority = mParentGOH.pRenderPriority; mWalkSpeed = 3.0f; mHasMultipleHitsBeforePartner = false; mSetActiveAnimationMsg = new SpriteRender.SetActiveAnimationMessage(); mGetAttachmentPointMsg = new SpriteRender.GetAttachmentPointMessage(); mMatchRestartMsg = new OnMatchRestartMessage(); mGameRestartMsg = new OnGameRestartMessage(); mGetCurrentHitCountMsg = new HitCountDisplay.GetCurrentHitCountMessage(); mGetPartnerHitCountMsg = new Partner.GetCurrentHitCountMessage(); }
/// <summary> /// Get a line defining a particular edge of the rectangle. /// </summary> /// <param name="edge">A preallocated edge (to avoid garbage).</param> public void GetLeftEdge(ref LineSegment edge) { edge.pPointA = pTopLeft; edge.pPointB = pBottomLeft; }
/// <summary> /// Get a line defining a particular edge of the rectangle. /// </summary> /// <param name="edge">A preallocated edge (to avoid garbage).</param> public void GetBottomEdge(ref LineSegment edge) { edge.pPointA = pBottomLeft; edge.pPointB = pBottomRight; }
/// <summary> /// Get a line defining a particular edge of the rectangle. /// </summary> /// <param name="edge">A preallocated edge (to avoid garbage).</param> public void GetRightEdge(ref LineSegment edge) { edge.pPointA = pTopRight; edge.pPointB = pBottomRight; }
/// <summary> /// Get a line defining a particular edge of the rectangle. /// </summary> /// <param name="edge">A preallocated edge (to avoid garbage).</param> public void GetTopEdge(ref LineSegment edge) { edge.pPointA = pTopLeft; edge.pPointB = pTopRight; }
/// <summary> /// Call this to initialize a Behaviour with data supplied in a file. /// </summary> /// <param name="fileName">The file to load from.</param> public override void LoadContent(String fileName) { base.LoadContent(fileName); LevelDefinition def = GameObjectManager.pInstance.pContentManager.Load<LevelDefinition>(fileName); mGraph = new MBHEngine.PathFind.GenericAStar.Graph(); mMapInfo = new MapInfo(); // TODO: This should be loaded in from the def. mMapInfo.mMapWidth = (Int32)def.mMapDimensions.X; mMapInfo.mMapHeight = (Int32)def.mMapDimensions.Y; mMapInfo.mTileWidth = (Int32)def.mTileDimensions.X; mMapInfo.mTileHeight = (Int32)def.mTileDimensions.Y; // Start by creating all the tiles for this level. mCollisionGrid = new Tile[mMapInfo.mMapWidth, mMapInfo.mMapHeight]; for (Int32 y = 0; y < mMapInfo.mMapHeight; y++) { for (Int32 x = 0; x < mMapInfo.mMapWidth; x++) { mCollisionGrid[x,y] = new Tile(); // Precalculate the adjecent tiles to this one. // // Allocate space for the Array itself. mCollisionGrid[x, y].mAdjecentTiles = new Tile[(Int32)Tile.AdjacentTileDir.NUM_DIRECTIONS]; // Calculate the center point of the tile. Vector2 cent = new Vector2((x * mMapInfo.mTileWidth) + (mMapInfo.mTileWidth * 0.5f), (y * mMapInfo.mTileHeight) + (mMapInfo.mTileHeight * 0.5f)); // Create a rectangle to represent the tile. mCollisionGrid[x, y].mCollisionRect = new MBHEngine.Math.Rectangle(mMapInfo.mTileWidth, mMapInfo.mTileHeight, cent); mCollisionGrid[x, y].mGraphNode = new TileGraphNode(mCollisionGrid[x, y]); mGraph.AddNode(mCollisionGrid[x, y].mGraphNode); // Start with the tiles left of this one, but avoid looking outside the map. if (x > 0) { // Store a reference to the tile to the left. mCollisionGrid[x, y].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.LEFT] = mCollisionGrid[x - 1, y]; mCollisionGrid[x, y].mGraphNode.AddNeighbour(mCollisionGrid[x - 1, y].mGraphNode); // Since the tile to the left was created before this one, it needs to be updated to point to this // once as the tile on it right. mCollisionGrid[x - 1, y].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.RIGHT] = mCollisionGrid[x, y]; mCollisionGrid[x - 1, y].mGraphNode.AddNeighbour(mCollisionGrid[x, y].mGraphNode); // Check up and to the left if that is not outside the map. if (y > 0) { // Again, set ourselves and then the adjecent one which was created prior to us being // created. mCollisionGrid[x, y].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.LEFT_UP] = mCollisionGrid[x - 1, y - 1]; mCollisionGrid[x, y].mGraphNode.AddNeighbour(mCollisionGrid[x - 1, y - 1].mGraphNode); mCollisionGrid[x - 1, y - 1].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.RIGHT_DOWN] = mCollisionGrid[x, y]; mCollisionGrid[x - 1, y - 1].mGraphNode.AddNeighbour(mCollisionGrid[x, y].mGraphNode); } } // For tiles above. if (y > 0) { // Set our up, their down. mCollisionGrid[x, y].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.UP] = mCollisionGrid[x, y - 1]; mCollisionGrid[x, y].mGraphNode.AddNeighbour(mCollisionGrid[x, y - 1].mGraphNode); mCollisionGrid[x, y - 1].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.DOWN] = mCollisionGrid[x, y]; mCollisionGrid[x, y - 1].mGraphNode.AddNeighbour(mCollisionGrid[x, y].mGraphNode); // All that is left is the RIGHT_UP/LEFT_DOWN relationship. if (x < mMapInfo.mMapWidth - 1) { mCollisionGrid[x, y].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.RIGHT_UP] = mCollisionGrid[x + 1, y - 1]; mCollisionGrid[x, y].mGraphNode.AddNeighbour(mCollisionGrid[x + 1, y - 1].mGraphNode); mCollisionGrid[x + 1, y - 1].mAdjecentTiles[(Int32)Tile.AdjacentTileDir.LEFT_DOWN] = mCollisionGrid[x, y]; mCollisionGrid[x + 1, y - 1].mGraphNode.AddNeighbour(mCollisionGrid[x, y].mGraphNode); } } // Give it a random chance to be solid. if (RandomManager.pInstance.RandomPercent() <= 0.05f)// && false) { mCollisionGrid[x, y].mType = Level.Tile.TileTypes.Solid; GameObject.GameObject g; Single chance = (Single)RandomManager.pInstance.RandomPercent( ); if (chance < 0.2f) { g = GameObjectFactory.pInstance.GetTemplate("GameObjects\\Environments\\WallWood\\WallWood"); } else if (chance < 0.4f) { g = GameObjectFactory.pInstance.GetTemplate("GameObjects\\Environments\\WallStone\\WallStone"); } else if (chance < 0.6f) { g = GameObjectFactory.pInstance.GetTemplate("GameObjects\\Environments\\WallSteel\\WallSteel"); } else if (chance < 0.8f) { g = GameObjectFactory.pInstance.GetTemplate("GameObjects\\Items\\GunTurret\\GunTurret"); } else { g = GameObjectFactory.pInstance.GetTemplate("GameObjects\\Items\\Detector\\Detector"); } g.pPosX =(x * mMapInfo.mTileWidth) + (mMapInfo.mTileWidth * 0.5f); g.pPosY = (y * mMapInfo.mTileHeight) + (mMapInfo.mTileHeight * 0.5f); GameObjectManager.pInstance.Add(g); } DetermineAndSetImage(mCollisionGrid[x, y]); } } // Loop through all the tiles and calculate which sides need to have collision checks done on it. // For example if a tile has another tile directly above it, it does not need to check collision // on the top side, because it is not reachable. for (Int32 y = 0; y < mMapInfo.mMapHeight; y++) { for (Int32 x = 0; x < mMapInfo.mMapWidth; x++) { if ((mCollisionGrid[x, y].mType & Level.Tile.TileTypes.Solid) == Tile.TileTypes.Solid) { if (y == 0 || (mCollisionGrid[x, y - 1].mType & Level.Tile.TileTypes.Solid) != Tile.TileTypes.Solid) mCollisionGrid[x, y].mActiveWalls |= Tile.WallTypes.Top; if (x == mMapInfo.mMapWidth - 1 || (mCollisionGrid[x + 1, y].mType & Level.Tile.TileTypes.Solid) != Tile.TileTypes.Solid) mCollisionGrid[x, y].mActiveWalls |= Tile.WallTypes.Right; if (y == mMapInfo.mMapHeight - 1 || (mCollisionGrid[x, y + 1].mType & Level.Tile.TileTypes.Solid) != Tile.TileTypes.Solid) mCollisionGrid[x, y].mActiveWalls |= Tile.WallTypes.Bottom; if (x == 0 || (mCollisionGrid[x - 1, y].mType & Level.Tile.TileTypes.Solid) != Tile.TileTypes.Solid) mCollisionGrid[x, y].mActiveWalls |= Tile.WallTypes.Left; } } } // Allocate these once and use them over and over again. mCollisionWall = new LineSegment(); mCollisionRectMovement = new LineSegment(); // Load an image to use for rendering the level. mMapInfo.mTileMap = GameObjectManager.pInstance.pContentManager.Load<Texture2D> (def.mTileMapImageName); // Instantiate the NavMesh, but wait to actually initialize it. mNavMesh = new NavMesh(5); mOnNavMeshInvalidatedMsg = new Level.OnNavMeshInvalidatedMessage(); // Let the GameObjectManager know that the level data has changed. GameObjectManager.pInstance.OnMapInfoChange(mMapInfo); }
/// <summary> /// Call this to initialize a Behaviour with data supplied in a file. /// </summary> /// <param name="fileName">The file to load from.</param> public override void LoadContent(String fileName) { base.LoadContent(fileName); mCollisionWall = new LineSegment(); mBallMovementLine = new LineSegment(); mTimeOnGroundToEndPlay = StopWatchManager.pInstance.GetNewStopWatch(); mTimeOnGroundToEndPlay.pLifeTime = 10.0f; mTimeOnGroundToEndPlay.pIsPaused = true; mFxSand = GameObjectManager.pInstance.pContentManager.Load<SoundEffect>("Audio\\FX\\HitSand"); mOnGround = false; mPlayOver = false; mHasHitNet = false; mStartingRenderPriority = mParentGOH.pRenderPriority; mSetActiveAnimationMsg = new SpriteRender.SetActiveAnimationMessage(); mGetAttachmentPointMsg = new SpriteRender.GetAttachmentPointMessage(); mOnPlayOverMsg = new OnPlayOverMessage(); mOnMatchRestartMsg = new Player.OnMatchRestartMessage(); mIncrementHitCountMsg = new HitCountDisplay.IncrementHitCountMessage(); mSetServeDestinationMsg = new GetServeDestinationMessage(); mGetCurrentStateMsg = new Player.GetCurrentStateMessage(); mGetHasMultipleHitsBeforePartnerMsg = new Player.GetHasMultipleHitsBeforePartnerMessage(); }
public void AddSegment(LineSegment line, Color color) { AddSegment(line.pPointA, line.pPointB, color); }