예제 #1
0
        /// <summary>
        /// General purpose helper method that checks if an object collides with
        /// anything else in the world.
        /// </summary>
        /// <param name="o"></param> The object we want to check against everything else
        /// <param name="objectType"></param> A integer code that tells the method what kind of object o is
        /// <returns></returns>
        private bool CheckForCollision(Object o, int objectType)
        {
            //Collision flags
            bool collisionStatusX = false;
            bool collisionStatusY = false;

            //If o is a projectile
            if (objectType == 0)
            {
                Projectile proj = o as Projectile;

                //returns true if projectile if it leaves world
                if ((proj.Location.GetX() > serverWorld.Size / 2) || (proj.Location.GetX() < -(serverWorld.Size / 2)) || (proj.Location.GetY() > serverWorld.Size / 2) || (proj.Location.GetY() < -serverWorld.Size / 2))
                {
                    return(true);
                }

                //Check collsion against walls
                foreach (Wall curWall in serverWorld.Walls.Values)
                {
                    //Get range of values for x
                    double high = Math.Max(curWall.GetP2().GetX(), curWall.GetP1().GetX()) + 25;
                    double low  = Math.Min(curWall.GetP2().GetX(), curWall.GetP1().GetX()) - 25;

                    //Check if projectile is in between range of x values
                    if (proj.Location.GetX() < high && proj.Location.GetX() > low)
                    {
                        collisionStatusX = true;
                    }

                    //Get range of values for y
                    high = Math.Max(curWall.GetP2().GetY(), curWall.GetP1().GetY()) + 25;
                    low  = Math.Min(curWall.GetP2().GetY(), curWall.GetP1().GetY()) - 25;

                    //Check if projectile is in between range of y values
                    if (proj.Location.GetY() < high && proj.Location.GetY() > low)
                    {
                        collisionStatusY = true;
                    }

                    //If both are within range, projectile collided with wall so return true
                    if (collisionStatusX && collisionStatusY)
                    {
                        return(true);
                    }
                    else //Projectile did not collide with this wall, reset flags and move on to next segment
                    {
                        collisionStatusY = false;
                        collisionStatusX = false;
                        continue;
                    }
                }

                //Check collision against tanks
                lock (serverWorld.Tanks)
                {
                    foreach (Tank t in serverWorld.Tanks.Values)
                    {
                        //Create radius around tank
                        Vector2D radius = proj.Location - t.Location;

                        //If distance between projectile and tank is less than 30, its a hit
                        if (radius.Length() < 30 && proj.getOwner() != t.GetID())
                        {
                            //Can't hit a dead tank
                            if (t.HealthLevel == 0)
                            {
                                return(false);
                            }

                            //It's a hit if tank has health
                            if (t.HealthLevel > 0)
                            {
                                //decrement tank health
                                t.HealthLevel -= 1;
                            }

                            //if health is 0, then it has died
                            if (t.HealthLevel == 0)
                            {
                                t.HasDied = true;
                                //increment player score
                                serverWorld.Tanks[proj.getOwner()].Score++;
                            }
                            return(true);
                        }
                    }
                }
            }

            //object is a tank
            else if (objectType == 1)
            {
                Tank t = o as Tank;

                //Check for powerup collision and wall collision
                foreach (Wall curWall in serverWorld.Walls.Values)
                {
                    //Get range of values for x
                    double high = Math.Max(curWall.GetP2().GetX(), curWall.GetP1().GetX()) + 55;
                    double low  = Math.Min(curWall.GetP2().GetX(), curWall.GetP1().GetX()) - 55;

                    //Check if projectile is in between range of x values
                    if (t.Location.GetX() < high && t.Location.GetX() > low)
                    {
                        collisionStatusX = true;
                    }

                    //Get range of values for y
                    high = Math.Max(curWall.GetP2().GetY(), curWall.GetP1().GetY()) + 55;
                    low  = Math.Min(curWall.GetP2().GetY(), curWall.GetP1().GetY()) - 55;

                    //Check if projectile is in between range of y values
                    if (t.Location.GetY() < high && t.Location.GetY() > low)
                    {
                        collisionStatusY = true;
                    }

                    //If both are within range, projectile collided with wall so return true
                    if (collisionStatusX && collisionStatusY)
                    {
                        return(true);
                    }
                    else //Projectile did not collide with this wall, reset flags and move on to next segment
                    {
                        collisionStatusY = false;
                        collisionStatusX = false;
                        continue;
                    }
                }

                lock (serverWorld.PowerUps)
                {
                    foreach (PowerUp curPower in serverWorld.PowerUps.Values)
                    {
                        //Create radius around tank
                        Vector2D radius = curPower.position - t.Location;

                        //If distance between powerup and tank is less than 30, its a hit
                        if (radius.Length() < 30)
                        {
                            // Increment powerUp number if powerup is not collected
                            if (!curPower.collected)
                            {
                                t.CollectPowerup();
                            }

                            //Powerup has been collected
                            curPower.collected = true;
                            return(false);
                        }
                    }
                }
            }

            //object is a powerup
            else if (objectType == 2)
            {
                PowerUp power = o as PowerUp;
                foreach (Wall curWall in serverWorld.Walls.Values)
                {
                    //Get range of values for x
                    double high = Math.Max(curWall.GetP2().GetX(), curWall.GetP1().GetX()) + 25;
                    double low  = Math.Min(curWall.GetP2().GetX(), curWall.GetP1().GetX()) - 25;

                    //Check if powerUp is in between range of x values
                    if (power.position.GetX() < high && power.position.GetX() > low)
                    {
                        collisionStatusX = true;
                    }

                    //Get range of values for y
                    high = Math.Max(curWall.GetP2().GetY(), curWall.GetP1().GetY()) + 25;
                    low  = Math.Min(curWall.GetP2().GetY(), curWall.GetP1().GetY()) - 25;

                    //Check if powerUp is in between range of y values
                    if (power.position.GetY() < high && power.position.GetY() > low)
                    {
                        collisionStatusY = true;
                    }

                    //If both are within range, powerUp collided with wall so return true
                    if (collisionStatusX && collisionStatusY)
                    {
                        return(true);
                    }
                    else //PowerUp did not collide with this wall, reset flags and move on to next segment
                    {
                        collisionStatusY = false;
                        collisionStatusX = false;
                        continue;
                    }
                }

                lock (serverWorld.Tanks)
                {
                    foreach (Tank t in serverWorld.Tanks.Values)
                    {
                        //Create radius around tank
                        Vector2D radius = power.position - t.Location;

                        //If distance between powerUp and tank is less than 30, it can't spawn
                        if (radius.Length() < 30)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }