Exemple #1
0
        public static void Main(string[] args)
        {
            Initialize();

            RotatingObject Ship = null;
            LinkedList <RotatingObject> Asteroids = new LinkedList <RotatingObject>();
            LinkedList <Particle>       Particles = new LinkedList <Particle>();
            LinkedList <Particle>       Shots     = new LinkedList <Particle>();
            double ToRadians = Math.PI / 180;
            double d;
            int    i, j, k;

            int[]  Radiuses;
            int[]  Angles;
            int    Level               = 0;
            int    Lives               = 3;
            int    Score               = 0;
            int    TeleportsLeft       = 3;
            int    HighScore           = 0;
            int    HighLevel           = 0;
            double ImmortalSecondsLeft = 0;
            double NewShipSecondsLeft  = 0;
            bool   Collision;
            bool   Done     = false;
            bool   GameOver = false;

            // Source of sound: http://www.freesound.org/people/jobro/sounds/35686/
            int ShotSound = UploadAudioSample(GetResourceWavAudio("35686__jobro__laser9.wav"));

            // Source of sound: http://www.freesound.org/people/Tony%20B%20kksm/sounds/80938/
            int AsteroidHitSound = UploadAudioSample(GetResourceWavAudio("80938__tony-b-kksm__soft-explosion.wav"));

            // Source of sound: http://www.freesound.org/people/sandyrb/sounds/35643/
            int ShipExplodeSound = UploadAudioSample(GetResourceWavAudio("35643__sandyrb__usat-bomb.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/172207/
            int TeleportSound = UploadAudioSample(GetResourceWavAudio("172207__fins__teleport.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/133284/
            int LevelCompletedSound = UploadAudioSample(GetResourceWavAudio("133284__fins__level-completed.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/133283/
            int GameOverSound = UploadAudioSample(GetResourceWavAudio("133283__fins__game-over.wav"));

            OpenConsoleWindow(4, 4, 35, 25, "Welcome to Asteroids.");

            WriteLine();
            WriteLine("Keys in the game:");
            WriteLine();
            WriteLine("Left: Turn ship left");
            WriteLine("Right: Turn ship right");
            WriteLine("Up: Accelerate forwards");
            WriteLine("Down: Teleport to safe location");
            WriteLine("Space: Fire");
            WriteLine("Esc: Close application");
            WriteLine("Q: Quit current game");
            WriteLine();
            WriteLine("To play, press ENTER.");

            ReadLine();
            ClearConsoleWindowArea();
            Clear();

            Write("Ships: ");
            int NrShipsPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Lives.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Hyper: ");
            int NrTeleportsPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(TeleportsLeft.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Lvl: ");
            int LevelPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Level.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Score: ");
            int ScorePos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Score.ToString("D5"));

            OnUpdateModel += (s, e) =>
            {
                if (GameOver)
                {
                    return;
                }

                double ElapsedSeconds = e.Seconds;

                if (Asteroids.First is null)
                {
                    ImmortalSecondsLeft = 4;

                    Level++;
                    GotoXY(LevelPos, 0);
                    Write(Level.ToString("D2"));

                    for (i = 0; i < 5 + 5 * Level; i++)
                    {
                        Radiuses = new int[16];
                        Angles   = new int[16];

                        for (j = 0; j < 16; j++)
                        {
                            Radiuses[j] = Random(16, 32);
                            Angles[j]   = Random(0, 359);
                        }

                        Array.Sort <int>(Angles);

                        j = Random(0, 359);
                        k = Random(200, 400);

                        Asteroids.AddLast(new RotatingObject(Radiuses, Angles,
                                                             320 + Math.Cos(j * ToRadians) * k,
                                                             240 + Math.Sin(j * ToRadians) * k,
                                                             60 * Random() - 30,
                                                             60 * Random() - 30,
                                                             0, 200 * Random() - 100));
                    }

                    if (Level > 1)
                    {
                        PlayAudioSample(LevelCompletedSound);
                    }
                }

                foreach (RotatingObject Obj in Asteroids)
                {
                    Obj.Draw(Color.Black);
                    Obj.Move(ElapsedSeconds);
                    Obj.Draw(Color.White);

                    if (!(Ship is null) && ImmortalSecondsLeft <= 0 && IntersectsPolygon(Ship.Points, Obj.Points))
                    {
                        Ship.Draw(Color.Black);

                        for (i = 0; i < 200; i++)
                        {
                            d = Random() * 360 * ToRadians;
                            j = Random(10, 100);

                            Particles.AddLast(new Particle(
                                                  Ship.X,                           // X
                                                  Ship.Y,                           // Y
                                                  Ship.VelocityX + Math.Cos(d) * j, // Velocity X
                                                  Ship.VelocityY + Math.Sin(d) * j, // Velocity Y
                                                  Blend(Color.Blue, Color.White, Random()),
                                                  4));
                        }

                        Ship = null;
                        NewShipSecondsLeft = 4;

                        PlayAudioSample(ShipExplodeSound);
                    }
                }

                if (!(Ship is null))
                {
                    Ship.Draw(Color.Black);

                    if (IsPressed(KeyCode.Left))
                    {
                        Ship.Angle -= 3;
                    }

                    if (IsPressed(KeyCode.Right))
                    {
                        Ship.Angle += 3;
                    }

                    if (IsPressed(KeyCode.Up))
                    {
                        Ship.VelocityX += Math.Cos(Ship.Angle * ToRadians) * 4;
                        Ship.VelocityY += Math.Sin(Ship.Angle * ToRadians) * 4;

                        d = (Random() * 30 - 15 + Ship.Angle + 180) * ToRadians;                     // Particle direction
                        Particles.AddLast(new Particle(
                                              Ship.X + Math.Cos((Ship.Angle + 180) * ToRadians) * 5, // X
                                              Ship.Y + Math.Sin((Ship.Angle + 180) * ToRadians) * 5, // Y
                                              Ship.VelocityX + Math.Cos(d) * 100,                    // Velocity X
                                              Ship.VelocityY + Math.Sin(d) * 100,                    // Velocity Y
                                              Blend(Color.Yellow, Color.Orange, Random()),
                                              2));
                    }

                    if (TeleportsLeft > 0 && ImmortalSecondsLeft <= 0 && IsPressed(KeyCode.Down))
                    {
                        do
                        {
                            Ship.X         = Random(50, RasterWidth - 50);
                            Ship.Y         = Random(50, RasterHeight - 50);
                            Ship.VelocityX = 0;
                            Ship.VelocityY = 0;

                            Ship.CalcPoints();

                            Collision = false;

                            foreach (RotatingObject Obj in Asteroids)
                            {
                                if (IntersectsPolygon(Obj.Points, Ship.Points))
                                {
                                    Collision = true;
                                    break;
                                }
                            }
                        }while (Collision);

                        ImmortalSecondsLeft = 4;

                        PlayAudioSample(TeleportSound);

                        TeleportsLeft--;
                        GotoXY(NrTeleportsPos, 0);
                        Write(TeleportsLeft.ToString("D2"));
                    }

                    Ship.Move(ElapsedSeconds);

                    if (ImmortalSecondsLeft > 0)
                    {
                        ImmortalSecondsLeft -= ElapsedSeconds;

                        if (Math.IEEERemainder(ImmortalSecondsLeft, 0.5) < 0)
                        {
                            Ship.Draw(Blend(Color.Blue, Color.White, 0.5));
                        }
                        else
                        {
                            Ship.Draw(Color.White);
                        }
                    }
                    else
                    {
                        Ship.Draw(Color.White);
                    }
                }
Exemple #2
0
        public static void Main(string[] args)
        {
            Initialize();

            RotatingObject Ship = null;
            LinkedList<RotatingObject> Asteroids = new LinkedList<RotatingObject>();
            LinkedList<Particle> Particles = new LinkedList<Particle>();
            LinkedList<Particle> Shots = new LinkedList<Particle>();
            double ToRadians = Math.PI / 180;
            double d;
            int i, j, k;
            int[] Radiuses;
            int[] Angles;
            int Level = 0;
            int Lives = 3;
            int Score = 0;
            int TeleportsLeft = 3;
            int HighScore = 0;
            int HighLevel = 0;
            double ImmortalSecondsLeft = 0;
            double NewShipSecondsLeft = 0;
            bool Collision;
            bool Done = false;
            bool GameOver = false;

            // Source of sound: http://www.freesound.org/people/jobro/sounds/35686/
            int ShotSound = UploadAudioSample(GetResourceWavAudio("35686__jobro__laser9.wav"));

            // Source of sound: http://www.freesound.org/people/Tony%20B%20kksm/sounds/80938/
            int AsteroidHitSound = UploadAudioSample(GetResourceWavAudio("80938__tony-b-kksm__soft-explosion.wav"));

            // Source of sound: http://www.freesound.org/people/sandyrb/sounds/35643/
            int ShipExplodeSound = UploadAudioSample(GetResourceWavAudio("35643__sandyrb__usat-bomb.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/172207/
            int TeleportSound = UploadAudioSample(GetResourceWavAudio("172207__fins__teleport.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/133284/
            int LevelCompletedSound = UploadAudioSample(GetResourceWavAudio("133284__fins__level-completed.wav"));

            // Source of sound: http://www.freesound.org/people/fins/sounds/133283/
            int GameOverSound = UploadAudioSample(GetResourceWavAudio("133283__fins__game-over.wav"));

            OpenConsoleWindow(4, 4, 35, 25, "Welcome to Asteroids.");

            WriteLine();
            WriteLine("Keys in the game:");
            WriteLine();
            WriteLine("Left: Turn ship left");
            WriteLine("Right: Turn ship right");
            WriteLine("Up: Accelerate forwards");
            WriteLine("Down: Teleport to safe location");
            WriteLine("Space: Fire");
            WriteLine("Esc: Close application");
            WriteLine("Q: Quit current game");
            WriteLine();
            WriteLine("To play, press ENTER.");

            ReadLine();
            ClearConsoleWindowArea();
            Clear();

            Write("Ships: ");
            int NrShipsPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Lives.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Hyper: ");
            int NrTeleportsPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(TeleportsLeft.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Lvl: ");
            int LevelPos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Level.ToString("D2"));
            ForegroundColor = Color.White;

            Write(" Score: ");
            int ScorePos = CursorX;

            ForegroundColor = Color.Salmon;
            Write(Score.ToString("D5"));

            OnUpdateModel += (s, e) =>
                {
                    if (GameOver)
                        return;

                    double ElapsedSeconds = e.Seconds;

                    if (Asteroids.First == null)
                    {
                        ImmortalSecondsLeft = 4;

                        Level++;
                        GotoXY(LevelPos, 0);
                        Write(Level.ToString("D2"));

                        for (i = 0; i < 5 + 5 * Level; i++)
                        {
                            Radiuses = new int[16];
                            Angles = new int[16];

                            for (j = 0; j < 16; j++)
                            {
                                Radiuses[j] = Random(16, 32);
                                Angles[j] = Random(0, 359);
                            }

                            Array.Sort<int>(Angles);

                            j = Random(0, 359);
                            k = Random(200, 400);

                            Asteroids.AddLast(new RotatingObject(Radiuses, Angles,
                                320 + Math.Cos(j * ToRadians) * k,
                                240 + Math.Sin(j * ToRadians) * k,
                                60 * Random() - 30,
                                60 * Random() - 30,
                                0, 200 * Random() - 100));
                        }

                        if (Level > 1)
                            PlayAudioSample(LevelCompletedSound);
                    }

                    foreach (RotatingObject Obj in Asteroids)
                    {
                        Obj.Draw(Color.Black);
                        Obj.Move(ElapsedSeconds);
                        Obj.Draw(Color.White);

                        if (Ship != null && ImmortalSecondsLeft <= 0 && IntersectsPolygon(Ship.Points, Obj.Points))
                        {
                            Ship.Draw(Color.Black);

                            for (i = 0; i < 200; i++)
                            {
                                d = Random() * 360 * ToRadians;
                                j = Random(10, 100);

                                Particles.AddLast(new Particle(
                                    Ship.X,  // X
                                    Ship.Y,  // Y
                                    Ship.VelocityX + Math.Cos(d) * j,                       // Velocity X
                                    Ship.VelocityY + Math.Sin(d) * j,                       // Velocity Y
                                    Blend(Color.Blue, Color.White, Random()),
                                    4));
                            }

                            Ship = null;
                            NewShipSecondsLeft = 4;

                            PlayAudioSample(ShipExplodeSound);
                        }
                    }

                    if (Ship != null)
                    {
                        Ship.Draw(Color.Black);

                        if (IsPressed(KeyCode.Left))
                            Ship.Angle -= 3;

                        if (IsPressed(KeyCode.Right))
                            Ship.Angle += 3;

                        if (IsPressed(KeyCode.Up))
                        {
                            Ship.VelocityX += Math.Cos(Ship.Angle * ToRadians) * 4;
                            Ship.VelocityY += Math.Sin(Ship.Angle * ToRadians) * 4;

                            d = (Random() * 30 - 15 + Ship.Angle + 180) * ToRadians;    // Particle direction
                            Particles.AddLast(new Particle(
                                Ship.X + Math.Cos((Ship.Angle + 180) * ToRadians) * 5,  // X
                                Ship.Y + Math.Sin((Ship.Angle + 180) * ToRadians) * 5,  // Y
                                Ship.VelocityX + Math.Cos(d) * 100,                       // Velocity X
                                Ship.VelocityY + Math.Sin(d) * 100,                       // Velocity Y
                                Blend(Color.Yellow, Color.Orange, Random()),
                                2));
                        }

                        if (TeleportsLeft > 0 && ImmortalSecondsLeft <= 0 && IsPressed(KeyCode.Down))
                        {
                            do
                            {
                                Ship.X = Random(50, RasterWidth - 50);
                                Ship.Y = Random(50, RasterHeight - 50);
                                Ship.VelocityX = 0;
                                Ship.VelocityY = 0;

                                Ship.CalcPoints();

                                Collision = false;

                                foreach (RotatingObject Obj in Asteroids)
                                {
                                    if (IntersectsPolygon(Obj.Points, Ship.Points))
                                    {
                                        Collision = true;
                                        break;
                                    }
                                }
                            }
                            while (Collision);

                            ImmortalSecondsLeft = 4;

                            PlayAudioSample(TeleportSound);

                            TeleportsLeft--;
                            GotoXY(NrTeleportsPos, 0);
                            Write(TeleportsLeft.ToString("D2"));
                        }

                        Ship.Move(ElapsedSeconds);

                        if (ImmortalSecondsLeft > 0)
                        {
                            ImmortalSecondsLeft -= ElapsedSeconds;

                            if (Math.IEEERemainder(ImmortalSecondsLeft, 0.5) < 0)
                                Ship.Draw(Blend(Color.Blue, Color.White, 0.5));
                            else
                                Ship.Draw(Color.White);
                        }
                        else
                            Ship.Draw(Color.White);
                    }
                    else
                    {
                        NewShipSecondsLeft -= ElapsedSeconds;

                        if (NewShipSecondsLeft <= 0 && Lives > 0)
                        {
                            Ship = new RotatingObject(new int[] { 15, 15, 5, 15 }, new int[] { 0, 135, 180, 225 }, 320, 240, 0, 0, 270, 0);
                            ImmortalSecondsLeft = 4;

                            Lives--;
                            GotoXY(NrShipsPos, 0);
                            Write(Lives.ToString("D2"));
                        }
                        else if (Lives == 0)
                        {
                            Lives--;
                            PlayAudioSample(GameOverSound);
                        }
                        else if (NewShipSecondsLeft < -1.5 && Lives == -1)
                        {
                            Lives--;
                            GameOver = true;
                        }
                    }

                    LinkedListNode<Particle> ParticleNode = Particles.First;
                    LinkedListNode<Particle> Next;
                    Particle Particle;

                    while (ParticleNode != null)
                    {
                        Particle = ParticleNode.Value;

                        if (Particle.Draw(Color.Black))
                        {
                            Particle.Move(ElapsedSeconds);
                            Particle.Draw(Particle.Color);
                            ParticleNode = ParticleNode.Next;
                        }
                        else
                        {
                            Next = ParticleNode.Next;
                            Particles.Remove(ParticleNode);
                            ParticleNode = Next;
                        }
                    }

                    LinkedListNode<Particle> ShotNode = Shots.First;
                    LinkedListNode<RotatingObject> AsteroidNode;
                    RotatingObject Asteroid;
                    Particle Shot;
                    int x0, y0, x1, y1;
                    double vx, vy;

                    while (ShotNode != null)
                    {
                        Shot = ShotNode.Value;

                        if (Shot.Draw(Color.Black))
                        {
                            Shot.Move(ElapsedSeconds);
                            x0 = (int)(Shot.PrevX + 0.5);
                            y0 = (int)(Shot.PrevY + 0.5);
                            x1 = (int)(Shot.X + 0.5);
                            y1 = (int)(Shot.Y + 0.5);

                            AsteroidNode = Asteroids.First;
                            while (AsteroidNode != null)
                            {
                                Asteroid = AsteroidNode.Value;

                                if (IntersectsPolygon(x0, y0, x1, y1, Asteroid.Points))
                                {
                                    i = Asteroid.Points.Length;

                                    if (i > 4)
                                    {
                                        i /= 2;

                                        for (k = 0; k < 3; k++)
                                        {
                                            Radiuses = new int[i];
                                            Angles = new int[i];

                                            for (j = 0; j < i; j++)
                                            {
                                                Radiuses[j] = Random(i, i << 1);
                                                Angles[j] = Random(0, 359);
                                            }

                                            Array.Sort<int>(Angles);

                                            j = Random(0, 359);

                                            do
                                            {
                                                vx = Asteroid.VelocityX + 100 * Random() - 50;
                                            }
                                            while (Math.Abs(vx) < 5);   // To avoid slow moving objects hidden by the border.

                                            do
                                            {
                                                vy = Asteroid.VelocityY + 100 * Random() - 50;
                                            }
                                            while (Math.Abs(vy) < 5);   // To avoid slow moving objects hidden by the border.

                                            Asteroids.AddLast(new RotatingObject(Radiuses, Angles,
                                                Asteroid.X,
                                                Asteroid.Y,
                                                vx,
                                                vy,
                                                Asteroid.Angle, Asteroid.VelocityAngle + 200 * Random() - 100));
                                        }
                                    }

                                    for (i = 0; i < 30; i++)
                                    {
                                        d = Random() * 360 * ToRadians;
                                        j = Random(10, 100);

                                        Particles.AddLast(new Particle(
                                            Asteroid.X,  // X
                                            Asteroid.Y,  // Y
                                            Asteroid.VelocityX + Math.Cos(d) * j,                       // Velocity X
                                            Asteroid.VelocityY + Math.Sin(d) * j,                       // Velocity Y
                                            Blend(Color.Red, Color.Yellow, Random()),
                                            2));
                                    }

                                    Asteroid.Draw(Color.Black);
                                    Asteroids.Remove(AsteroidNode);

                                    PlayAudioSample(AsteroidHitSound);

                                    Score++;
                                    GotoXY(ScorePos, 0);
                                    Write(Score.ToString("D5"));

                                    break;
                                }
                                else
                                    AsteroidNode = AsteroidNode.Next;
                            }

                            if (AsteroidNode == null)
                            {
                                Shot.Draw(Shot.Color);
                                ShotNode = ShotNode.Next;
                            }
                            else
                            {
                                Next = ShotNode.Next;
                                Shots.Remove(ShotNode);
                                ShotNode = Next;
                            }
                        }
                        else
                        {
                            Next = ShotNode.Next;
                            Shots.Remove(ShotNode);
                            ShotNode = Next;
                        }
                    }
                };

            OnKeyPressed += (s, e) =>
                {
                    switch (e.Character)
                    {
                        case '\x1b':
                            Done = true;
                            break;

                        case ' ':
                            if (Ship != null)
                            {
                                d = Ship.Angle * ToRadians;                 // Shot direction
                                Shots.AddLast(new Particle(
                                    Ship.X + Math.Cos(d) * 15,              // X
                                    Ship.Y + Math.Sin(d) * 15,              // Y
                                    Ship.VelocityX + Math.Cos(d) * 200,     // Velocity X
                                    Ship.VelocityY + Math.Sin(d) * 200,     // Velocity Y
                                    Color.White,
                                    3));

                                PlayAudioSample(ShotSound);
                            }
                            break;

                        case 'q':
                        case 'Q':
                            GameOver = true;
                            PlayAudioSample(GameOverSound);
                            break;
                    }
                };

            while (!Done)
            {
                while (!GameOver && !Done)
                {
                    Sleep(10);
                }

                if (!Done)
                {
                    ForegroundColor = Color.White;
                    OpenConsoleWindow(4, 4, 35, 25, "Game Over!");

                    WriteLine();
                    Write("Level: ");
                    ForegroundColor = Color.Salmon;
                    WriteLine(Level.ToString("D2"));
                    ForegroundColor = Color.White;

                    Write("Score: ");
                    ForegroundColor = Color.Salmon;
                    WriteLine(Score.ToString("D5"));
                    ForegroundColor = Color.White;

                    if (Score > HighScore)
                    {
                        WriteLine();
                        WriteLine("New High Score!");

                        HighScore = Score;
                        HighLevel = Level;
                    }

                    WriteLine();
                    Write("Highest Level: ");
                    ForegroundColor = Color.Salmon;
                    WriteLine(HighLevel.ToString("D2"));
                    ForegroundColor = Color.White;

                    Write("Highest Score: ");
                    ForegroundColor = Color.Salmon;
                    WriteLine(HighScore.ToString("D5"));
                    ForegroundColor = Color.White;

                    WriteLine();
                    WriteLine("To play again, press ENTER.");
                    WriteLine("To quit, press CTRL+C.");

                    ReadLine();
                    ClearConsoleWindowArea();
                    Clear();

                    Asteroids.Clear();
                    Particles.Clear();
                    Shots.Clear();
                    Level = 0;
                    Lives = 3;
                    Score = 0;
                    TeleportsLeft = 3;
                    Ship = null;
                    GameOver = false;

                    Write("Ships: ");
                    ForegroundColor = Color.Salmon;
                    Write(Lives.ToString("D2"));
                    ForegroundColor = Color.White;

                    Write(" Hyper: ");
                    ForegroundColor = Color.Salmon;
                    Write(TeleportsLeft.ToString("D2"));
                    ForegroundColor = Color.White;

                    Write(" Lvl: ");
                    ForegroundColor = Color.Salmon;
                    Write(Level.ToString("D2"));
                    ForegroundColor = Color.White;

                    Write(" Score: ");
                    ForegroundColor = Color.Salmon;
                    Write(Score.ToString("D5"));
                }
            }

            Terminate();
        }