Пример #1
0
 public void AddAsteroid(Asteroid asteroid, int levelWidth, int levelHeight, Random r, float frameDeltaTime)
 {
     foreach (var ast in _asteroidsInCell)
     {
         HandleCollision(ast, asteroid, levelWidth, levelHeight, r, frameDeltaTime);
     }
     _asteroidsInCell.Add(asteroid);
 }
Пример #2
0
 public void SetUpLevel(AsteroidType[] types, int asteroidPoints, Random r)
 {
     Asteroids.Clear(); //Just to make sure it's really empty
     int width = _gameMain.LevelSize.X;
     int height = _gameMain.LevelSize.Y;
     _astCells = new AstCell[width / GameMain.CELL_SIZE][];
     for (int i = 0; i < _astCells.Length; i++)
     {
         _astCells[i] = new AstCell[height / GameMain.CELL_SIZE];
         for (int j = 0; j < _astCells[i].Length; j++)
         {
             _astCells[i][j] = new AstCell();
             _astCells[i][j].PlayerIsOwedMoney += _gameMain.PayPlayer;
         }
     }
     while (asteroidPoints > 0)
     {
         var type = types[r.Next(types.Length)];
         Asteroid newAst = new Asteroid(type, width, height, r);
         Asteroids.Add(newAst);
         asteroidPoints -= newAst.Point;
     }
 }
Пример #3
0
        private List<Asteroid> SpawnAsteroids(Asteroid whichAsteroid)
        {
            var newAsteroids = new List<Asteroid>();
            if (whichAsteroid.Size == 1)
            {
                //Smallest asteroid, do nothing unless it's explosive, in which case, spawn an explosion
                //TODO: Add explosion code
                return newAsteroids;
            }
            int point = whichAsteroid.Size;

            while (point > 0)
            {
                //Continue spawning until points run out
                float addVel = 0; //for yellow asteroids, they explode fragments FAST
                int newSize = _gameMain.Random.Next(whichAsteroid.Size - 1) + 1;
                Asteroid newAsteroid = new Asteroid(whichAsteroid.AsteroidType, _gameMain.LevelSize.X, _gameMain.LevelSize.Y, _gameMain.Random);
                switch (whichAsteroid.AsteroidType)
                {
                    case AsteroidType.GENERIC:
                        newAsteroid.HP = 5 * newSize;
                        break;
                    case AsteroidType.CLUMPY:
                        newAsteroid.HP = 10 * newSize;
                        break;
                    case AsteroidType.GRAVITIC:
                        newAsteroid.HP = 10 * newSize;
                        break;
                    case AsteroidType.REPULSER:
                        newAsteroid.HP = 10 * newSize;
                        break;
                    case AsteroidType.GOLD:
                        newAsteroid.HP = 40 * newSize;
                        break;
                    case AsteroidType.MAGNETIC:
                        newAsteroid.HP = 10 * newSize;
                        break;
                    case AsteroidType.BLACK:
                        newAsteroid.HP = 5 * newSize;
                        break;
                    case AsteroidType.ZIPPY:
                        addVel = 200;
                        newAsteroid.HP = 5 * newSize;
                        break;
                    case AsteroidType.DENSE:
                        newAsteroid.HP = 50 * newSize;
                        break;
                    default:
                        newAsteroid.HP = 20 * newSize;
                        break;
                }
                newAsteroid.Size = newSize;
                newAsteroid.Radius = newAsteroid.Size * 16;
                newAsteroid.AsteroidSprite = SpriteManager.GetAsteroidSprite(newAsteroid.Size, newAsteroid.Style, _gameMain.Random);
                var randomAngle = (_gameMain.Random.Next(360) / 180.0) * Math.PI;
                float tempXVel = (float)Math.Cos(randomAngle) * (75.0f + addVel);
                float tempYVel = (float)Math.Sin(randomAngle) * (75.0f + addVel);
                newAsteroid.PositionX = whichAsteroid.PositionX;
                newAsteroid.PositionY = whichAsteroid.PositionY;
                newAsteroid.VelocityX = whichAsteroid.VelocityX + tempXVel;
                newAsteroid.VelocityY = whichAsteroid.VelocityY + tempYVel;
                point -= newAsteroid.Size;
                newAsteroids.Add(newAsteroid);
            }
            return newAsteroids;
        }
Пример #4
0
            private static void HandleCollision(Asteroid ast1, Asteroid ast2, int levelWidth, int levelHeight, Random r, float frameDeltaTime)
            {
                if (ast1.ToBeRemoved || ast2.ToBeRemoved)
                {
                    //Some asteroids have clumped together, don't calculate between any asteroids with the asteroid to be removed;
                    return;
                }

                if ((ast1.Phase < 100 && ast2.Phase >= 100) || (ast1.Phase >= 100 && ast2.Phase < 100))
                {
                    //Out of phase asteroids won't collide with each other.  Phased asteroids will collide, as non-phased asteroids will.
                    return;
                }

                //create variables that'd be easier to read than function calls
                float x1 = ast1.PositionX;
                float y1 = ast1.PositionY;
                float x2 = ast2.PositionX;
                float y2 = ast2.PositionY;

                Utility.GetClosestDistance(x1, y1, x2, y2, levelWidth, levelHeight, out x2, out y2);

                float v1x = ast1.VelocityX; //e.FrameDeltaTime is the time between frames, less than 1
                float v1y = ast1.VelocityY;
                float v2x = ast2.VelocityX;
                float v2y = ast2.VelocityY;

                //get the position plus velocity
                float tx1 = x1 + v1x * frameDeltaTime;
                float ty1 = y1 + v1y * frameDeltaTime;
                float tx2 = x2 + v2x * frameDeltaTime;
                float ty2 = y2 + v2y * frameDeltaTime;

                float dx = tx2 - tx1;
                float dy = ty2 - ty1;
                float dx2 = x2 - x1;
                float dy2 = y2 - y1;
                float r1 = (float)Math.Sqrt(dx * dx + dy * dy); //Get the distance between centers of asteroids
                float r2 = (float)Math.Sqrt(dx2 * dx2 + dy2 * dy2);

                if (r1 < ast1.Radius + ast2.Radius && r1 < r2) //Collision!
                {
                    if (!((ast1.AsteroidType == AsteroidType.CLUMPY && ast2.AsteroidType == AsteroidType.CLUMPY) && ast1.Size + ast2.Size <= 5)) //Make sure it's not clumpy asteroids that can clump together
                    {
                        //Calculate the impulse or change of momentum, or whatever people call it
                        float rx = dx / r1;
                        float ry = dy / r1;
                        float k1 = 2 * ast2.Mass * (rx * (v2x - v1x) + ry * (v2y - v1y)) / (ast1.Mass + ast2.Mass);
                        float k2 = 2 * ast1.Mass * (rx * (v1x - v2x) + ry * (v1y - v2y)) / (ast1.Mass + ast2.Mass);

                        //Adjust the velocities
                        v1x += k1 * rx;
                        v1y += k1 * ry;
                        v2x += k2 * rx;
                        v2y += k2 * ry;

                        //Assign the final value to asteroids
                        ast1.VelocityX = v1x;
                        ast1.VelocityY = v1y;
                        ast2.VelocityX = v2x;
                        ast2.VelocityY = v2y;
                    }
                    else //it's clumpy, clump them together
                    {
                        float firstAsteroidFactor = (ast1.Size * 1.0f) / (ast1.Size + ast2.Size);
                        float secondAsteroidFactor = 1.0f - firstAsteroidFactor;
                        ast1.Size += ast2.Size;
                        ast1.Radius = ast1.Size * 16;
                        ast1.Mass = ast1.Size * 300;
                        ast1.PositionX = (ast1.PositionX + ast2.PositionX) / 2;
                        ast1.PositionY = (ast1.PositionY + ast2.PositionY) / 2;
                        //Combine position and velocity:
                        ast1.VelocityX = (ast1.VelocityX * firstAsteroidFactor) + (ast2.VelocityX * secondAsteroidFactor);
                        ast1.VelocityY = (ast1.VelocityY * firstAsteroidFactor) + (ast2.VelocityY * secondAsteroidFactor);
                        ast1.AsteroidSprite = SpriteManager.GetAsteroidSprite(ast1.Size, ast1.Style, r);
                        //TODO: Combine the remaining HP

                        ast2.ToBeRemoved = true;
                    }
                }
                if ((ast1.AsteroidType == AsteroidType.REPULSER || ast2.AsteroidType == AsteroidType.REPULSER) && (r1 < ast1.Size * 64 || r1 < ast2.Size * 64))
                {
                    var degree = Math.Atan2(ty2 - ty1, tx2 - tx1);
                    float repulsingForce;
                    if (ast1.AsteroidType == AsteroidType.REPULSER && ast2.AsteroidType == AsteroidType.REPULSER)
                    {
                        if (r1 < ast1.Size * 64 && r1 < ast2.Size * 64)
                        {
                            //Double the power
                            repulsingForce = ((ast1.Size * 96) - r1) + ((ast2.Size * 96) - r1);
                        }
                        else if (r1 < ast1.Size * 64)
                        {
                            repulsingForce = ((ast1.Size * 96) - r1);
                        }
                        else
                        {
                            repulsingForce = ((ast2.Size * 96) - r1);
                        }
                    }
                    else
                    {
                        if (ast1.AsteroidType == AsteroidType.REPULSER)
                        {
                            repulsingForce = ((ast1.Size * 96) - r1);
                        }
                        else
                        {
                            repulsingForce = ((ast2.Size * 96) - r1);
                        }
                    }
                    ast2.VelocityX += (float)(repulsingForce * Math.Cos(degree) * frameDeltaTime * (ast1.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast2.VelocityY += (float)(repulsingForce * Math.Sin(degree) * frameDeltaTime * (ast1.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast1.VelocityX -= (float)(repulsingForce * Math.Cos(degree) * frameDeltaTime * (ast2.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast1.VelocityY -= (float)(repulsingForce * Math.Sin(degree) * frameDeltaTime * (ast2.Mass / (float)(ast1.Mass + ast2.Mass)));
                }
                if ((ast1.AsteroidType == AsteroidType.GRAVITIC || ast2.AsteroidType == AsteroidType.GRAVITIC) && (r1 < ast1.Size * 64 || r1 < ast2.Size * 64))
                {
                    var degree = Math.Atan2(ty2 - ty1, tx2 - tx1);
                    float graviticForce;
                    if (ast1.AsteroidType == AsteroidType.GRAVITIC && ast2.AsteroidType == AsteroidType.GRAVITIC)
                    {
                        if (r1 < ast1.Size * 64 && r1 < ast2.Size * 64)
                        {
                            //Double the power
                            graviticForce = ((ast1.Size * 96) - r1) + ((ast2.Size * 96) - r1);
                        }
                        else if (r1 < ast1.Size * 64)
                        {
                            graviticForce = ((ast1.Size * 96) - r1);
                        }
                        else
                        {
                            graviticForce = ((ast2.Size * 96) - r1);
                        }
                    }
                    else
                    {
                        if (ast1.AsteroidType == AsteroidType.REPULSER)
                        {
                            graviticForce = ((ast1.Size * 96) - r1);
                        }
                        else
                        {
                            graviticForce = ((ast2.Size * 96) - r1);
                        }
                    }
                    ast2.VelocityX -= (float)(graviticForce * Math.Cos(degree) * frameDeltaTime * (ast1.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast2.VelocityY -= (float)(graviticForce * Math.Sin(degree) * frameDeltaTime * (ast1.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast1.VelocityX += (float)(graviticForce * Math.Cos(degree) * frameDeltaTime * (ast2.Mass / (float)(ast1.Mass + ast2.Mass)));
                    ast1.VelocityY += (float)(graviticForce * Math.Sin(degree) * frameDeltaTime * (ast2.Mass / (float)(ast1.Mass + ast2.Mass)));
                }
            }