Пример #1
0
        // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // ResetGameWorld() method
        // resets variables and initializes and empties lists and objects to prepare new game
        // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public void ResetGameWorld()
        {
            _currentLives = _lives;             //reset player lives
            _score        = 0;                  //reset score
            _astDelay     = 500;                //reset asteroid tick delay
            _curAstDelay  = _astDelay;          //reset current asteroid delay

            //create new ship.
            ss = new SpaceShip(ClientRectangle.Size, new PointF(ClientRectangle.Width / 2, ClientRectangle.Height / 2));

            //clear any leftover bullets from last game
            //ss._bullets.Clear();

            //reset life display ships
            _livesDisplay = new List <SpaceShip>();
            for (int i = 1; i <= _lives; i++)
            {
                _livesDisplay.Add(new SpaceShip(ClientRectangle.Size, new PointF(i * 50, 50)));
            }

            //create initial asteroids
            _astBelt = new List <Asteroid>();
            for (int i = 0; i < _asteroidNumber; i++)
            {
                _astBelt.Add(new Asteroid(new PointF(_rng.Next(ClientRectangle.Width), _rng.Next(ClientRectangle.Height)), Asteroid.astSize.large));
            }
        }
Пример #2
0
        private void GameTimer_Tick(object sender, EventArgs e)
        {
            //double buffer graffics to remove stutter
            using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
            {
                using (BufferedGraphics bg = bgc.Allocate(CreateGraphics(), ClientRectangle))
                {
                    //if game over is false, animate and render game
                    if (!_gameOver)
                    {
                        //smooth edges of shapes
                        bg.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

                        //create black background
                        bg.Graphics.FillRectangle(new SolidBrush(Color.Black), ClientRectangle);

                        //determine if pause is selected
                        _nextPause = VGInput.pause;

                        //if pause is pressed, and not pressed last frame, toggle pause
                        if (_nextPause && !_lastPause)
                        {
                            _paused = !_paused;
                        }

                        //save current pause for next tick
                        _lastPause = _nextPause;

                        //if not paused, move each animated object and check for collisions
                        if (!_paused)
                        {
                            //add asteroid every n ticks
                            _curAstDelay--;

                            //of delay counter is finish, reset and reduce delay, add asteroid
                            if (_curAstDelay <= 0)
                            {
                                //reduce delay before asteroid spawn, limit to above 100 ticks
                                _astDelay    = (_astDelay - 20 >= 100) ? _astDelay - 20 : 100;
                                _curAstDelay = _astDelay;

                                //add new asteroid to game
                                _astBelt.Add(new Asteroid(new PointF(_rng.Next(ClientRectangle.Width), _rng.Next(ClientRectangle.Height)), Asteroid.astSize.large));
                            }

                            //tick asteroids and ship/bullets
                            _astBelt.ForEach((s) => s.Tick(ClientRectangle.Size));
                            ss.Tick(VGInput.left, VGInput.right, VGInput.thrust, VGInput.warp, VGInput.shoot, ClientRectangle.Size);

                            //check if ship is dead
                            Region shipReg = new Region(ss.GetPath());

                            //bool causes loop to exit if collision detected to prevent more than one death from being registered
                            bool exitColLoop = false;

                            //if ship is not invincible, check for collisions with asteroids
                            if (!ss._invincible)
                            {
                                //iterate through all asteroids
                                for (int i = 0; i < _astBelt.Count(); i++)
                                {
                                    //if asteroid is not fading in test for collision with ship
                                    if (_astBelt[i]._dangerous && !exitColLoop)
                                    {
                                        Region astReg = new Region(_astBelt[i].GetPath());

                                        //intersect asteroid and ship regions
                                        astReg.Intersect(shipReg);

                                        //is intersection is not empty, there is a collision
                                        if (!astReg.IsEmpty(bg.Graphics))
                                        {
                                            //kill old ship, make new one
                                            ss._alive = false;
                                            ss        = new SpaceShip(ClientRectangle.Size, new PointF(ClientRectangle.Width / 2, ClientRectangle.Height / 2));

                                            //play death sound
                                            music.Play2D("../../../wilhelm.wav", false);

                                            //don't check any more asteroids to prevent muptiple collitions
                                            exitColLoop = true;

                                            //remove life from display and counter
                                            if (_livesDisplay.Count() > 0)
                                            {
                                                _livesDisplay.RemoveAt(_livesDisplay.Count() - 1);
                                            }
                                            _currentLives--;

                                            //game over if all lives gone
                                            if (_currentLives <= 0)
                                            {
                                                _gameOver = true;
                                            }
                                        }
                                    }
                                }
                            }

                            //reset for use with bullet/asteroid collisions
                            exitColLoop = false;

                            //iterate through bullets and asteroids
                            for (int j = 0; j < ss._bullets.Count(); j++)
                            {
                                for (int k = 0; k < _astBelt.Count(); k++)
                                {
                                    //intersect bullet and asteroid regions
                                    Region bullReg = new Region(ss._bullets[j].GetPath());
                                    Region asReg   = new Region(_astBelt[k].GetPath());

                                    asReg.Intersect(bullReg);

                                    //if collision detected, kill asteroid, add score
                                    if (!asReg.IsEmpty(bg.Graphics) && !exitColLoop)
                                    {
                                        //kill asteroid and bullet
                                        ss._bullets[j]._alive       = false;
                                        _astBelt[k]._markedForDeath = true;
                                        exitColLoop = true;

                                        //check size of dead asteroid
                                        if (_astBelt[k]._astSize == Asteroid.astSize.large)
                                        {
                                            //if large, add two medium asteroids
                                            for (int l = 0; l < 2; l++)
                                            {
                                                _astBelt.Add(new Asteroid(_astBelt[k]._pos, Asteroid.astSize.medium));
                                            }

                                            //increase score for large
                                            _score += 100;
                                        }
                                        else if (_astBelt[k]._astSize == Asteroid.astSize.medium)
                                        {
                                            //if medium add 3 small
                                            for (int m = 0; m < 3; m++)
                                            {
                                                _astBelt.Add(new Asteroid(_astBelt[k]._pos, Asteroid.astSize.small));
                                            }

                                            //increase score for medium
                                            _score += 200;
                                        }
                                        else
                                        {
                                            //increase score for small
                                            _score += 300;
                                        }

                                        //see if score has reached points to extra life
                                        if (_score > _scoreToLife)
                                        {
                                            //increase lives and add to live display ship list
                                            _currentLives++;
                                            _livesDisplay.Add(new SpaceShip(ClientRectangle.Size, new PointF(_currentLives * 50, 50)));
                                            //double score needed to next life
                                            _scoreToLife *= 2;
                                        }
                                    }
                                }
                            }

                            //remove dead asteroids from list
                            _astBelt.RemoveAll(a => a._markedForDeath);
                        }
                        else
                        {
                            //if game paused display "pause" on screen
                            bg.Graphics.DrawString("Pause", new Font(FontFamily.GenericSansSerif, 60), new SolidBrush(Color.YellowGreen), ClientRectangle.Width / 2 - 130, ClientRectangle.Height / 2 - 50);
                        }

                        //display score and lives
                        _livesDisplay.ForEach(l => l.Render(bg));
                        bg.Graphics.DrawString("score: " + _score.ToString(), new Font(FontFamily.GenericSansSerif, 16), new SolidBrush(Color.GreenYellow), 20, 0);


                        //render asteroids and ship/bullets
                        _astBelt.ForEach((s) => s.Render(bg));
                        ss.Render(bg);
                    }
                    else
                    {
                        //if gameover is true, display main menu


                        bg.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        bg.Graphics.FillRectangle(new SolidBrush(Color.Black), ClientRectangle);

                        bg.Graphics.DrawString("Astheroids", new Font(FontFamily.GenericSansSerif, 100), new SolidBrush(Color.White), 160, 100);
                        bg.Graphics.DrawString("PAUSE = ESC / START", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), 0, ClientRectangle.Height - 200);
                        bg.Graphics.DrawString("SHOOT = SPACE / A BUTTON", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), 0, ClientRectangle.Height - 160);
                        bg.Graphics.DrawString("TURN = LEFT/RIGHT / RIGHT ANALOG STICK", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), 0, ClientRectangle.Height - 120);
                        bg.Graphics.DrawString("THRUST = UP / RIGHT TRIGGER", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), 0, ClientRectangle.Height - 80);
                        bg.Graphics.DrawString("WARP SPEED = W / LEFT TRIGGER", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), 0, ClientRectangle.Height - 40);
                        bg.Graphics.DrawString("SHOOT to start game", new Font(FontFamily.GenericSansSerif, 20), new SolidBrush(Color.GreenYellow), ClientRectangle.Width / 2 - 160, ClientRectangle.Height / 2);

                        //only display game over and score if a game has been finished
                        if (!firstRun)
                        {
                            bg.Graphics.DrawString("GAME OVER", new Font(FontFamily.GenericSansSerif, 80), new SolidBrush(Color.White), 150, 220);
                            bg.Graphics.DrawString("score: " + _score, new Font(FontFamily.GenericSansSerif, 40), new SolidBrush(Color.White), 320, 420);
                        }

                        //detect button press to restart game.
                        //button must be released and pressed to prevent new game from starting immediately if shoot button is held down when
                        //game ends
                        if (VGInput.shoot && !_restart)
                        {
                            //reset game world
                            _gameOver = false;
                            firstRun  = false;
                            ResetGameWorld();
                        }
                        _restart = VGInput.shoot;
                    }

                    //render graphics from backbuffer
                    bg.Render();
                }
            }
        }