/// <summary>
        /// This method checks if a vector collides with walls
        /// </summary>
        /// <param name="vector"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        private bool WallCollisionCheck(Vector2D vector, object obj)
        {
            double halfObj = 0;

            if (obj is Tank)
            {
                halfObj = Constant.TankSize / 2;
            }
            if (obj is Powerup)
            {
                halfObj = 10;
            }

            lock (theServerWorld)
            {
                foreach (Wall wall in theServerWorld.Walls.Values)
                {
                    if (vector.GetX() > wall.x1 - halfObj && vector.GetX() < wall.x2 + halfObj &&
                        vector.GetY() > wall.y1 - halfObj && vector.GetY() < wall.y2 + halfObj)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// This method computes the edges of the walls
        /// </summary>
        private void WallCollisionSize()
        {
            foreach (Wall wall in theServerWorld.Walls.Values)
            {
                Vector2D head = wall.endPoint1;
                Vector2D tail = wall.endPoint2;
                // check which endpoint is the head
                if (!wall.IsEndpoint1Head)
                {
                    head = wall.endPoint2;
                    tail = wall.endPoint1;
                }

                if (wall.IsHorizontal)
                {
                    wall.x1 = head.GetX() - wall.halfWallSize;
                    wall.x2 = tail.GetX() + wall.halfWallSize;
                    wall.y1 = head.GetY() - wall.halfWallSize;
                    wall.y2 = head.GetY() + wall.halfWallSize;
                }
                else
                {
                    wall.y1 = head.GetY() - wall.halfWallSize;
                    wall.y2 = tail.GetY() + wall.halfWallSize;
                    wall.x1 = head.GetX() - wall.halfWallSize;
                    wall.x2 = head.GetX() + wall.halfWallSize;
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Checks for collision between powerup and current walls.
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        private bool CheckPowerupWallCollision(Vector2D position)
        {
            bool temp = false;

            lock (world)
            {
                double x = (double)position.GetX(), y = (double)position.GetY(), worldsize = world.GetSize() / 2;
                foreach (Wall w in world.GetWalls())
                {
                    Vector2D p1 = w.p1, p2 = w.p2;
                    double   topX   = Math.Max(p1.GetX() + 35, p2.GetX() + 35);
                    double   botX   = Math.Min(p1.GetX() - 35, p2.GetX() - 35);
                    double   leftY  = Math.Min(p1.GetY() - 35, p2.GetY() - 35);
                    double   rightY = Math.Max(p1.GetY() + 35, p2.GetY() + 35);
                    if (x > botX && x < topX && y > leftY && y < rightY)
                    {
                        temp = true;
                    }
                }

                if (x < -worldsize || x > worldsize || y < -worldsize || y > worldsize)
                {
                    temp = true;
                }
            }
            return(temp);
        }
        /// <summary>
        /// Move a tank based on given tank and movement, if tank will collide with a wall, tank will not move
        /// If tank goes out of the world, tank will be wrapped back into the world
        /// </summary>
        /// <param name="movement">movement command string, either "none", "left", "right", "up", or "down"</param>
        private void HandleTankMovement(string movement, Tank tank)
        {
            if (movement != "none")
            {
                //Get the direction vector base on
                Vector2D dir = GetDirection(movement, tank);
                //Set tank's orientation base on the wasd
                tank.Orientation = dir;
                //Compute next frame location
                Vector2D nextframelocation = tank.Location + dir * _tankspeed;
                //If tank will not collide with wall and in world, the update the tank location based on current engine strength (tank speed) and given direction
                if (!CollisionDetect.ObjectWallsCollision(tank, nextframelocation, theWorld) && InWorld(nextframelocation))
                {
                    tank.Location = nextframelocation;
                }

                //Wrap around to the other side
                if (!InWorld(nextframelocation))
                {
                    //Horizontal direction
                    if (Math.Abs(nextframelocation.GetX()) > (theWorld.Size / 2))
                    {
                        tank.Location = new Vector2D(-nextframelocation.GetX(), nextframelocation.GetY());
                    }

                    //Vertical direction
                    if (Math.Abs(nextframelocation.GetY()) > (theWorld.Size / 2))
                    {
                        tank.Location = new Vector2D(nextframelocation.GetX(), -nextframelocation.GetY());
                    }
                }
            }
        }
 /// <summary>
 /// This method checks if a vector reaches the bounds of the world
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 private bool OutsideOfBoundsDetection(Vector2D vector)
 {
     if (vector.GetX() < -theServerWorld.worldSize / 2 || vector.GetX() > theServerWorld.worldSize / 2 ||
         vector.GetY() < -theServerWorld.worldSize / 2 || vector.GetY() > theServerWorld.worldSize / 2)
     {
         return(true);
     }
     return(false);
 }
Exemple #6
0
        /// <summary>
        /// Returns the wraparound position of tank when needed. Otherwise, returns original position.
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        private Vector2D TankWraparound(Vector2D position)
        {
            double   x = (double)position.GetX(), y = (double)position.GetY(), worldsize = world.GetSize() / 2;
            Vector2D temp;

            if (x < 15 - worldsize)
            {
                temp = new Vector2D(worldsize - 16, y);
            }
            else if (x > worldsize - 15)
            {
                temp = new Vector2D(16 - worldsize, y);
            }
            else if (y < 15 - worldsize)
            {
                temp = new Vector2D(x, worldsize - 16);
            }
            else if (y > worldsize - 15)
            {
                temp = new Vector2D(x, 16 - worldsize);
            }
            else
            {
                temp = new Vector2D(x, y);
            }

            return(temp);
        }
Exemple #7
0
        /// <summary>
        /// Method for calculating the tank turret direction based on the mouse location in order to send
        /// to the server.
        /// </summary>
        /// <param name="x">X location of the mouse</param>
        /// <param name="y">Y location of the mouse</param>
        public void ProcessMouseMove(double x, double y)
        {
            Vector2D loc = new Vector2D(x - Constants.ViewSize / 2, y - Constants.ViewSize / 2);

            loc.Normalize();

            commands.aiming = new Vector2D(loc.GetX(), loc.GetY());
        }
        public static void TranslateTransformToCenterPlayersView(int viewSize, int worldSize, Vector2D playerLocation, PaintEventArgs e)
        {
            double playerX           = playerLocation.GetX();
            double playerY           = playerLocation.GetY();
            double ratio             = (double)viewSize / (double)worldSize;
            int    halfSizeScaled    = (int)(worldSize / 2.0 * ratio);
            double inverseTranslateX = -WorldSpaceToImageSpace(worldSize, playerX) + halfSizeScaled;
            double inverseTranslateY = -WorldSpaceToImageSpace(worldSize, playerY) + halfSizeScaled;

            e.Graphics.TranslateTransform((float)inverseTranslateX, (float)inverseTranslateY);
        }
Exemple #9
0
        /// <summary>
        /// Handle the mouse movement via centering x and y at our tank center.
        /// We then normalize and set the Turret direction.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="mousePoint"></param>
        public void HandleMouseMovement(object sender, Vector2D mousePoint)
        {
            // x,y to be centered at our tank
            double x = mousePoint.GetX() - 450;
            double y = mousePoint.GetY() - 450;

            mousePoint = new Vector2D(x, y);
            mousePoint.Normalize();

            commands.SetTDIR(mousePoint);
        }
Exemple #10
0
        /// <summary>
        /// Checks for collision between a tank and the current walls.
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        private bool CheckTankWallCollision(Vector2D position)
        {
            bool temp = false;

            lock (world)
            {
                double x = (double)position.GetX(), y = (double)position.GetY();
                foreach (Wall w in world.GetWalls())
                {
                    Vector2D p1 = w.p1, p2 = w.p2;
                    double   topX   = Math.Max(p1.GetX() + 55, p2.GetX() + 55);
                    double   botX   = Math.Min(p1.GetX() - 55, p2.GetX() - 55);
                    double   leftY  = Math.Min(p1.GetY() - 55, p2.GetY() - 55);
                    double   rightY = Math.Max(p1.GetY() + 55, p2.GetY() + 55);
                    if (x > botX && x < topX && y > leftY && y < rightY)
                    {
                        temp = true;
                    }
                }
            }
            return(temp);
        }
Exemple #11
0
        /// <summary>
        /// Method for drawing walls
        /// </summary>
        /// <param name="o"></param>
        /// <param name="e"></param>
        private void WallDrawer(object o, PaintEventArgs e)
        {
            // checks if the image of the wall is already loaded
            // the purpose is to load the image only in 1 frame, not every frame, so improve the performance
            if (wallImg == null)
            {
                wallImg = Image.FromFile(Constant.WallFile);
            }
            Wall     w        = o as Wall;
            int      location = -(Constant.WallSize / 2);
            Vector2D head     = w.endPoint1;
            Vector2D tail     = w.endPoint2;

            // check which endpoint is the head
            if (!w.IsEndpoint1Head)
            {
                head = w.endPoint2;
                tail = w.endPoint1;
            }

            // if horizontal wall, increase X by 50 to draw the next wall
            // if vertical wall, increase Y
            if (w.IsHorizontal)
            {
                for (double i = head.GetX(); i <= tail.GetX(); i += 50.0F)
                {
                    e.Graphics.DrawImage(wallImg, location, -(Constant.WallSize / 2), Constant.WallSize, Constant.WallSize);
                    location += 50;
                }
            }
            else
            {
                for (double i = head.GetY(); i <= tail.GetY(); i += 50.0F)
                {
                    e.Graphics.DrawImage(wallImg, -(Constant.WallSize / 2), location, Constant.WallSize, Constant.WallSize);
                    location += 50;
                }
            }
        }
Exemple #12
0
 /// <summary>
 /// Compute the dot product of this vector with another vector
 /// </summary>
 /// <param name="v">The other vector</param>
 /// <returns></returns>
 public double Dot(Vector2D v)
 {
     return(GetX() * v.GetX() + GetY() * v.GetY());
 }
Exemple #13
0
        /// <summary>
        /// This method is invoked when the DrawingPanel needs to be re-drawn
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            //Makes sure world is null, since it is null while loading game
            if (theWorld != null)
            {
                //Locks world since it accesses info from it
                lock (theWorld)
                {
                    //Get player's tank to center view
                    Tank player;
                    if (theWorld.GetTank(PlayerID, out player))
                    {
                        double playerX = player.location.GetX();
                        double playerY = player.location.GetY();

                        double ratio          = (double)ViewSize / (double)theWorld.GetSize();
                        int    halfSizeScaled = (int)(theWorld.GetSize() / 2.0 * ratio);

                        double inverseTranslateX = -WorldSpaceToImageSpace(theWorld.GetSize(), playerX) + halfSizeScaled;
                        double inverseTranslateY = -WorldSpaceToImageSpace(theWorld.GetSize(), playerY) + halfSizeScaled;

                        e.Graphics.TranslateTransform((float)inverseTranslateX, (float)inverseTranslateY);
                    }

                    //Draw background
                    e.Graphics.DrawImage(Background, new Rectangle(0, 0, theWorld.GetSize(), theWorld.GetSize()));

                    // Draw the tanks
                    foreach (Tank tank in theWorld.GetTanks())
                    {
                        //Draw tank, turret, and info if tank is alive and ingame
                        if (!tank.died && !tankTimer.ContainsKey(tank) && tank.hitPoints > 0)
                        {
                            DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), tank.orientation.ToAngle(), TankDrawer);
                            DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), tank.aiming.ToAngle(), TurretDrawer);
                            DrawObjectWithTransform(e, tank, theWorld.GetSize(), tank.location.GetX(), tank.location.GetY(), 0, InfoDrawer);
                        }
                        //Otherwise, add tank to tank timer, increment tank timer, or remove tank from tank timer if it is alive
                        else
                        {
                            //If tank is a live again, remove from tank timer
                            if (tank.hitPoints > 0)
                            {
                                tankTimer.Remove(tank);
                                break;
                            }
                            //If tank is already in tank timer, decrement tank timer or remove tank from timer
                            if (tankTimer.ContainsKey(tank))
                            {
                                if (tankTimer[tank] < 200)
                                {
                                    tankTimer[tank]++;
                                }
                                else
                                {
                                    tankTimer.Remove(tank);
                                }
                            }
                            //Add tank to timer if not in timer yet
                            else
                            {
                                tankTimer.Add(tank, 0);
                            }
                        }
                    }

                    // Draw the walls
                    foreach (Wall w in theWorld.GetWalls())
                    {
                        Vector2D location = GetWallLocation(w);
                        DrawObjectWithTransform(e, w, theWorld.GetSize(), location.GetX(), location.GetY(), 0, WallDrawer);
                    }

                    //Draw beams if existed for less than 60 frames
                    List <Beam> beams = new List <Beam>(beamsTimer.Keys);
                    foreach (Beam b in beams)
                    {
                        if (beamsTimer[b] > 60)
                        {
                            beamsTimer.Remove(b);
                        }
                        //Increments beamsTimer and draws beams
                        else
                        {
                            beamsTimer[b]++;
                            DrawObjectWithTransform(e, b, theWorld.GetSize(), b.origin.GetX(), b.origin.GetY(), b.direction.ToAngle(), BeamDrawer);;
                        }
                    }

                    // Draw the powerups if not dead
                    foreach (Powerup pow in theWorld.GetPowerups())
                    {
                        if (!pow.died)
                        {
                            DrawObjectWithTransform(e, pow, theWorld.GetSize(), pow.location.GetX(), pow.location.GetY(), 0, PowerupDrawer);
                        }
                    }

                    //Draw projectiles if not dead
                    foreach (Projectile p in theWorld.GetProjectiles())
                    {
                        if (!p.died)
                        {
                            DrawObjectWithTransform(e, p, theWorld.GetSize(), p.location.GetX(), p.location.GetY(), p.orientation.ToAngle(), ProjectileDrawer);
                        }
                    }

                    //Draw tank explosions with tanks in tankTimer
                    List <Tank> tanks = new List <Tank>(tankTimer.Keys);
                    foreach (Tank t in tanks)
                    {
                        DrawObjectWithTransform(e, t, theWorld.GetSize(), t.location.GetX(), t.location.GetY(), 0, ExplosionDrawer);
                    }
                }
            }
            // Do anything that Panel (from which we inherit) needs to do
            base.OnPaint(e);
        }
Exemple #14
0
 /// <summary>
 /// Check if a given location is inside of the world
 /// </summary>
 /// <param name="loc">Vector2d representing object location</param>
 /// <returns>True if given vector is in the world, false otherwise</returns>
 private bool InWorld(Vector2D loc) => - theWorld.Size / 2 <= loc.GetX() && loc.GetX() <= theWorld.Size / 2 && -theWorld.Size / 2 <= loc.GetY() && loc.GetY() <= theWorld.Size / 2;
Exemple #15
0
 /// <summary>
 /// A range check on if object collides with within certain range
 /// </summary>
 /// <param name="xmin">x lower bound</param>
 /// <param name="xmax">x upper bound</param>
 /// <param name="ymin">y lower bound</param>
 /// <param name="ymax">y upper bound</param>
 /// <param name="input">location to check if it is specific range</param>
 /// <returns></returns>
 private static bool Collide(double xmin, double xmax, double ymin, double ymax, Vector2D input) => xmin <= input.GetX() && input.GetX() <= xmax && ymin <= input.GetY() && input.GetY() <= ymax;