/// <summary> /// Runs update logic for a raycast /// </summary> /// <param name="emitPos"> Passes through ray emit vector </param> /// <param name="directionVect"> passes throguh direction vector for the ray </param> /// <param name="rayLineLength"> Passes through the max length of the ray </param> /// <param name="tiles"> Passes through the tiles on the map </param> /// <param name="angle"> Passes through the angle of the ray </param> public void Update(Vector2 emitPos, float rayLineLength, Tile[,] map, Rectangle mapArea, float angle) { directionVect = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); // Runs raycast method for and stores the returned result in RayCastLine RayCastLine = RayCastMethod(emitPos, directionVect, rayLineLength, map, mapArea, angle); // Sets global Collision Pos to the one obtained from RayCastLine CollisionPos = RayCastLine.CollisionPos; // Sets Ray line oclor based on distance from collision pos if (GetRayLength() > 400f) { RayColor = Color.Green; } else if (GetRayLength() > 250f) { RayColor = Color.Yellow; } else // if (GetRayLength<100f) { RayColor = Color.Red; } }
/// <summary> /// This method returns the the collision point and a bool stating whether a collision has been found /// </summary> /// <param name="emitPos"> Passes through the ray emitter vector </param> /// <param name="directionVect"> specifies the direction vector of the ray </param> /// <param name="rayLineLength"> Passes through the max ray length </param> /// <param name="angle"> Passes through the angle of the ray </param> /// <returns></returns> public RayCastResult RayCastMethod(Vector2 emitPos, Vector2 directionVect, float rayLineLength, Tile[,] tileMap, Rectangle mapArea, float angle) { // Sets global variables values to values btained from local variables this.emitPos = emitPos; this.directionVect = directionVect; this.rayLength = rayLineLength; this.angle = angle; // Creates an instance of rayCastResult RayCastResult castResult = new RayCastResult(); // If the rayLineLength is 0 then t if (rayLineLength == 0f) { castResult.CollisionPos = emitPos; castResult.IsColliding = (IsVectorAccessible(emitPos, tileMap, mapArea)); return(castResult); } // Normalizes direction vect so that its equivilant to one unit directionVect.Normalize(); // Returns each of the points that are in the ray an stores it in the pointsOnRay array Vector2[] pointsOnRay = GetPointsOnRay(emitPos, emitPos + (directionVect * rayLineLength)); // If theres more than 1 point on the ray run logic below if (pointsOnRay.Length > 0) { int index = 0; // If the first element is not at the emit position set the index to the last element in the array if (pointsOnRay[0] != emitPos) { index = pointsOnRay.Length - 1; } // Starts while loop while (true) { // Sets the tempPoint vector tot the point on the index Vector2 tempPoint = pointsOnRay[index]; // If the vector at the point above is not accessible then a collision point is found if (!(IsVectorAccessible(tempPoint, tileMap, mapArea))) { castResult.CollisionPos = tempPoint; castResult.IsColliding = true; break; } // If the first element in pointsOnRAy is not at the emit poisiton yet then decrement current Index if (pointsOnRay[0] != emitPos) { index--; // If the index gets out of bounds then break form the loop if (index < 0) { break; } } else // If the first index is at the emitter position incriment the index { index++; // Prevents the index from going out of bounds if (index >= pointsOnRay.Length) { break; } } } } return(castResult); }
/// <summary> /// Creates an instance of RayCastModel /// </summary> public RayCast() { RayCastLine = new RayCastResult(); }
/// <summary> /// Draws the game world /// </summary> /// <param name="sb"></param> public void DrawWorld(SpriteBatch sb) { // Draw black background sb.Draw(assets.PixelTexture, new Rectangle( -500, -500, assets.MapData.MapArea.Width + 1000, assets.MapData.MapArea.Height + 1000), Color.Black); // If the game is active if (CurState == GameEngineState.Active) { // Draw the map assets.MapData.Draw(sb); // Draw every player foreach (ClientPlayer ply in Players) { if (ply.Identifier == Client.Identifier) { Client.Draw(sb); } else { if (ply.CurrentTeam == Client.CurrentTeam) { ply.Draw(sb); } else { // Get distance between the player and the enemy Vector2 delta = ply.Position - Client.Position; // Get -2Pi - 2Pi version of the shooter's angle float angle = (float)Math.Atan2(delta.Y, delta.X); // Get the direction of the shooter Vector2 direction = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); // Get distance between the player and any possible obstacles in between the // player and the enemy RayCastResult result = raycaster.RayCastMethod(Client.Position, direction, 1280, assets.MapData.TileMap, assets.MapData.MapArea, angle); // Get the delta between the collision point and the shooter Vector2 raycastDistance = result.CollisionPos - Client.Position; if (raycastDistance.Length() > delta.Length()) { ply.Draw(sb); } } } ply.DrawRay(sb); } // Draw a white background if the player is flashed if (Flashed) { sb.Draw(assets.PixelTexture, new Rectangle((int)Client.Position.X - 640, (int)Client.Position.Y - 360, 1280, 720), Color.White * ((flashTimer * 2) / 20f)); } } }