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); } }
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(); }