Skip to content

Commit

Permalink
Shmup (#86)
Browse files Browse the repository at this point in the history
shmupdate
  • Loading branch information
ZacharyPatten committed Sep 30, 2023
1 parent 57a4f06 commit 532c3af
Show file tree
Hide file tree
Showing 19 changed files with 2,141 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/Shmup Build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Shmup Build
on:
push:
paths:
- 'Projects/Shmup/**'
- '!**.md'
pull_request:
paths:
- 'Projects/Shmup/**'
- '!**.md'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- run: dotnet build "Projects\Shmup\Shmup.csproj" --configuration Release
10 changes: 10 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -472,5 +472,15 @@
"console": "externalTerminal",
"stopAtEntry": false,
},
{
"name": "Shmup",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build Shmup",
"program": "${workspaceFolder}/Projects/Shmup/bin/Debug/Shmup.dll",
"cwd": "${workspaceFolder}/Projects/Shmup/bin/Debug",
"console": "externalTerminal",
"stopAtEntry": false,
},
],
}
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,19 @@
],
"problemMatcher": "$msCompile",
},
{
"label": "Build Shmup",
"command": "dotnet",
"type": "process",
"args":
[
"build",
"${workspaceFolder}/Projects/Shmup/Shmup.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
],
"problemMatcher": "$msCompile",
},
{
"label": "Build Solution",
"command": "dotnet",
Expand Down
97 changes: 97 additions & 0 deletions Projects/Shmup/Enemies/Helicopter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using System;
using System.Linq;

namespace Shmup.Enemies;

internal class Helicopter : IEnemy
{
public static int scorePerKill = 100;
public int Health = 70;
public float X;
public float Y;
public float XVelocity;
public float YVelocity;

Check warning on line 13 in Projects/Shmup/Enemies/Helicopter.cs

View workflow job for this annotation

GitHub Actions / build

Field 'Helicopter.YVelocity' is never assigned to, and will always have its default value 0

Check warning on line 13 in Projects/Shmup/Enemies/Helicopter.cs

View workflow job for this annotation

GitHub Actions / build

Field 'Helicopter.YVelocity' is never assigned to, and will always have its default value 0

Check warning on line 13 in Projects/Shmup/Enemies/Helicopter.cs

View workflow job for this annotation

GitHub Actions / deployment

Field 'Helicopter.YVelocity' is never assigned to, and will always have its default value 0
private int Frame;
private string[] Sprite = Random.Shared.Next(2) is 0 ? spriteA : spriteB;

static readonly string[] spriteA =
{
@" ~~~~~+~~~~~",
@"'\===<[_]L) ",
@" -'-`- ",
};

static readonly string[] spriteB =
{
@" -----+-----",
@"*\===<[_]L) ",
@" -'-`- ",
};

internal static int XMax = Math.Max(spriteA.Max(s => s.Length), spriteB.Max(s => s.Length));
internal static int YMax = Math.Max(spriteA.Length, spriteB.Length);

public void Render()
{
for (int y = 0; y < Sprite.Length; y++)
{
int yo = (int)Y + y;
int yi = Sprite.Length - y - 1;
if (yo >= 0 && yo < Program.frameBuffer.GetLength(1))
{
for (int x = 0; x < Sprite[y].Length; x++)
{
int xo = (int)X + x;
if (xo >= 0 && xo < Program.frameBuffer.GetLength(0))
{
if (Sprite[yi][x] is not ' ')
{
Program.frameBuffer[xo, yo] = Sprite[yi][x];
}
}
}
}
}
}

public void Update()
{
Frame++;
if (Frame > 10)
{
Sprite = Sprite == spriteB ? spriteA : spriteB;
Frame = 0;
}
X += XVelocity;
Y += YVelocity;
}

public bool CollidingWith(int x, int y)
{
int xo = x - (int)X;
int yo = y - (int)Y;
return
yo >= 0 && yo < Sprite.Length &&
xo >= 0 && xo < Sprite[yo].Length &&
Sprite[yo][xo] is not ' ';
}

public bool IsOutOfBounds()
{
return
XVelocity <= 0 && X < -XMax ||
YVelocity <= 0 && Y < -YMax ||
XVelocity >= 0 && X > Program.gameWidth + XMax ||
YVelocity >= 0 && Y > Program.gameHeight + YMax;
}

public void Shot()
{
Health--;
if (Health <= 0)
{
Program.enemies.Remove(this);
Program.score += scorePerKill;
}
}
}
14 changes: 14 additions & 0 deletions Projects/Shmup/Enemies/IEnemy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Shmup.Enemies;

internal interface IEnemy
{
public void Shot();

public void Render();

public void Update();

public bool CollidingWith(int x, int y);

public bool IsOutOfBounds();
}
111 changes: 111 additions & 0 deletions Projects/Shmup/Enemies/Tank.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Linq;

namespace Shmup.Enemies;

internal class Tank : IEnemy
{
public static int scorePerKill = 20;
public int Health = 20;
public float X;
public float Y;
public float XVelocity;

Check warning on line 12 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / build

Field 'Tank.XVelocity' is never assigned to, and will always have its default value 0

Check warning on line 12 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / build

Field 'Tank.XVelocity' is never assigned to, and will always have its default value 0

Check warning on line 12 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / deployment

Field 'Tank.XVelocity' is never assigned to, and will always have its default value 0
public float YVelocity;
private string[] Sprite;

Check warning on line 14 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'Sprite' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 14 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'Sprite' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 14 in Projects/Shmup/Enemies/Tank.cs

View workflow job for this annotation

GitHub Actions / deployment

Non-nullable field 'Sprite' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

static readonly string[] spriteDown =
{
@" ___ ",
@"|_O_|",
@"[ooo]",
};

static readonly string[] spriteUp =
{
@" _^_ ",
@"|___|",
@"[ooo]",
};

static readonly string[] spriteLeft =
{
@" __ ",
@"=|__|",
@"[ooo]",
};

static readonly string[] spriteRight =
{
@" __ ",
@"|__|=",
@"[ooo]",
};

internal static int XMax = new[] { spriteDown.Max(s => s.Length), spriteUp.Max(s => s.Length), spriteLeft.Max(s => s.Length), spriteRight.Max(s => s.Length), }.Max();
internal static int YMax = new[] { spriteDown.Length, spriteUp.Length, spriteLeft.Length, spriteRight.Length, }.Max();

public void Render()
{
for (int y = 0; y < Sprite.Length; y++)
{
int yo = (int)Y + y;
int yi = Sprite.Length - y - 1;
if (yo >= 0 && yo < Program.frameBuffer.GetLength(1))
{
for (int x = 0; x < Sprite[y].Length; x++)
{
int xo = (int)X + x;
if (xo >= 0 && xo < Program.frameBuffer.GetLength(0))
{
if (Sprite[yi][x] is not ' ')
{
Program.frameBuffer[xo, yo] = Sprite[yi][x];
}
}
}
}
}
}

public void Update()
{
int xDifToPlayer = (int)Program.player.X - (int)X;
int yDifToPlayer = (int)Program.player.Y - (int)Y;

Sprite = Math.Abs(xDifToPlayer) > Math.Abs(yDifToPlayer)
? xDifToPlayer > 0 ? spriteRight : spriteLeft
: yDifToPlayer > 0 ? spriteUp : spriteDown;

X += XVelocity;
Y += YVelocity;
}

public bool CollidingWith(int x, int y)
{
int xo = x - (int)X;
int yo = y - (int)Y;
return
yo >= 0 && yo < Sprite.Length &&
xo >= 0 && xo < Sprite[yo].Length &&
Sprite[yo][xo] is not ' ';
}

public bool IsOutOfBounds()
{
return
XVelocity <= 0 && X < -XMax ||
YVelocity <= 0 && Y < -YMax ||
XVelocity >= 0 && X > Program.gameWidth + XMax ||
YVelocity >= 0 && Y > Program.gameHeight + YMax;
}

public void Shot()
{
Health--;
if (Health <= 0)
{
Program.enemies.Remove(this);
Program.score += scorePerKill;
}
}
}
95 changes: 95 additions & 0 deletions Projects/Shmup/Enemies/UFO1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Linq;

namespace Shmup.Enemies;

internal class UFO1 : IEnemy
{
public static int scorePerKill = 10;
public int Health = 10;
public float X;
public float Y;
public float XVelocity = 1f / 8f;
public float YVelocity = 1f / 8f;
private static readonly string[] Sprite =
{
@" _!_ ",
@"(_o_)",
@" ''' ",
};

internal static int XMax = Sprite.Max(s => s.Length);
internal static int YMax = Sprite.Length;

public void Render()
{
for (int y = 0; y < Sprite.Length; y++)
{
int yo = (int)Y + y;
int yi = Sprite.Length - y - 1;
if (yo >= 0 && yo < Program.frameBuffer.GetLength(1))
{
for (int x = 0; x < Sprite[y].Length; x++)
{
int xo = (int)X + x;
if (xo >= 0 && xo < Program.frameBuffer.GetLength(0))
{
if (Sprite[yi][x] is not ' ')
{
Program.frameBuffer[xo, yo] = Sprite[yi][x];
}
}
}
}
}
}

public void Update()
{
if (Program.player.X < X)
{
X = Math.Max(Program.player.X, X - XVelocity);
}
else
{
X = Math.Min(Program.player.X, X + XVelocity);
}
if (Program.player.Y < Y)
{
Y = Math.Max(Program.player.Y, Y - YVelocity);
}
else
{
Y = Math.Min(Program.player.Y, Y + YVelocity);
}
}

public bool CollidingWith(int x, int y)
{
int xo = x - (int)X;
int yo = y - (int)Y;
return
yo >= 0 && yo < Sprite.Length &&
xo >= 0 && xo < Sprite[yo].Length &&
Sprite[yo][xo] is not ' ';
}

public bool IsOutOfBounds()
{
return
XVelocity <= 0 && X < -XMax ||
YVelocity <= 0 && Y < -YMax ||
XVelocity >= 0 && X > Program.gameWidth + XMax ||
YVelocity >= 0 && Y > Program.gameHeight + YMax;
}

public void Shot()
{
Health--;
if (Health <= 0)
{
Program.enemies.Remove(this);
Program.score += scorePerKill;
}
}
}
Loading

0 comments on commit 532c3af

Please sign in to comment.