initial commit

This commit is contained in:
Booklordofthedings 2024-05-12 09:57:03 +02:00
commit 6d6019c62b
61 changed files with 2579 additions and 0 deletions

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.bf linguist-language=Beef

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
build/
recovery/
BeefSpace_User.toml

BIN
Assets/abil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Assets/abil2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Assets/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Assets/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

BIN
Assets/box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

BIN
Assets/brawl.wav Normal file

Binary file not shown.

BIN
Assets/death.wav Normal file

Binary file not shown.

BIN
Assets/deathfast.wav Normal file

Binary file not shown.

BIN
Assets/deathheavy.wav Normal file

Binary file not shown.

BIN
Assets/deathmagi.wav Normal file

Binary file not shown.

BIN
Assets/dog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 B

BIN
Assets/dog2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

BIN
Assets/dog3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

BIN
Assets/fg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
Assets/jam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
Assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
Assets/pdeath.wav Normal file

Binary file not shown.

BIN
Assets/sad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
Assets/select.wav Normal file

Binary file not shown.

BIN
Assets/slime.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

BIN
Assets/slimedeath.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

BIN
Assets/slimef.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

BIN
Assets/slimem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

BIN
Assets/slimemetal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

BIN
Assets/speed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

BIN
Assets/titlething.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

27
BeefProj.toml Normal file
View file

@ -0,0 +1,27 @@
FileVersion = 1
Dependencies = {corlib = "*", SDL2 = "*"}
[Project]
Name = "Slime-Slammer"
TargetType = "BeefGUIApplication"
StartupObject = "bounty_game.Program"
DefaultNamespace = "bounty_game"
Aliases = ["Slime slammer"]
[Platform.Windows]
IconFile = "D:\\Desktop\\bounty-game\\icon.ico"
[Configs.Debug.Win64]
PostBuildCmds = ["CopyFilesIfNewer(\"$(ProjectDir)/Assets\",\"$(WorkspaceDir)/Slime-Slammer\")\nCopyFilesIfNewer(\"$(BuildDir)\",\"$(ProjectDir)\")"]
[[Configs.Debug.Win64.DistinctOptions]]
Filter = ""
[Configs.Release.Win64]
PostBuildCmds = ["CopyFilesIfNewer(\"$(ProjectDir)/Assets\",\"$(WorkspaceDir)/bounty-game\")\nCopyFilesIfNewer(\"$(BuildDir)\",\"$(ProjectDir)\")"]
[Configs.Paranoid.Win64]
PostBuildCmds = ["CopyFilesIfNewer(\"$(ProjectDir)/Assets\",\"$(WorkspaceDir)/SDL2_Tut\")\nCopyFilesIfNewer(\"$(BuildDir)\",\"$(ProjectDir)\")"]
[Configs.Test.Win64]
PostBuildCmds = ["CopyFilesIfNewer(\"$(ProjectDir)/Assets\",\"$(WorkspaceDir)/SDL2_Tut\")\nCopyFilesIfNewer(\"$(BuildDir)\",\"$(ProjectDir)\")"]

5
BeefSpace.toml Normal file
View file

@ -0,0 +1,5 @@
FileVersion = 1
Projects = {Slime-Slammer = {Path = "."}, SDL2 = "*"}
[Workspace]
StartupProject = "Slime-Slammer"

7
README.md Normal file
View file

@ -0,0 +1,7 @@
# Slime slammer - a gmtk jam game
A small arcade game where you play as a knight, have to hit slimes with your flail and have to survive for as long as possible.
The game is made with Sdl2 as a Framework and my own Engine thingy, written in Beeflang.
This was made in a heavily timed enviroment, so code quality is not up to any standarts.
## You could probably build this, but I dont remember the exact replication steps.
## Ask me if you want, maybe I can help you

BIN
icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

73
src/Arcade/EndScene.bf Normal file
View file

@ -0,0 +1,73 @@
namespace bounty_game
{
class EndScene : Scene
{
public override void Load()
{
base.Load();
this.AddEntity(new Background());
this.AddEntity(new foreground());
this.AddEntity(new EndHud());
}
}
class EndHud : Entity
{
public bool* gCurrentKeyStates;
public bool[] gLastKeyStates;
public static int wave;
public static int killcount;
public static float timer;
public static float score;
public System.String text = """
Game ended
press Enter to restart
My Highscore: 10291
""";
Texture tt;
Texture tw;
SDL2.SDLMixer.Chunk *pdeath = null;
public override void Update(float delta)
{
gCurrentKeyStates = Game.gCurrentScene.gCurrentKeyStates;
gLastKeyStates = Game.gCurrentScene.gLastKeyStates;
timer += delta/1000;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] != gLastKeyStates[(int)SDL2.SDL.Scancode.Return] && timer > 1)
{
Game.gCurrentScene = new MenuScene();
Game.changedScene = true;
}
}
public override void Draw()
{
tt.Render(game_width/2 - tt.GetWidth/2,game_height/2 - tt.GetHeight/2);
tw.Render(game_width/2 - tw.GetWidth/2,game_height/2 - tw.GetHeight/2 -100);
}
public override void Destroy()
{
delete tt;
delete tw;
SDL2.SDLMixer.FreeChunk(pdeath);
}
public override void Init()
{
pdeath = SDL2.SDLMixer.LoadWAV("Assets/pdeath.wav");
SDL2.SDLMixer.PlayChannel(-1,pdeath,0);
score = 5 * killcount + 100* wave + 2 * timer;
tt = new Texture();
tt.LoadFromString(scope System.String("Your Score: ")..Append(score.ToString(.. scope .())),
SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.LargeFont);
tw = new Texture();
tw.LoadFromStringWrapped(text,SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.LargeFont,500);
}
}
}

41
src/Arcade/KillHud.bf Normal file
View file

@ -0,0 +1,41 @@
namespace bounty_game
{
class KillHud : Entity
{
public static int count;
public static float timeLived;
Texture slime;
Texture tcount;
Texture ttimeLived;
public override void Update(float delta)
{
timeLived += delta/1000;
}
public override void Draw()
{
slime.Render(5+PlayerBoxes.hitoffsetx,50+PlayerBoxes.hitoffsety);
tcount.LoadFromString(count.ToString(.. scope .() ),SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.GetDefaultFont());
tcount.Render(40+PlayerBoxes.hitoffsetx,66+PlayerBoxes.hitoffsety);
ttimeLived.LoadFromString(timeLived.ToString(.. scope .() ),SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.GetDefaultFont());
ttimeLived.Render(10+PlayerBoxes.hitoffsetx,85+PlayerBoxes.hitoffsety);
}
public override void Destroy()
{
delete slime;
delete tcount;
delete ttimeLived;
}
public override void Init()
{
slime = new Texture();
slime.LoadFromFile("Assets/slimedeath.png");
tcount = new Texture();
ttimeLived = new Texture();
count = 0;
timeLived = 0;
}
}
}

27
src/Background.bf Normal file
View file

@ -0,0 +1,27 @@
namespace bounty_game
{
class Background : Entity
{
Texture myTexture;
public override void Update(float delta)
{
}
public override void Draw()
{
myTexture.Render(0,0);
}
public override void Destroy()
{
delete myTexture;
}
public override void Init()
{
myTexture = new Texture();
myTexture.LoadFromFile("Assets/bg.png");
}
}
}

86
src/Ball.bf Normal file
View file

@ -0,0 +1,86 @@
namespace bounty_game
{
class Ball : Entity
{
public static vec2 pos;
public static vec2 vel;
Texture myTexture;
public static Texture abil;
public static Texture abil2;
float multx;
float multy;
public static float timer = 0;
public override void Update(float delta)
{
timer += delta/1000;
vel.x += (PlayerBoxes.Apos.x - (pos.x+16))*(0.015f)*(delta/1000);
vel.y += (PlayerBoxes.Apos.y - (pos.y-64))*(0.015f)*(delta/1000);
vel.x -= 0.004f*vel.x * delta;
vel.y -= 0.004f*vel.y * delta;
int32 x = 0,y = 0;
if(SDL2.SDL.GetMouseState(&x,&y) == SDL2.SDL.BUTTON_LMASK && timer > 2)
{
vel.x = (x - Ball.pos.x);
vel.y = (y -Ball.pos.y);
vel.normalize();
vel.x = vel.x * 2;
vel.y = vel.y * 2;
timer = 0;
myTexture.SetColor(0xFF,0xFF,0xFF);
}
pos.x += vel.x * (delta);
pos.y += vel.y * (delta);
pos.y = System.Math.Clamp(pos.y + (vel.y * delta),0,game_height - 64);
pos.x = System.Math.Clamp(pos.x + (vel.x * delta),0,game_width - 64);
}
public override void Draw()
{
if(timer > 2)
myTexture.SetColor(0x90,0x3f,0x39);
myTexture.Render((.)pos.x,(.)pos.y);
}
public override void Destroy()
{
delete myTexture;
delete abil;
delete abil2;
timer = 0;
}
public override void Init()
{
pos.x =500;
pos.y = 500;
vel.x = 0;
vel.y = 0;
abil = new Texture();
abil.LoadFromFile("Assets/abil.png");
abil2 = new Texture();
abil2.LoadFromFile("Assets/abil2.png");
myTexture = new Texture();
myTexture.LoadFromFile("Assets/ball.png");
}
}
class abil : Hud
{
public override void Draw(float delta)
{
/*
Ball.abil.Render(231,5);
if(Ball.timer > 2)
Ball.abil2.Render(231,5);
*/
}
}
}

View file

@ -0,0 +1,37 @@
using System;
using System.IO;
using SDL2;
namespace bounty_game
{
class DebugRenderTexture
{
///Create a screenshot
public static Result<void> Screenshot()
{
SDL.Rect viewport;
SDL.Surface* _surface;
SDL.RenderGetViewport(SDLManager.gGameRender,out viewport);
_surface = SDL.CreateRGBSurface(0,viewport.w,viewport.h,32,0,0,0,0);
SDL.RenderReadPixels(SDLManager.gGameRender,null,_surface.format.format,_surface.pixels,_surface.pitch);
String path = scope String(SDL.GetBasePath());
path.AppendF("Screenshots\\");
Directory.CreateDirectory(path);
path.Append(DateTime.Now.Ticks.ToString(.. scope .() ));
path.AppendF(".png");
SDLImage.SavePNG(_surface,path);
SDL.FreeSurface(_surface);
return .Ok;
}
}
}

246
src/Enemier.bf Normal file
View file

@ -0,0 +1,246 @@
using System.Collections;
namespace bounty_game
{
class Enemier : Entity
{
Texture myTexture;
float speed = 250f;
public static List<Slime> slimes;
public static SDL2.SDLMixer.Chunk *death = null;
float targetAngle = 0;
public static int wave = 1;
float timer = 0;
public override void Update(float delta)
{
speed += 0.0001f *delta;
int alive = 0;
timer += delta/1000;
if(timer > 2)
{
timer -= 2;
if(System.gRand.Next(-1,5) <= 0)
{
int ran = System.gRand.Next(0,3);
if(ran == 0)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
slimes.Add(a);
}
if(ran == 1)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(game_height-150,game_height);
slimes.Add(a);
}
if(ran == 2)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,150);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
if(ran == 3)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(game_width-150,game_width);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
}
}
if(slimes.Count == 0)
{
wave++;
GenerateSlimes(wave);
HeavySlime.GenerateSlimes(wave);
FastSlime.GenerateSlimes(wave);
MagiSlime.GenerateSlimes(wave);
}
for(int i = 0; i < slimes.Count; i++)
{
alive++;
vec2 move;
//move towards player
move.x = (PlayerBoxes.Apos.x - slimes[i].pos.x);
move.y = (PlayerBoxes.Apos.y - slimes[i].pos.y);
targetAngle = System.Math.Atan2(move.y,move.x);
let pi=3.142f, tau=2*pi;
let
diffA = (targetAngle+tau - slimes[i]. moveAngle)%tau,
diffB = (targetAngle-tau - slimes[i].moveAngle)%tau;
if(System.Math.Abs(diffA) < System.Math.Abs(diffB))
slimes[i].moveAngle += 0.004f*diffA;
else
slimes[i].moveAngle += 0.004f*diffB;
slimes[i].pos.x += System.Math.Cos(slimes[i].moveAngle)* speed *(delta/1000);
slimes[i].pos.y += System.Math.Sin(slimes[i].moveAngle) * speed* (delta/1000);
//calculate collision
float x = Ball.pos.x - slimes[i].pos.x;
float y = Ball.pos.y - slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 55)
{
slimes[i].isHurt = true;
slimes[i].vel.x += (.)(-x * Ball.vel.x * (2-0.01*wave));
slimes[i].vel.y += (.)(-y * Ball.vel.y * (2-0.01*wave));
}
//decrease velocity
slimes[i].vel.x -= 0.9f*slimes[i].vel.x * (delta/1000);
slimes[i].vel.y -= 0.9f*slimes[i].vel.y * (delta/1000);
//move towards velocity
slimes[i].pos.x += slimes[i].vel.x * (delta/1000);
slimes[i].pos.y += slimes[i].vel.y * (delta/1000);
if(slimes[i].pos.x > game_width -32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count++;
}
else if(slimes[i].pos.x < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count++;
}
else if(slimes[i].pos.y > game_height - 32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count++;
}
else if(slimes[i].pos.y < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count++;
}
}
}
public override void Draw()
{
for(int i = 0; i < slimes.Count; i++)
{
if(slimes[i].isHurt)
{
myTexture.SetColor(255,0,0);
slimes[i].isHurt = false;
}
else
{
myTexture.SetColor(255,255,255);
}
myTexture.Render((.)slimes[i].pos.x,(.)slimes[i].pos.y);
}
}
public override void Destroy()
{
delete myTexture;
delete slimes;
wave = 1;
SDL2.SDLMixer.FreeChunk(death);
}
public override void Init()
{
death = SDL2.SDLMixer.LoadWAV("Assets/death.wav");
myTexture = new Texture();
myTexture.LoadFromFile("Assets/slime.png");
slimes = new List<Slime>(500);
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
a.vel.x = 0;
a.vel.y = 0;
slimes.Add(a);
}
public void GenerateSlimes(int wave)
{
int amount = System.gRand.Next(wave,(.)(wave*4+5));
Title.WaveShowcase(wave);
if(amount > 0)
{
for(int i = amount;i > 0;--i)
{
int ran = System.gRand.Next(0,3);
if(ran == 0)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
slimes.Add(a);
}
if(ran == 1)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(game_height-150,game_height);
slimes.Add(a);
}
if(ran == 2)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,150);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
if(ran == 3)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(game_width-150,game_width);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
amount--;
}
}
}
}
struct Slime
{
public float moveAngle = 0;
public vec2 vel = vec2();
public vec2 pos = vec2();
public bool isHurt = false;
}
}

193
src/FastSlime.bf Normal file
View file

@ -0,0 +1,193 @@
using System.Collections;
namespace bounty_game
{
class FastSlime : Entity
{
Texture myTexture;
float speed = 400f;
public static List<Slime> slimes;
public static SDL2.SDLMixer.Chunk *death = null;
float targetAngle = 0;
public static int wave = 1;
float timer = 0;
public override void Update(float delta)
{
int alive = 0;
timer += delta/1000;
for(int i = 0; i < slimes.Count; i++)
{
alive++;
vec2 move;
//move towards player
move.x = (PlayerBoxes.Apos.x - slimes[i].pos.x);
move.y = (PlayerBoxes.Apos.y - slimes[i].pos.y);
targetAngle = System.Math.Atan2(move.y,move.x);
let pi=3.142f, tau=2*pi;
let
diffA = (targetAngle+tau - slimes[i]. moveAngle)%tau,
diffB = (targetAngle-tau - slimes[i].moveAngle)%tau;
if(System.Math.Abs(diffA) < System.Math.Abs(diffB))
slimes[i].moveAngle += 0.004f*diffA;
else
slimes[i].moveAngle += 0.004f*diffB;
slimes[i].pos.x += System.Math.Cos(slimes[i].moveAngle)* speed *(delta/1000);
slimes[i].pos.y += System.Math.Sin(slimes[i].moveAngle) * speed* (delta/1000);
//calculate collision
float x = Ball.pos.x - slimes[i].pos.x;
float y = Ball.pos.y - slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 60)
{
slimes[i].isHurt = true;
slimes[i].vel.x += (.)(-x * Ball.vel.x * 3);
slimes[i].vel.y += (.)(-y * Ball.vel.y * 3);
}
//decrease velocity
slimes[i].vel.x -= 0.9f*slimes[i].vel.x * (delta/1000);
slimes[i].vel.y -= 0.9f*slimes[i].vel.y * (delta/1000);
//move towards velocity
slimes[i].pos.x += slimes[i].vel.x * (delta/1000);
slimes[i].pos.y += slimes[i].vel.y * (delta/1000);
if(slimes[i].pos.x > game_width -32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 3;
}
else if(slimes[i].pos.x < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 3;
}
else if(slimes[i].pos.y > game_height - 32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 3;
}
else if(slimes[i].pos.y < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 3;
}
}
}
public override void Draw()
{
for(int i = 0; i < slimes.Count; i++)
{
if(slimes[i].isHurt)
{
myTexture.SetColor(255,0,0);
slimes[i].isHurt = false;
}
else
{
myTexture.SetColor(255,255,255);
}
myTexture.Render((.)slimes[i].pos.x,(.)slimes[i].pos.y);
}
}
public override void Destroy()
{
delete myTexture;
delete slimes;
wave = 1;
SDL2.SDLMixer.FreeChunk(death);
}
public override void Init()
{
death = SDL2.SDLMixer.LoadWAV("Assets/deathfast.wav");
myTexture = new Texture();
myTexture.LoadFromFile("Assets/slimef.png");
slimes = new List<Slime>(50);
}
public static void GenerateSlimes(int wave)
{
if(System.gRand.Next(-1,0) < 0 && wave >= 10)
{
int amount = System.gRand.Next(0,(.)(0.5*wave));
if(amount > 0)
{
for(int i = amount;i > 0;--i)
{
int ran = System.gRand.Next(0,3);
if(ran == 0)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
slimes.Add(a);
}
if(ran == 1)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(game_height-150,game_height);
slimes.Add(a);
}
if(ran == 2)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,150);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
if(ran == 3)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(game_width-150,game_width);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
amount--;
}
}
}
}
}
}

194
src/HeavySlime.bf Normal file
View file

@ -0,0 +1,194 @@
using System.Collections;
namespace bounty_game
{
class HeavySlime : Entity
{
Texture myTexture;
float speed = 150f;
public static List<Slime> slimes;
public static SDL2.SDLMixer.Chunk *death = null;
float targetAngle = 0;
public static int wave = 1;
float timer = 0;
public override void Update(float delta)
{
speed += 0.0001f *delta;
int alive = 0;
timer += delta/1000;
for(int i = 0; i < slimes.Count; i++)
{
alive++;
vec2 move;
//move towards player
move.x = (PlayerBoxes.Apos.x - slimes[i].pos.x);
move.y = (PlayerBoxes.Apos.y - slimes[i].pos.y);
targetAngle = System.Math.Atan2(move.y,move.x);
let pi=3.142f, tau=2*pi;
let
diffA = (targetAngle+tau - slimes[i]. moveAngle)%tau,
diffB = (targetAngle-tau - slimes[i].moveAngle)%tau;
if(System.Math.Abs(diffA) < System.Math.Abs(diffB))
slimes[i].moveAngle += 0.004f*diffA;
else
slimes[i].moveAngle += 0.004f*diffB;
slimes[i].pos.x += System.Math.Cos(slimes[i].moveAngle)* speed *(delta/1000);
slimes[i].pos.y += System.Math.Sin(slimes[i].moveAngle) * speed* (delta/1000);
//calculate collision
float x = Ball.pos.x - slimes[i].pos.x;
float y = Ball.pos.y - slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 55)
{
slimes[i].isHurt = true;
slimes[i].vel.x += (.)(-x * Ball.vel.x * 0.9);
slimes[i].vel.y += (.)(-y * Ball.vel.y * 0.9);
}
//decrease velocity
slimes[i].vel.x -= 0.9f*slimes[i].vel.x * (delta/1000);
slimes[i].vel.y -= 0.9f*slimes[i].vel.y * (delta/1000);
//move towards velocity
slimes[i].pos.x += slimes[i].vel.x * (delta/1000);
slimes[i].pos.y += slimes[i].vel.y * (delta/1000);
if(slimes[i].pos.x > game_width -32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.x < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.y > game_height - 32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.y < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
}
}
public override void Draw()
{
for(int i = 0; i < slimes.Count; i++)
{
if(slimes[i].isHurt)
{
myTexture.SetColor(255,0,0);
slimes[i].isHurt = false;
}
else
{
myTexture.SetColor(255,255,255);
}
myTexture.Render((.)slimes[i].pos.x,(.)slimes[i].pos.y);
}
}
public override void Destroy()
{
delete myTexture;
delete slimes;
wave = 1;
SDL2.SDLMixer.FreeChunk(death);
}
public override void Init()
{
death = SDL2.SDLMixer.LoadWAV("Assets/deathheavy.wav");
myTexture = new Texture();
myTexture.LoadFromFile("Assets/slimemetal.png");
slimes = new List<Slime>(50);
}
public static void GenerateSlimes(int wave)
{
if(System.gRand.Next(-1,1) < 0 && wave >= 5)
{
int amount = System.gRand.Next(0,(.)wave);
if(amount > 0)
{
for(int i = amount;i > 0;--i)
{
int ran = System.gRand.Next(0,3);
if(ran == 0)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
slimes.Add(a);
}
if(ran == 1)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(game_height-150,game_height);
slimes.Add(a);
}
if(ran == 2)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,150);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
if(ran == 3)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(game_width-150,game_width);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
amount--;
}
}
}
}
}
}

10
src/IO/BeefIncludes.bf Normal file

File diff suppressed because one or more lines are too long

148
src/IO/Texture.bf Normal file
View file

@ -0,0 +1,148 @@
using System;
using SDL2;
namespace bounty_game
{
class Texture
{
//Private member variables of the texture
private int32 mWidth;
private int32 mHeight;
private SDL.Texture* mTexture;
public ~this()
{
free();
}
//Loading functions
///Load a Texture from a specific path
public Result<void> LoadFromFile(String path)
{
free();
SDL.Texture* newTexture = null;
SDL.Surface* loadedSurface = SDLImage.Load(path);
if(loadedSurface == null)
return .Err;
newTexture = SDL.CreateTextureFromSurface(SDLManager.gGameRender,loadedSurface);
if(newTexture == null)
return .Err;
mWidth = loadedSurface.w;
mHeight = loadedSurface.h;
SDL.FreeSurface(loadedSurface);
this.mTexture = newTexture;
return .Ok;
}
///Load a Texture from memory
public Result<void> LoadFromMem(void* data, int32 size)
{
free();
SDL2.SDL.Texture* newTexture = null;
SDL.Surface* tempsurface = null;
SDL.RWOps* temp = SDL.RWFromMem(data,size);
tempsurface = SDLImage.Load_RW(temp,0);
if(tempsurface == null)
return .Err;
newTexture = SDL.CreateTextureFromSurface(SDLManager.gGameRender,tempsurface);
if(newTexture == null)
return .Err;
mWidth = tempsurface.w;
mHeight = tempsurface.h;
SDL2.SDL.FreeSurface(tempsurface);
this.mTexture = newTexture;
return .Ok;
}
public Result<void> LoadFromString(String text,SDL.Color color, SDLTTF.Font* font)
{
free();
SDL.Surface* textSurface = SDLTTF.RenderText_Solid(font,text,color);
if(textSurface == null)
return .Err;
mTexture = SDL.CreateTextureFromSurface(SDLManager.gGameRender,textSurface);
if(mTexture == null)
return .Err;
mWidth = textSurface.w;
mHeight = textSurface.h;
SDL.FreeSurface(textSurface);
return .Ok;
}
public void LoadFromStringWrapped(String text,SDL.Color color, SDLTTF.Font* font,uint size)
{
free();
SDL.Surface* textSurface = SDLTTF.RenderText_Blended_Wrapped(font,text,color,size);
if(textSurface == null)
return;
mTexture = SDL.CreateTextureFromSurface(SDLManager.gGameRender,textSurface);
if(mTexture == null)
return;
mWidth = textSurface.w;
mHeight = textSurface.h;
SDL.FreeSurface(textSurface);
}
public int32 GetWidth
{
get
{
return mWidth;
}
}
public int32 GetHeight
{
get
{
return mHeight;
}
}
[Inline]
public void SetColor(uint8 r, uint8 g, uint8 b)
{
SDL.SetTextureColorMod(mTexture,r,g,b);
}
[Inline]
public void SetBlendMode( SDL.BlendMode blending )
{
SDL.SetTextureBlendMode(mTexture,blending);
}
[Inline]
public void SetAlpha( uint8 alpha )
{
SDL.SetTextureAlphaMod(mTexture,alpha);
}
public void free()
{
if(mTexture != null)
{
SDL2.SDL.DestroyTexture(mTexture);
mTexture = null;
mWidth = 0;
mHeight = 0;
}
}
///Renders texture at given point
public void Render( int32 x, int32 y, SDL.Rect* clip = null, double angle = 0.0, SDL.Point* center = null, SDL.RendererFlip flip = .None )
{
SDL.Rect renderQuad = SDL.Rect(x,y,mWidth,mHeight);
if(clip != null)
{
renderQuad.w = clip.w;
renderQuad.h = clip.h;
}
SDL.RenderCopyEx(SDLManager.gGameRender,mTexture,clip,&renderQuad,angle,center,flip);
}
}
}

63
src/InfoScene.bf Normal file
View file

@ -0,0 +1,63 @@
namespace bounty_game
{
class InfoScene : Scene
{
public override void Load()
{
base.Load();
this.AddEntity(new Background());
this.AddEntity(new foreground());
this.AddEntity(new Item());
}
}
class Item : Entity
{
public bool* gCurrentKeyStates;
public bool[] gLastKeyStates;
public System.String Text = """
Guide:
WASD: Move
M1: Launch flail
Throw the slimes back into the forest to kill them.
Killing slimes will grant hp, hp will slowly deplete over time
Mushrooms will spawn that grant usefull effects.
If your hp is 0 you have lost.
How long can you survive ?
Enter to exit this page
""";
Texture myTexture;
float timer = 0;
public override void Update(float delta)
{
gCurrentKeyStates = Game.gCurrentScene.gCurrentKeyStates;
gLastKeyStates = Game.gCurrentScene.gLastKeyStates;
timer += delta/1000;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] != gLastKeyStates[(int)SDL2.SDL.Scancode.Return] && timer > 1)
{
Game.gCurrentScene = new MenuScene();
Game.changedScene = true;
}
}
public override void Draw()
{
myTexture.Render(game_width/2 - myTexture.GetWidth/2,game_height/2 - myTexture.GetHeight/2);
}
public override void Destroy()
{
delete myTexture;
}
public override void Init()
{
myTexture = new Texture();
myTexture.LoadFromStringWrapped(Text,SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.LargeFont,500);
}
}
}

17
src/Lifebar.bf Normal file
View file

@ -0,0 +1,17 @@
namespace bounty_game
{
class Lifebar : Hud
{
public static float hight= 30;
public override void Draw(float delta)
{
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,0x90,0x3f,0x39,255);
SDL2.SDL.Rect test = .(5+PlayerBoxes.hitoffsetx,5+PlayerBoxes.hitoffsety, (.)(200*PlayerBoxes.hp/PlayerBoxes.maxhp),30);
SDL2.SDL.RenderFillRect(SDLManager.gGameRender,&test);
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,0xFF,0xFF,0xFF,0xFF);
SDL2.SDL.Rect test2 = .(4+PlayerBoxes.hitoffsetx,4+PlayerBoxes.hitoffsety, 201,31);
SDL2.SDL.RenderDrawRect(SDLManager.gGameRender,&test2);
}
}
}

12
src/Logic/Bases/Entity.bf Normal file
View file

@ -0,0 +1,12 @@
namespace bounty_game
{
abstract class Entity
{
public float x = 0;
public float y = 0;
public abstract void Update(float delta);
public abstract void Draw();
public abstract void Destroy();
public abstract void Init();
}
}

80
src/Logic/Bases/Game.bf Normal file
View file

@ -0,0 +1,80 @@
using System;
using System.Collections;
using SDL2;
namespace bounty_game
{
class Game
{
public static Scene gCurrentScene;
public static bool quit = false;
private static double Framtime;
private static float measurement = 1;
private static float smoothing = 0.9f;
public static bool changedScene = false;
public static bool fullscreen = false;
public static void Init(String GameTitle,int32 width,int32 height)
{
if(SDLManager.Init(GameTitle,width,height) == .Err)
Runtime.FatalError("Couldnt initialize the game");
SDLManager.LoadStandartMedia();
}
public static void Close()
{
SDLManager.Close();
}
public static void Run()
{
gCurrentScene = new InitScene();
double beforeTime = (double)SDL.GetPerformanceCounter() / SDL.GetPerformanceFrequency();
while(!quit)
{
while(SDL.PollEvent(out SDLManager.gGameEvents) != 0)
{
if(SDLManager.gGameEvents.type == .Quit)
quit = true;
}
SDL.RenderClear(SDLManager.gGameRender);
if(Scene.doDebug && Scene.doDraw)
{
SDL.SetRenderDrawColor(SDLManager.gGameRender,0xFF,0xFF,0xFF,0xFF);
SDL.Rect* Test = scope SDL.Rect(0,35,(.)(Framtime*100000),20);
SDL.RenderFillRect(SDLManager.gGameRender,Test);
SDL.SetRenderDrawColor(SDLManager.gGameRender,0x55,0x45,0x65,0xFF);
}
Framtime =(double)SDL.GetPerformanceCounter() / SDL.GetPerformanceFrequency();
double currentTime = (double)SDL.GetPerformanceCounter() / SDL.GetPerformanceFrequency();
float deltaTime = (.)(currentTime - beforeTime)*1000;
beforeTime = currentTime;
SDL.SetRenderDrawColor(SDLManager.gGameRender,0x55,0x45,0x65,0xFF);
gCurrentScene.Update(deltaTime);
SDL.RenderPresent(SDLManager.gGameRender);
Framtime =(double)SDL.GetPerformanceCounter() / SDL.GetPerformanceFrequency() - Framtime;
}
delete gCurrentScene;
}
}
}

7
src/Logic/Bases/Hud.bf Normal file
View file

@ -0,0 +1,7 @@
namespace bounty_game
{
abstract class Hud
{
public abstract void Draw(float delta);
}
}

View file

@ -0,0 +1,50 @@
namespace bounty_game
{
class InitScene : Scene
{
public override void Load()
{
base.Load();
AddEntity(new Book());
AddEntity(new Image());
}
}
class Image : Entity
{
float timer = 0;
bool doDraw = true;
public override void Update(float delta)
{
timer = timer + 1*delta;
if(timer > 1*1000)
{
doDraw = false;
if(timer > 2.5*1000)
{
Game.gCurrentScene = new MenuScene();
Game.changedScene = true;
}
}
}
public override void Destroy()
{
}
public override void Init()
{
this.x = game_width/2 - SDLManager.GetBeefTitle().GetWidth/2;
this.y = game_height/2 - SDLManager.GetBeefTitle().GetHeight/2;
}
public override void Draw()
{
if(doDraw)
SDLManager.GetBeefTitle().Render((.)x,(.)y);
}
}
}

View file

@ -0,0 +1,82 @@
using System;
using System.Collections;
using SDL2;
namespace bounty_game
{
class SDLManager
{
//global variables
public static SDL.Window* gGameWindow;
public static SDL.Renderer* gGameRender;
public static SDL.Event gGameEvents;
//Global static variables
private static Texture BeefTitle;
private static Texture BookTitle;
private static SDLTTF.Font *DefaultFont;
public static SDLTTF.Font *LargeFont;
public static Texture GetBeefTitle()
{
return BeefTitle;
}
public static Texture GetBookTitle()
{
return BookTitle;
}
public static SDLTTF.Font* GetDefaultFont()
{
return DefaultFont;
}
///Initialize SDL2
public static Result<void> Init(String gGameTitle,int32 gGameWidth, int32 gGameHeight)
{
if(SDL.Init(.Everything) < 0)
return .Err;
gGameWindow = SDL.CreateWindow(gGameTitle,.Centered,.Centered,gGameWidth,gGameHeight,.Shown);
if(gGameWindow == null)
return .Err;
gGameRender = SDL.CreateRenderer(gGameWindow,-1, .Accelerated);
if(gGameRender == null)
return .Err;
SDL.SetRenderDrawColor(gGameRender,0x55,0x45,0x65,0xFF);
SDLImage.InitFlags ImgFlags = SDLImage.InitFlags.PNG;
if((int)((SDLImage.InitFlags)SDLImage.Init(ImgFlags) & ImgFlags) != 2)
return .Err;
if(SDLTTF.Init() < 0)
return .Err;
if(SDLMixer.OpenAudio(44100,SDLMixer.MIX_DEFAULT_FORMAT,2,2048) < 0)
return .Err;
return .Ok;
}
public static void LoadStandartMedia()
{
BeefTitle = new Texture();
BeefTitle.LoadFromMem(&BeefIncludes.beef_title,BeefIncludes.beef_title.Count*8);
BookTitle = new Texture();
BookTitle.LoadFromMem(&BeefIncludes.bookhead,BeefIncludes.bookhead.Count*8);
SDL.RWOps* temp = SDL.RWFromMem(&BeefIncludes.sono_regular,BeefIncludes.sono_regular.Count*8);
DefaultFont = SDLTTF.OpenFontRW(temp,1,12);
LargeFont = SDLTTF.OpenFontRW(temp,1,30);
}
///Close everything SDL2
public static void Close()
{
BeefTitle.free();
BookTitle.free();
delete(BeefTitle);
delete(BookTitle);
SDLTTF.CloseFont(DefaultFont);
SDL.DestroyWindow(gGameWindow);
SDL.DestroyRenderer(gGameRender);
SDL.Quit();
SDLImage.Quit();
SDLTTF.Quit();
SDLMixer.Quit();
}
}
}

186
src/Logic/Bases/Scene.bf Normal file
View file

@ -0,0 +1,186 @@
using System;
using System.Collections;
using SDL2;
namespace bounty_game
{
class Scene
{
public List<Entity> SceneEntities;
public List<Hud> SceneHuds;
public List<Hud> DebugHud;
public static bool doDraw = true; //
public static bool doDebug = false; //
private bool doHud = true; //
private bool runGame = true; //
//Take screenshot |
//Reload Scene //
private bool showConsole = false;
public bool* gCurrentKeyStates;
public bool[] gLastKeyStates;
int32 len;
/*
Debug key commands:
alt + 1 = take screenshot
alt + 2 = toggle debug menu
alt + 3 = toggle hud
alt + 4 = toggle rendering
alt + 5 = toggle pause
alt + 6 = reset scene
// Unimplemented
alt + 7 = (show console)
alt + 8 = (show debug menu)
*/
private static float deltaT = 0;
private static float measurement = 1;
private static float smoothing = 0.9f;
public static bool reset = false;
public this()
{
Load();
}
public ~this()
{
Delete();
}
public virtual void Update(float delta)
{
deltaT = delta;
gCurrentKeyStates = SDL2.SDL.GetKeyboardState(&len);
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key2] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key2] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key2] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt])
Scene.doDebug = !doDebug;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key3] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key3] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key3] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt])
doHud = !doHud;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key4] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key4] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key4] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt])
Scene.doDraw = !Scene.doDraw;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key5] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key5] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key5] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt])
runGame = !runGame;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key6] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key6] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key6] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt] || reset)
{
reset = false;
Reset();
}
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.F] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.F] != gLastKeyStates[(int)SDL2.SDL.Scancode.F])
{
if(!Game.fullscreen)
{
SDL2.SDL.SetWindowFullscreen(SDLManager.gGameWindow,(.)SDL2.SDL.WindowFlags.Fullscreen);
Game.fullscreen = true;
}
else
{
SDL2.SDL.SetWindowFullscreen(SDLManager.gGameWindow,0);
Game.fullscreen = false;
}
}
if(runGame)
for(Entity e in SceneEntities)
e.Update(delta);
Draw(delta);
for(int i < len)
gLastKeyStates[i] = gCurrentKeyStates[i];
if(Game.changedScene)
{
delete this;
Game.changedScene = false;
}
}
public void Draw(float delta)
{
if(Scene.doDraw)
{
for(Entity e in SceneEntities)
e.Draw();
for(Hud e in SceneHuds)
e.Draw(delta);
if(Scene.doDebug)
{
for(Hud e in DebugHud)
e.Draw(delta);
SDL.SetRenderDrawColor(SDLManager.gGameRender,0xFF,0xFF,0xFF,0xFF);
measurement = (measurement * smoothing) + (1/(deltaT/1000) * (1.0f-smoothing));
Texture fps = scope Texture();
fps.LoadFromString(measurement.ToString(.. scope String()),SDL.Color(0xFF,0xFF,0xFF,0xFF),SDLManager.GetDefaultFont());
fps.Render(0,20);
//
Texture mpos = scope Texture();
int32 mx = 0, my = 0;
SDL.GetMouseState(&mx,&my);
String values = mx.ToString(.. scope String());
values.AppendF(" / ");
values.AppendF(my.ToString(.. scope String()));
mpos.LoadFromString(values,SDL.Color(0xFF,0xFF,0xFF,0xFF),SDLManager.GetDefaultFont());
mpos.Render(0,0);
//
SDL.SetRenderDrawColor(SDLManager.gGameRender,0x55,0x45,0x65,0xFF);
}
}
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key1] && gLastKeyStates[(int)SDL2.SDL.Scancode.Key1] != gCurrentKeyStates[(int)SDL2.SDL.Scancode.Key1] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.RAlt])
DebugRenderTexture.Screenshot();
}
public void AddEntity(Entity entity)
{
entity.Init();
SceneEntities.Add(entity);
}
public void RemoveEntity(Entity entity)
{
SceneEntities.Remove(entity);
delete(entity);
}
public void Reset()
{
Delete();
Load();
}
///Reset the current scene to its default state
public virtual void Delete()
{
for(Entity i in SceneEntities)
i.Destroy();
DeleteContainerAndItems!(this.SceneHuds);
DeleteContainerAndItems!(this.SceneEntities);
DeleteContainerAndItems!(this.DebugHud);
delete gLastKeyStates;
}
public virtual void Load()
{
SDL2.SDL.GetKeyboardState(&len);
gLastKeyStates = new bool[len];
SceneEntities = new List<Entity>();
SceneHuds = new List<Hud>();
DebugHud = new List<Hud>();
}
}
}

215
src/MagiSlime.bf Normal file
View file

@ -0,0 +1,215 @@
using System.Collections;
namespace bounty_game
{
class MagiSlime : Entity
{
Texture myTexture;
float speed = 400f;
public static List<Slime> slimes;
public static SDL2.SDLMixer.Chunk *death = null;
float targetAngle = 0;
public static int wave = 1;
float timer = 0;
public override void Update(float delta)
{
int alive = 0;
timer += delta/1000;
for(int i = 0; i < slimes.Count; i++)
{
if(timer > 2)
{
timer = 0;
slimes[i].pos.x = System.gRand.Next(0,game_width);
slimes[i].pos.y = System.gRand.Next(0,game_height);
}
alive++;
vec2 move;
//move towards player
move.x = (PlayerBoxes.Apos.x - slimes[i].pos.x);
move.y = (PlayerBoxes.Apos.y - slimes[i].pos.y);
targetAngle = System.Math.Atan2(move.y,move.x);
let pi=3.142f, tau=2*pi;
let
diffA = (targetAngle+tau - slimes[i]. moveAngle)%tau,
diffB = (targetAngle-tau - slimes[i].moveAngle)%tau;
if(System.Math.Abs(diffA) < System.Math.Abs(diffB))
slimes[i].moveAngle += 0.004f*diffA;
else
slimes[i].moveAngle += 0.004f*diffB;
slimes[i].pos.x += System.Math.Cos(slimes[i].moveAngle)* speed *(delta/1000);
slimes[i].pos.y += System.Math.Sin(slimes[i].moveAngle) * speed* (delta/1000);
//calculate collision
float x = Ball.pos.x - slimes[i].pos.x;
float y = Ball.pos.y - slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 60)
{
slimes[i].isHurt = true;
slimes[i].vel.x += (.)(-x * Ball.vel.x * 0.8);
slimes[i].vel.y += (.)(-y * Ball.vel.y * 0.8);
}
//decrease velocity
slimes[i].vel.x -= 0.9f*slimes[i].vel.x * (delta/1000);
slimes[i].vel.y -= 0.9f*slimes[i].vel.y * (delta/1000);
//move towards velocity
slimes[i].pos.x += slimes[i].vel.x * (delta/1000);
slimes[i].pos.y += slimes[i].vel.y * (delta/1000);
if(slimes[i].pos.x > game_width -32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.x < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.y > game_height - 32)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
else if(slimes[i].pos.y < 0)
{
SDL2.SDLMixer.PlayChannel(-1,death,0);
slimes.RemoveAt(i);
PlayerBoxes.hp += 90;
KillHud.count += 2;
}
}
}
public override void Draw()
{
for(int i = 0; i < slimes.Count; i++)
{
if(slimes[i].isHurt)
{
myTexture.SetColor(255,0,0);
slimes[i].isHurt = false;
}
else
{
myTexture.SetColor(255,255,255);
}
myTexture.Render((.)slimes[i].pos.x,(.)slimes[i].pos.y);
}
}
public override void Destroy()
{
delete myTexture;
delete slimes;
wave = 1;
SDL2.SDLMixer.FreeChunk(death);
}
public override void Init()
{
death = SDL2.SDLMixer.LoadWAV("Assets/deathmagi.wav");
myTexture = new Texture();
myTexture.LoadFromFile("Assets/slimem.png");
slimes = new List<Slime>(50);
}
public static void GenerateSlimes(int wave)
{
if(System.gRand.Next(-1,0) < 0 && wave >= 15)
{
int amount = 4;
if(wave < 20)
amount = 1;
else if(wave < 25)
amount = 2;
else if(wave < 45)
amount = 3;
else if(wave < 60)
amount = 4;
else if(wave < 80)
amount = 5;
else if(wave < 150)
amount = 6;
if(amount > 0)
{
for(int i = amount;i > 0;--i)
{
int ran = System.gRand.Next(0,3);
if(ran == 0)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(0,150);
slimes.Add(a);
}
if(ran == 1)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,game_width);
a.pos.y = System.gRand.Next(game_height-150,game_height);
slimes.Add(a);
}
if(ran == 2)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(0,150);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
if(ran == 3)
{
Slime a = Slime();
a.pos.x = System.gRand.Next(game_width-150,game_width);
a.pos.y = System.gRand.Next(0,game_height);
slimes.Add(a);
}
amount--;
}
}
}
}
}
}

27
src/MainMenu/Book.bf Normal file
View file

@ -0,0 +1,27 @@
namespace bounty_game
{
class Book : Entity
{
public override void Update(float delta)
{
}
public override void Draw()
{
SDLManager.GetBookTitle().Render( game_width/2 - SDLManager.GetBookTitle().GetWidth/2, game_height/2 - SDLManager.GetBookTitle().GetHeight/2);
}
public override void Destroy()
{
}
public override void Init()
{
}
}
}

51
src/MainMenu/Info.bf Normal file
View file

@ -0,0 +1,51 @@
namespace bounty_game
{
class Info : Entity
{
Texture jam = new Texture();
Texture logo = new Texture();
Texture tex = new Texture();
System.String text = """
- Slime Slammer -
Submission to the gmtk 2021 gamejam
Made by: Booklordofthedings
@Booklordofthed1
Programming language: Beeflang
Engine: none (selfmade + sdl2)
Fonts:
Old Newspaper type
Sono by Tyler Fink
Special thanks:
ppl from the Beef discord for tech support
""";
public override void Update(float delta)
{
}
public override void Draw()
{
jam.Render(0,500);
logo.Render(game_width/2 - logo.GetWidth/2 ,0);
tex.Render(game_width-tex.GetWidth -5,game_height-tex.GetHeight-5);
}
public override void Destroy()
{
delete tex;
delete jam;
delete logo;
}
public override void Init()
{
jam.LoadFromFile("Assets/jam.png");
logo.LoadFromFile("Assets/logo.png");
tex.LoadFromStringWrapped(text,SDL2.SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.GetDefaultFont(),200);
}
}
}

19
src/MainMenu/MenuScene.bf Normal file
View file

@ -0,0 +1,19 @@
namespace bounty_game
{
class MenuScene : Scene
{
public override void Load()
{
base.Load();
this.AddEntity(new foreground());
this.AddEntity(new Info());
this.SceneHuds.Add(new SceneSelector());
}
public override void Delete()
{
base.Delete();
}
}
}

View file

@ -0,0 +1,90 @@
using SDL2;
using System;
namespace bounty_game
{
class SceneSelector : Hud
{
public bool* gCurrentKeyStates;
public bool[] gLastKeyStates;
public static SDL2.SDLMixer.Chunk *select = null;
float timer = 0;
SDL.Rect b1 = .(game_width/2 -150,game_height/2-25,300,50);
SDL.Point[?] points = SDL.Point[](.(game_width/2,game_height/2 -75),.(game_width/2 -12,game_height/2 -50),.(game_width/2 +12,game_height/2 -50),.(game_width/2,game_height/2 -75));
SDL.Point[?] points2 = SDL.Point[](.(game_width/2,game_height/2 +75),.(game_width/2 -12,game_height/2 +50),.(game_width/2 + 12,game_height/2 +50),.(game_width/2,game_height/2 +75));
int cselect = 0;
String[3] options = String[](
"Arcade mode",
"Guide Screen",
"End game"
);
public bool isinit = false;
public Texture[] textures = new Texture[4]();
public override void Draw(float delta)
{
if(!isinit)
{
for(int i < options.Count)
{
textures[i] = new Texture();
textures[i].LoadFromString(options[i],SDL.Color(0xFF,0xFf,0xFf,0xFF),SDLManager.LargeFont);
}
isinit = true;
select = SDLMixer.LoadWAV("Assets/select.wav");
}
timer += delta/1000;
gCurrentKeyStates = Game.gCurrentScene.gCurrentKeyStates;
gLastKeyStates = Game.gCurrentScene.gLastKeyStates;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.W] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.W] != gLastKeyStates[(int)SDL.Scancode.W])
cselect--;
else if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.S] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.S] != gLastKeyStates[(int)SDL.Scancode.S])
cselect++;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] && gCurrentKeyStates[(int)SDL2.SDL.Scancode.Return] != gLastKeyStates[(int)SDL.Scancode.Return] && timer > 0.5)
{
switch(cselect)
{
case 0:
SDLMixer.PlayChannel(-1,select,0);
Game.gCurrentScene = new TestScene();
Game.changedScene = true;
break;
case 1:
SDLMixer.PlayChannel(-1,select,0);
Game.gCurrentScene = new InfoScene();
Game.changedScene = true;
break;
case 2:
Game.quit = true;
break;
default:
}
}
if(cselect > options.Count-1)
cselect = options.Count-1;
else if(cselect < 0)
cselect = 0;
SDL.SetRenderDrawColor(SDLManager.gGameRender,0x00,0xFF,0x00,0xFF);
SDL.RenderDrawRect(SDLManager.gGameRender,&b1);
SDL.RenderDrawLines(SDLManager.gGameRender,&points,4);
SDL.RenderDrawLines(SDLManager.gGameRender,&points2,4);
textures[cselect].Render(game_width/2 - textures[cselect].GetWidth/2,game_height/2 - textures[cselect].GetHeight/2);
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,0x55,0x45,0x65,0xFF);
}
public ~this()
{
for(Texture i in textures)
delete i;
delete textures;
SDLMixer.FreeChunk(select);
}
}
}

20
src/Minimap.bf Normal file
View file

@ -0,0 +1,20 @@
namespace bounty_game
{
class Minimap : Hud
{
public override void Draw(float delta)
{
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,255,255,255,255);
SDL2.SDL.Rect test = .(5+PlayerBoxes.hitoffsetx,600+PlayerBoxes.hitoffsety, 160,90);
SDL2.SDL.RenderDrawRect(SDLManager.gGameRender,&test);
SDL2.SDL.Rect pos = .((.)(160*PlayerBoxes.Apos.x/1280)+5-5+PlayerBoxes.hitoffsetx,(.)(90*PlayerBoxes.Apos.y/720)+600-5+PlayerBoxes.hitoffsety,10,10);
SDL2.SDL.RenderDrawRect(SDLManager.gGameRender,&pos);
for(int i < Enemier.slimes.Count)
{
SDL2.SDL.RenderDrawPoint(SDLManager.gGameRender,(.)(160*Enemier.slimes[i].pos.x/1280)+5+PlayerBoxes.hitoffsetx,(.)(90*Enemier.slimes[i].pos.y/720)+600+PlayerBoxes.hitoffsety);
}
}
}
}

19
src/Program.bf Normal file
View file

@ -0,0 +1,19 @@
using System;
using SDL2;
namespace bounty_game
{
public static{
public static String game_Name = "Slime Slammers";
public static int32 game_width = 1280;
public static int32 game_height = 720;
}
class Program
{
public static void Main()
{
Game.Init(game_Name,game_width,game_height);
Game.Run();
Game.Close();
}
}
}

339
src/TestScene.bf Normal file
View file

@ -0,0 +1,339 @@
namespace bounty_game
{
class TestScene : Scene
{
public override void Load()
{
base.Load();
this.SceneHuds.Add(new Minimap());
this.SceneHuds.Add(new Lifebar());
this.SceneHuds.Add(new Title());
this.AddEntity(new Background());
this.AddEntity(new PlayerBoxes());
this.AddEntity(new Ball());
this.AddEntity(new Enemier());
this.AddEntity(new HeavySlime());
this.AddEntity(new FastSlime());
this.AddEntity(new MagiSlime());
this.AddEntity(new dog());
this.AddEntity(new foreground());
this.AddEntity(new KillHud());
Lifebar.hight = 30;
}
}
class PlayerBoxes : Entity
{
public static int32 hitoffsetx;
public static int32 hitoffsety;
public bool* gCurrentKeyStates;
public bool[] gLastKeyStates;
bool ishit;
public Texture myTexture;
public static vec2 Apos;
vec2 movTest2;
public static float max = 0.6f;
float accel = 0.06f;
float deveö = 0.01f;
public static vec2 movTest = vec2();
public static vec2 vel;
public SDL2.SDLMixer.Music *music;
float timer = 0;
public static float hp;
public const float maxhp = 10000;
public override void Update(float delta)
{
if(hitoffsetx < 0)
hitoffsetx++;
else if(hitoffsetx > 0)
hitoffsetx--;
if(hitoffsety < 0)
hitoffsety++;
else if(hitoffsety > 0)
hitoffsety--;
gCurrentKeyStates = Game.gCurrentScene.gCurrentKeyStates;
gLastKeyStates = Game.gCurrentScene.gLastKeyStates;
movTest = vec2();
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.W])
movTest.y = -1;
else if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.S])
movTest.y = 1;
if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.A])
movTest.x = -1;
else if(gCurrentKeyStates[(int)SDL2.SDL.Scancode.D])
movTest.x = 1;
movTest.normalize();
if(movTest.x != 0)
{
vel.x = vel.x + accel * delta * movTest.x;
}
else
{
if(vel.x < 0)
{
vel.x = vel.x + deveö * delta;
if(vel.x > 0)
vel.x = 0;
}
else
{
vel.x = vel.x - deveö * delta;
if(vel.x < 0)
vel.x = 0;
}
}
if(movTest.y != 0)
{
vel.y = vel.y + accel * delta * movTest.y;
}
else
{
if(vel.y < 0)
{
vel.y = vel.y + deveö * delta;
if(vel.y > 0)
vel.y = 0;
}
else
{
vel.y = vel.y - deveö * delta;
if(vel.y < 0)
vel.y = 0;
}
}
if(vel.x !=0 && vel.y != 0)
{
if(System.Math.Sqrt(vel.x*vel.x + vel.y * vel.y) > max)
{
vel.normalize();
vel.x = vel.x * max;
vel.y = vel.y * max;
}
if(System.Math.Sqrt(vel.x*vel.x + vel.y * vel.y) < -max)
{
vel.normalize();
vel.x = vel.x * -max;
vel.y = vel.y * -max;
}
}
else
{
if(vel.x > max)
vel.x = max;
else if(vel.x < -max)
vel.x = -max;
if(vel.y > max)
vel.y = max;
else if(vel.y < -max)
vel.y = -max;
}
Apos.y = System.Math.Clamp(Apos.y + (vel.y * delta),55,680 - 32);
Apos.x = System.Math.Clamp(Apos.x + (vel.x * delta),60,1230 - 32);
for(int i = 0; i < Enemier.slimes.Count; i++)
{
float x = Apos.x - Enemier.slimes[i].pos.x;
float y = Apos.y - Enemier.slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 20)
{
hp -= 3 * delta;
ishit = true;
hitoffsety += System.gRand.Next(-3,3);
hitoffsetx += System.gRand.Next(-3,3);
}
}
if(hp > maxhp)
hp -= delta * 1f;
else
hp -= delta * 0.1f;
if(hp < 0)
{
EndHud.timer = KillHud.timeLived;
EndHud.wave = Enemier.wave;
EndHud.killcount = KillHud.count;
Game.gCurrentScene = new EndScene();
Game.changedScene = true;
}
for(int i = 0; i < HeavySlime.slimes.Count; i++)
{
float x = Apos.x - HeavySlime.slimes[i].pos.x;
float y = Apos.y - HeavySlime.slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 20)
{
hp -= 5 * delta;
ishit = true;
hitoffsety += System.gRand.Next(-3,3);
hitoffsetx += System.gRand.Next(-3,3);
}
}
if(hp < 0)
{
EndHud.timer = KillHud.timeLived;
EndHud.wave = Enemier.wave;
EndHud.killcount = KillHud.count;
Game.gCurrentScene = new EndScene();
Game.changedScene = true;
}
for(int i = 0; i < FastSlime.slimes.Count; i++)
{
float x = Apos.x - FastSlime.slimes[i].pos.x;
float y = Apos.y - FastSlime.slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 20)
{
hp -= 5 * delta;
ishit = true;
hitoffsety += System.gRand.Next(-3,3);
hitoffsetx += System.gRand.Next(-3,3);
}
}
if(hp < 0)
{
EndHud.timer = KillHud.timeLived;
EndHud.wave = Enemier.wave;
EndHud.killcount = KillHud.count;
Game.gCurrentScene = new EndScene();
Game.changedScene = true;
}
for(int i = 0; i < MagiSlime.slimes.Count; i++)
{
float x = Apos.x - MagiSlime.slimes[i].pos.x;
float y = Apos.y - MagiSlime.slimes[i].pos.y;
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght < 20)
{
hp -= 10 * delta;
ishit = true;
hitoffsety += System.gRand.Next(-3,3);
hitoffsetx += System.gRand.Next(-3,3);
}
}
if(hp < 0)
{
EndHud.timer = KillHud.timeLived;
EndHud.wave = Enemier.wave;
EndHud.killcount = KillHud.count;
Game.gCurrentScene = new EndScene();
Game.changedScene = true;
}
}
public override void Draw()
{
myTexture.SetColor(0xFF,0xFF,0xFF);
if(ishit)
{
myTexture.SetColor(0x90,0x3f,0x39);
ishit = false;
}
myTexture.Render((.)Apos.x,(.)Apos.y);
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,255,255,255,255);
SDL2.SDL.RenderDrawLine(SDLManager.gGameRender,(.)Apos.x +16,(.)Apos.y+16,(.)Ball.pos.x+32,(.)Ball.pos.y+32);
SDL2.SDL.SetRenderDrawColor(SDLManager.gGameRender,0x55,0x45,0x65,0xFF);
}
public override void Destroy()
{
delete myTexture;
delete Title.title;
SDL2.SDLMixer.FreeMusic(music);
}
public override void Init()
{
music = SDL2.SDLMixer.LoadMUS("Assets/brawl.wav");
SDL2.SDLMixer.PlayMusic(music,-1);
ishit = false;
hp = maxhp;
Apos.y = 500;
Apos.x = 500;
movTest.x = 0;
movTest.y = 0;
vel.x = 0;
vel.y = 0;
hitoffsetx = 0;
hitoffsety = 0;
myTexture = new Texture();
myTexture.LoadFromFile("Assets/box.png");
}
public void SetKeyCode(bool* cState)
{
gCurrentKeyStates = cState;
}
}
struct vec2
{
public float x = 0,y = 0;
[System.InlineAttribute]
public void normalize() mut
{
float lenght = System.Math.Sqrt(x*x + y*y);
if(lenght == 0)
{
return;
}
this.x = x / lenght;
this.y = y / lenght;
}
public bool isNull()
{
if(x == 0 && y == 0)
return false;
return true;
}
}
}

29
src/Title.bf Normal file
View file

@ -0,0 +1,29 @@
namespace bounty_game
{
class Title : Hud
{
public static System.String title;
static Texture cText = new Texture() ~ delete(_);
static float ypos = 100;
public override void Draw(float delta)
{
cText.LoadFromString(title,SDL2.SDL.Color(0xFF,0xFF,0xFF,0xFF),SDLManager.LargeFont);
cText.Render(game_width/2 - cText.GetWidth/2,(.) ypos);
ypos -= 0.1f*delta;
}
public static void WaveShowcase(int wave)
{
ypos = 100;
delete title;
title = new System.String("Wave: ");
title.Append(wave.ToString(.. scope .()));
cText.LoadFromString(title,SDL2.SDL.Color(0xFF,0xFF,0xFF,0xFF),SDLManager.LargeFont);
}
public this()
{
title = new System.String("Wave: 1");
}
}
}

146
src/dog.bf Normal file
View file

@ -0,0 +1,146 @@
using System.Collections;
namespace bounty_game
{
class dog : Entity
{
Texture myTexture;
Texture myTexture2;
Texture myTexture3;
Texture speedtxt;
Texture sad;
vec2 mov;
vec2 goal;
float timer = 30;
bool speedac = false;
bool death = false;
public shrooms cshrooms;
public override void Update(float delta)
{
timer += delta/1000;
if(timer > 20)
{
timer -= 20 - System.gRand.Next(0,2);
shrooms next = shrooms();
next.x = System.gRand.Next(150,1100);
next.y = System.gRand.Next(150,600);
next.type = System.gRand.Next(0,3);
cshrooms = next;
}
cshrooms.lifetime = cshrooms.lifetime - delta/1000;
if(cshrooms.lifetime < 0)
{
cshrooms.active = false;
PlayerBoxes.max = 0.6f;
speedac = false;
death = false;
}
float px = PlayerBoxes.Apos.x - cshrooms.x;
float py = PlayerBoxes.Apos.y - cshrooms.y;
if(px*px+py*py < 450 && cshrooms.active)
{
switch(cshrooms.type)
{
case 0:
PlayerBoxes.hp += 100;
break;
case 1:
PlayerBoxes.max = 0.7f;
speedac = true;
break;
case 2:
death = true;
for(int i < Enemier.slimes.Count)
{
float sx = Enemier.slimes[i].pos.x - cshrooms.x;
float sy = Enemier.slimes[i].pos.y - cshrooms.y;
if(System.Math.Sqrt(sx*sx + sy * sy) < 150)
{
SDL2.SDLMixer.PlayChannel(-1,Enemier.death,0);
Enemier.slimes.RemoveAt(i);
KillHud.count++;
}
}
break;
default:
break;
}
cshrooms.active = false;
}
}
public override void Draw()
{
myTexture.SetAlpha((.)(255*(cshrooms.lifetime/10)));
myTexture2.SetAlpha((.)(255*(cshrooms.lifetime/10)));
myTexture3.SetAlpha((.)(255*(cshrooms.lifetime/1)));
speedtxt.SetAlpha((.)(255*(cshrooms.lifetime/10)));
sad.SetAlpha((.)(255*(cshrooms.lifetime/10)));
if(cshrooms.active)
{
if(cshrooms.type == 0)
myTexture.Render((.)cshrooms.x,(.)cshrooms.y);
else if(cshrooms.type == 1)
myTexture2.Render((.)cshrooms.x,(.)cshrooms.y);
else if(cshrooms.type == 2)
myTexture3.Render((.)cshrooms.x,(.)cshrooms.y);
}
if(speedac)
{
speedtxt.Render((.)PlayerBoxes.Apos.x-16,(.)PlayerBoxes.Apos.y-16);
}
else if(death)
{
sad.Render((.)cshrooms.x-150,(.)cshrooms.y-150);
}
}
public override void Destroy()
{
delete myTexture;
delete myTexture2;
delete myTexture3;
delete speedtxt;
delete sad;
}
public override void Init()
{
myTexture = new Texture();
myTexture.LoadFromFile("Assets/dog.png");
myTexture2 = new Texture();
myTexture2.LoadFromFile("Assets/dog2.png");
myTexture3 = new Texture();
myTexture3.LoadFromFile("Assets/dog3.png");
speedtxt = new Texture();
speedtxt.LoadFromFile("Assets/speed.png");
sad = new Texture();
sad.LoadFromFile("Assets/sad.png");
}
}
public struct shrooms
{
public bool active = true;
public float lifetime = 10;
public int type;
/*
0 = hp
1 = speed
2 = destruction
3 = shield
*/
public float x;
public float y;
}
}

29
src/foreground.bf Normal file
View file

@ -0,0 +1,29 @@
namespace bounty_game
{
class foreground : Entity
{
Texture myTexture;
public override void Update(float delta)
{
}
public override void Draw()
{
myTexture.Render(0,0);
}
public override void Destroy()
{
delete myTexture;
}
public override void Init()
{
myTexture = new Texture();
myTexture.LoadFromFile("Assets/fg.png");
}
}
}