예제 #1
0
        /// <summary>
        /// Checks if the player hits the ground or a planet.
        /// </summary>
        /// <param name="p">The player.</param>
        private void CheckAirCollision(Player p)
        {
            if (CollidesWithBorders(p))
            {
                PlacePlayerInsideLevel(p);
                if (PhysicsEngine.CollidesWithBottomBorder(p, model.Terrain))
                {
                    p.IsStandingOn = GroundTypes.Ground;
                }
            }

            p.Position += p.TotalVelocity; //Check if next position collides with terrain
            bool collision = CollisionEngine.IntersectPixels(p.WorldTransform, (int)p.Size.X, (int)p.Size.Y, p.ColorData, model.Terrain);

            //bool collision = CollisionEngine.BoundingBoxTerrainCollision(p.BoundingBox, model.Terrain);
            if (collision) //check player vs terrain
            {
                Rectangle bottomHalf = PhysicsEngine.GetBottomHalf(p.BoundingBox);
                if (BunnyGame.DebugMode)
                {
                    model.View.DrawRectangle(bottomHalf, Color.Green);
                }
                bool bottomCollision = CollisionEngine.BoundingBoxTerrainCollision(bottomHalf, model.Terrain);
                p.Position -= p.TotalVelocity;
                if (bottomCollision)
                { //bottom half collides with terrain
                    PlacePlayerOnGround(p);
                }
                else
                { //top half collides with terrain
                    p.SelfVelocity = -p.SelfVelocity;
                    p.Velocity     = -p.Velocity;
                }
            }
            else
            { //Check player vs. planets
                Planet planet = CollidesWithPlanet(p);
                if (planet != null)
                {
                    PlacePlayerOnPlanet(p, planet);
                    collision = true;
                }
                if (!collision)
                {
                    p.Position -= p.TotalVelocity;
                }
            }
        }
예제 #2
0
 public GameplayModel(BunnyGame game)
     : base(game)
 {
     GameOver           = false;
     this.game          = game;
     KillLimit          = 1000000;
     PlayerList         = new List <Player>();
     BloodParticleList  = new List <BloodParticle>();
     ProjectileList     = new List <Projectile>();
     BlackHoleList      = new List <BlackHole>();
     PlanetList         = new List <Planet>();
     EntityList         = new List <Entity>();
     PhysicalObjectList = new List <PhysicalObject>();
     GravityPointList   = new List <GravityPoint>();
     ExplosionList      = new List <Explosion>();
     collisionEngine    = new CollisionEngine(this);
     updateEngine       = new UpdateEngine(this);
     ScoreBoard         = new Dictionary <Player, Scores>();
     MaxPlayers         = 4;
     RespawnDelay       = 120;
 }
예제 #3
0
        /// <summary>
        /// Places an entity in the level so its bounding box is fully inside the level and not colliding with the terrain.
        /// </summary>
        /// <param name="e">The entity to be placed.</param>
        public void PlaceEntity(Entity e)
        {
            int  timeOutCounter = 100;
            bool freespaceFound = true;

            e.Position = new Vector2(rand.Next(Terrain.Width), rand.Next(Terrain.Height));
            do
            {
                if (CollisionEngine.BoundingBoxTerrainCollision(e.BoundingBox, Terrain) || !Terrain.IsRectangleClear(e.BoundingBox))
                {
                    freespaceFound = false;
                }
                else
                {
                    foreach (Entity e2 in EntityList)
                    {
                        if (e.BoundingBox.Intersects(e2.BoundingBox))
                        {
                            freespaceFound = false;
                        }
                    }
                }
                timeOutCounter--;
                if (timeOutCounter == 0)
                {
                    DestroyCircle((int)e.Position.X, (int)e.Position.Y, (int)(MathHelper.Max(e.Size.X, e.Size.Y) / 2));
                    freespaceFound = true;
                }
                if (!freespaceFound)
                {
                    e.Position -= new Vector2(0, e.Size.Y / 2);
                    if (e.Position.Y - e.Origin.Y < 0)
                    {
                        e.Position = new Vector2(rand.Next(Terrain.Width), rand.Next(Terrain.Height));
                    }
                }
            } while (!freespaceFound);
        }
예제 #4
0
        /// <summary>
        /// Checks if projectiles' center point will collide with terrain or players,
        /// and notifies model if it does.
        /// </summary>
        private void CalculateProjectileCollisions() //TODO: Modify method to handle bouncing projectiles, terrain-adding projectiles, etc.
        {
            int margin = 200;                        //Projectile can go this far out of screen before disappearing

            for (int i = 0; i < model.ProjectileList.Count; i++)
            {
                Projectile proj           = model.ProjectileList.ElementAt(i);
                bool       collisionFound = false;
                Vector2    originalPos    = proj.Position;
                Vector2    nextPos        = proj.Position + proj.TotalVelocity;
                Vector2    stepSize       = Vector2.Normalize(proj.TotalVelocity);
                Vector2    collisionPoint;
                do
                {
                    //Check projectile vs. terrain, if entity limit is reached use cheaper collision detection
                    bool collision = model.IsEntityLimitReached ? !model.Terrain.IsRectangleClear(proj.BoundingBox) : CollisionEngine.IntersectPixels(proj.WorldTransform, (int)proj.SourceRect.Width, (int)proj.SourceRect.Height, proj.ColorData, Matrix.Identity, model.Terrain.Width, model.Terrain.Height, model.Terrain.GetTextureColor(), out collisionPoint);
                    //if(!model.Terrain.IsPositionClear(nextStep))
                    if (collision)
                    {
                        model.TerrainHit(proj, proj.Position);
                        collisionFound = true;
                    }// Check projectile vs. black hole
                    else if (CollidesWithBlackHole(proj))
                    {
                        model.BlackHoleHit(proj);
                        collisionFound = true;
                    }
                    else if (CollidesWithPlanet(proj) != null)
                    {
                        model.PlanetHit(proj);
                        collisionFound = true;
                    }
                    else
                    {//Check projectile vs. player
                        foreach (Player p in model.PlayerList)
                        {
                            if (p.Enabled)
                            {
                                //collision = model.IsEntityLimitReached ? p.BoundingBox.Contains((int)proj.Position.X, (int)proj.Position.Y) : CollisionEngine.IntersectPixels(proj.WorldTransform, (int)proj.Size.X, (int)proj.Size.Y, proj.ColorData, p.WorldTransform, (int)p.Size.X, (int)p.Size.Y, p.ColorData);
                                collision = p.BoundingBox.Contains(proj.BoundingBox);
                                if (collision)
                                {
                                    model.PlayerHit(proj, p, proj.Position);
                                    collisionFound = true;
                                }
                            }
                        }
                        if (!collisionFound)
                        {
                            proj.Position += stepSize;
                        }
                    }
                } while (!collisionFound && Vector2.Distance(proj.Position, nextPos) < 1);

                /* Explode projectile if it hits bottom */
                if (!collisionFound && proj.Ammunition.IsExplosive && PhysicsEngine.CollidesWithBottomBorder(proj, model.Terrain))
                {
                    model.TerrainHit(proj, proj.Position);
                }

                Rectangle extendedBoundingBox = new Rectangle(0, 0, model.Terrain.Width, model.Terrain.Height);
                extendedBoundingBox.Inflate(margin, margin);

                if (!collisionFound && !extendedBoundingBox.Contains(Utility.ToPoint(proj.Position)))
                {
                    //Projectile outside level bounds
                    model.ProjectileOutsideLevelBounds(proj);
                    collisionFound = true;
                }
                proj.Position = originalPos;
            }
        }