diff --git a/Program.cs b/Program.cs
index d23767e..3bd12d3 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,6 +1,5 @@
-// See https://aka.ms/new-console-template for more information
-
-var window = new Window("ASDLteroids", 800, 600);
+var window = new Window("ASDLteroids", 800, 600);
var renderer = new Renderer(window);
var scene = new Scene(renderer);
+
scene.Run();
diff --git a/dotnet-console.csproj b/asdlteroids.csproj
similarity index 55%
rename from dotnet-console.csproj
rename to asdlteroids.csproj
index c033c20..5524382 100644
--- a/dotnet-console.csproj
+++ b/asdlteroids.csproj
@@ -3,13 +3,20 @@
Exe
net6.0
- dotnet_console
+ asdlteroids
enable
enable
+
+
+
+
+
+
+
diff --git a/assets/explode.wav b/assets/explode.wav
new file mode 100644
index 0000000..0741f66
Binary files /dev/null and b/assets/explode.wav differ
diff --git a/assets/shot.wav b/assets/shot.wav
new file mode 100644
index 0000000..7de2c5f
Binary files /dev/null and b/assets/shot.wav differ
diff --git a/src/Controlls.cs b/src/Controlls.cs
new file mode 100644
index 0000000..1a27b7c
--- /dev/null
+++ b/src/Controlls.cs
@@ -0,0 +1,29 @@
+using static SDL2.SDL;
+
+enum Control
+{
+ THRUST,
+ LEFT,
+ RIGHT,
+ SHOOT
+}
+
+static class ControlKeyExtension
+{
+ public static SDL_Keycode Key(this Control c)
+ {
+ switch (c)
+ {
+ case Control.THRUST:
+ return SDL_Keycode.SDLK_UP;
+ case Control.LEFT:
+ return SDL_Keycode.SDLK_LEFT;
+ case Control.RIGHT:
+ return SDL_Keycode.SDLK_RIGHT;
+ case Control.SHOOT:
+ return SDL_Keycode.SDLK_SPACE;
+ default:
+ throw new ArgumentException("Invalid control");
+ }
+ }
+}
diff --git a/src/Scene.cs b/src/Scene.cs
index 68181f6..0be4c91 100644
--- a/src/Scene.cs
+++ b/src/Scene.cs
@@ -12,6 +12,7 @@ class Scene
public HashSet Asteroids;
public int Score = 0;
public int Level = 1;
+ public AudioPlayer AudioPlayer;
public Scene(Renderer renderer)
{
@@ -19,6 +20,9 @@ class Scene
this.Shots = new HashSet();
this.Asteroids = new HashSet();
this.renderer = renderer;
+ this.AudioPlayer = new AudioPlayer();
+ this.AudioPlayer.Register(Sound.SHOT, "assets.shot.wav");
+ this.AudioPlayer.Register(Sound.EXPLOSION, "assets.explode.wav");
instance = this;
}
diff --git a/src/engine/AudioPlayer.cs b/src/engine/AudioPlayer.cs
new file mode 100644
index 0000000..5bbc7f2
--- /dev/null
+++ b/src/engine/AudioPlayer.cs
@@ -0,0 +1,32 @@
+enum Sound : int
+{
+ SHOT = 0,
+ EXPLOSION = 1,
+}
+
+class AudioPlayer
+{
+ private Dictionary audioFiles = new();
+ private string assemblyName;
+
+ public AudioPlayer()
+ {
+ SDL2.SDL_mixer.Mix_OpenAudio(44100, SDL2.SDL_mixer.MIX_DEFAULT_FORMAT, 2, 2048);
+ this.assemblyName = this.GetType().Assembly.GetName().Name!;
+ }
+
+ public void Register(Sound name, string path)
+ {
+ var stream = this.GetType().Assembly.GetManifestResourceStream($"{this.assemblyName}.{path}");
+ var buffer = new byte[stream!.Length];
+ stream.Read(buffer, 0, buffer.Length);
+ this.audioFiles.Add(name, buffer);
+ }
+
+ public void Play(Sound name)
+ {
+ var buffer = this.audioFiles[name];
+ var sound = SDL2.SDL_mixer.Mix_QuickLoad_WAV(buffer);
+ SDL2.SDL_mixer.Mix_PlayChannel((int)name, sound, 0);
+ }
+}
diff --git a/src/engine/KeyState.cs b/src/engine/KeyState.cs
index 15032f0..5793a70 100644
--- a/src/engine/KeyState.cs
+++ b/src/engine/KeyState.cs
@@ -17,4 +17,9 @@ class KeyState
byte scanCode = (byte)SDL_GetScancodeFromKey(keycode);
return (this.keys[scanCode] == 1);
}
+
+ public bool isPressed(Control c)
+ {
+ return this.isPressed(c.Key());
+ }
}
diff --git a/src/entities/Asteroid.cs b/src/entities/Asteroid.cs
index b000814..7d7bef1 100644
--- a/src/entities/Asteroid.cs
+++ b/src/entities/Asteroid.cs
@@ -34,7 +34,6 @@ class Asteroid : Renderable, Logic
public void Render(Renderer renderer, double dx)
{
renderer.setColor(255, 255, 255);
- // renderer.DrawRect(X - (int)Size / 2, Y - (int)Size / 2, (int)Size, (int)Size);
double[][] drawLines = new double[shape.Length + 1][];
for (int i = 0; i < shape.Length; i++)
{
@@ -65,7 +64,8 @@ class Asteroid : Renderable, Logic
foreach (var shot in Scene.Instance.Shots)
{
- if (Point.Distance(shot.X, shot.Y, X, Y) < (int)Size / 2)
+ var halfSize = (int)Size / 2;
+ if (Point.Distance(shot.X, shot.Y, X - halfSize, Y - halfSize) < (int)Size / 2)
{
shot.Destroy();
this.Destroy();
@@ -88,6 +88,7 @@ class Asteroid : Renderable, Logic
public void Destroy()
{
+ Scene.Instance.AudioPlayer.Play(Sound.EXPLOSION);
Scene.Instance.Score += (int)Size;
Scene.Instance.Asteroids.Remove(this);
Console.WriteLine("Asteroid destroyed");
diff --git a/src/entities/Ship.cs b/src/entities/Ship.cs
index deaf974..39eddda 100644
--- a/src/entities/Ship.cs
+++ b/src/entities/Ship.cs
@@ -1,6 +1,3 @@
-using static SDL2.SDL;
-
-
class Ship : Logic, Renderable
{
const double SPEED = 0.3;
@@ -22,24 +19,25 @@ class Ship : Logic, Renderable
public void Update(KeyState keyState, double dt)
{
thrust = false;
- if (keyState.isPressed(SDL_Keycode.SDLK_LEFT))
+ if (keyState.isPressed(Control.LEFT))
{
rotation -= ROTATION_SPEED * dt;
}
- if (keyState.isPressed(SDL_Keycode.SDLK_RIGHT))
+ if (keyState.isPressed(Control.RIGHT))
{
rotation += ROTATION_SPEED * dt;
}
- if (keyState.isPressed(SDL_Keycode.SDLK_UP))
+ if (keyState.isPressed(Control.THRUST))
{
thrust = true;
this.dx += Math.Cos(rotation) * SPEED * dt;
this.dy += Math.Sin(rotation) * SPEED * dt;
}
- if (keyState.isPressed(SDL_Keycode.SDLK_SPACE) && (DateTime.Now - lastShot).TotalMilliseconds > 200)
+ if (keyState.isPressed(Control.SHOOT) && (DateTime.Now - lastShot).TotalMilliseconds > 200)
{
lastShot = DateTime.Now;
var shot = new Shot(x, y, rotation);
+ Scene.Instance.AudioPlayer.Play(Sound.SHOT);
Scene.Instance.Shots.Add(shot);
}
rotation = rotation % (2 * Math.PI);
@@ -63,7 +61,8 @@ class Ship : Logic, Renderable
}
foreach (var asteroid in Scene.Instance.Asteroids)
{
- if (Point.Distance(x, y, asteroid.X, asteroid.Y) < (int)asteroid.Size / 2)
+ var halfAsteroidSize = (int)asteroid.Size / 2;
+ if (Point.Distance(x, y, asteroid.X - halfAsteroidSize, asteroid.Y - halfAsteroidSize) < halfAsteroidSize + 3)
{
Scene.Instance.Loose();
}
@@ -74,20 +73,28 @@ class Ship : Logic, Renderable
{
renderer.setColor(255, 255, 255);
renderer.DrawLines(new double[][] {
- new double[]{x + Math.Cos(rotation) * 10, y + Math.Sin(rotation) * 10},
- new double[]{x + Math.Cos(rotation + Math.PI * 2 / 3) * 10, y + Math.Sin(rotation + Math.PI * 2 / 3) * 10},
- new double[]{x + Math.Cos(rotation + Math.PI * 4 / 3) * 10, y + Math.Sin(rotation + Math.PI * 4 / 3) * 10},
- new double[]{x + Math.Cos(rotation) * 10, y + Math.Sin(rotation) * 10}
+ new double[] { x + Math.Cos(rotation) * 10, y + Math.Sin(rotation) * 10 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3) * 10, y + Math.Sin(rotation + (Math.PI * 2) / 3) * 10 },
+ new double[] { x + Math.Cos(rotation) * 10, y + Math.Sin(rotation) * 10 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 2) * 10, y + Math.Sin(rotation + (Math.PI * 2) / 3 * 2) * 10 },
});
+ renderer.DrawLines(new double[][] {
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3) * 5, y + Math.Sin(rotation + (Math.PI * 2) / 3) * 5 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 2) * 5, y + Math.Sin(rotation + (Math.PI * 2) / 3 * 2) * 5 },
+ });
+
if (thrust)
{
renderer.setColor(255, 0, 0);
+ var random = new Random();
// Draw flame behind ship
renderer.DrawLines(new double[][] {
- new double[]{x + Math.Cos(rotation + Math.PI * 2 / 3) * 10, y + Math.Sin(rotation + Math.PI * 2 / 3) * 10},
- new double[]{x + Math.Cos(rotation + Math.PI * 2 / 3) * 10 + Math.Cos(rotation + Math.PI) * 10, y + Math.Sin(rotation + Math.PI * 2 / 3) * 10 + Math.Sin(rotation + Math.PI) * 10},
- new double[]{x + Math.Cos(rotation + Math.PI * 4 / 3) * 10, y + Math.Sin(rotation + Math.PI * 4 / 3) * 10},
- new double[]{x + Math.Cos(rotation + Math.PI * 2 / 3) * 10, y + Math.Sin(rotation + Math.PI * 2 / 3) * 10}
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3) * 10, y + Math.Sin(rotation + (Math.PI * 2) / 3) * 10 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 1.2) * 5+random.Next(5), y + Math.Sin(rotation + (Math.PI * 2) / 3 * 1.2) * 5+random.Next(5) },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 1.4) * 10, y + Math.Sin(rotation + (Math.PI * 2) / 3 * 1.4) * 10 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 1.6) * 6+random.Next(5), y + Math.Sin(rotation + (Math.PI * 2) / 3 * 1.6) * 5+random.Next(4) },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 1.8) * 10, y + Math.Sin(rotation + (Math.PI * 2) / 3 * 1.8) * 10 },
+ new double[] { x + Math.Cos(rotation + (Math.PI * 2) / 3 * 2) * 5+random.Next(5), y + Math.Sin(rotation + (Math.PI * 2) / 3 * 2) * 5+random.Next(5) },
});
}
}