Avoid/src/Main.c

338 lines
9.7 KiB
C
Raw Normal View History

/*
2022-05-29 16:02:30 +00:00
- Avoid ~ a game by Canneddonuts
- Filename ~ Main.c
- Author ~ Return0ne
- 2022
- *no license*
*/
2022-05-29 16:02:30 +00:00
#include "../include/raylib.h"
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
2022-03-27 20:40:15 +00:00
// screen variables
static const int screenWidth = 800;
static const int screenHeight = 450;
// Gamescreens
typedef enum GameScreen { TITLE = 0, GAMEPLAY, GAMEOVER, CREDITS } GameScreen;
// structs
typedef struct Ball {
Vector2 position;
Vector2 speed;
float radius;
float growth;
2022-03-27 20:40:15 +00:00
Color color;
bool active;
} Ball;
typedef struct Player {
2022-04-10 16:17:41 +00:00
Texture2D sprite;
2022-05-29 16:02:30 +00:00
float speed;
int hp;
2022-04-10 16:17:41 +00:00
int currentframe;
Vector2 sprite_pos;
Rectangle frameRec;
2022-03-27 20:40:15 +00:00
Rectangle hitbox;
} Player;
// Game variables
static int pauseTimer;
static int score, bestscore;
static int titleSelected = 0, gameoverSelected = 0;
2022-03-27 20:40:15 +00:00
static GameScreen currentScreen = { 0 };
static Sound fxbounce = { 0 };
static Player player = { 0 };
static Ball ball = { 0 };
static bool pause;
static bool mute;
2022-05-30 16:16:22 +00:00
static bool DebugMode;
2022-03-27 20:40:15 +00:00
// Game functions
static void gameSetup(void);
static void updateGame(void);
static void drawGame(void);
static void gameReset(void);
static void gameLoop(void);
static void unloadGame(void);
2022-03-27 20:40:15 +00:00
int main(void)
{
InitWindow(screenWidth, screenHeight, "Avoid");
InitAudioDevice();
gameSetup();
2022-03-27 20:40:15 +00:00
#if defined(PLATFORM_WEB)
2022-05-19 00:31:20 +00:00
emscripten_set_main_loop(gameLoop, 60, 1);
#else
SetTargetFPS(60);
while (!WindowShouldClose()) gameLoop();
#endif
2022-03-27 20:40:15 +00:00
unloadGame();
2022-03-27 20:40:15 +00:00
CloseWindow();
return 0;
2022-03-27 20:40:15 +00:00
}
void gameSetup(void)
2022-03-27 20:40:15 +00:00
{
// asset loading & setting of variable values
2022-03-27 20:40:15 +00:00
currentScreen = TITLE;
fxbounce = LoadSound("assets/sfx/boing.wav");
SetMasterVolume(0.2);
2022-04-10 16:17:41 +00:00
player.sprite = LoadTexture("assets/gfx/player.png");
player.currentframe = 0;
2022-05-29 16:02:30 +00:00
player.speed = 300.0f;
2022-03-27 20:40:15 +00:00
player.hp = 30;
2022-04-10 16:17:41 +00:00
player.frameRec = (Rectangle) {
0.0f,
0.0f,
2022-05-29 16:02:30 +00:00
(float) player.sprite.width/3,
2022-04-10 16:17:41 +00:00
(float) player.sprite.height
};
2022-03-27 20:40:15 +00:00
player.hitbox = (Rectangle) {
GetScreenWidth()/2.0f - 30,
GetScreenHeight()/2.0f - 30,
2022-04-10 16:17:41 +00:00
70,
70
2022-03-27 20:40:15 +00:00
};
ball.position = (Vector2){ 50, 50 };
2022-05-19 00:31:20 +00:00
ball.speed = (Vector2){ 400.0f, 300.0f };
2022-03-27 20:40:15 +00:00
ball.radius = 20;
ball.growth = 2;
2022-03-27 20:40:15 +00:00
ball.color = MAROON;
ball.active = true;
pause = 0;
mute = 0;
2022-05-30 16:16:22 +00:00
DebugMode = 0;
2022-03-27 20:40:15 +00:00
pauseTimer = 0;
2022-05-04 00:17:40 +00:00
score = 0;
2022-03-27 20:40:15 +00:00
}
void updateGame(void)
2022-03-27 20:40:15 +00:00
{
// code that runs as long as the program is running
if ((IsKeyDown(KEY_LEFT_ALT)) && (IsKeyPressed(KEY_F))) ToggleFullscreen();
2022-03-27 20:40:15 +00:00
switch(currentScreen) {
case TITLE:
if (IsKeyPressed(KEY_UP)) titleSelected++;
if (IsKeyPressed(KEY_DOWN)) titleSelected--;
if (titleSelected > 0) titleSelected--;
if (titleSelected < -2) titleSelected++;
if ((titleSelected == 0) && (IsKeyPressed(KEY_ENTER))) currentScreen = GAMEPLAY;
if ((titleSelected == -1) && (IsKeyPressed(KEY_ENTER))) currentScreen = CREDITS;
if ((titleSelected == -2) && (IsKeyPressed(KEY_ENTER))) OpenURL("https://canneddonuts.itch.io/");
2022-03-27 20:40:15 +00:00
break;
case GAMEPLAY:
if (IsKeyPressed(KEY_M)) mute = !mute;
2022-03-27 20:40:15 +00:00
if (IsKeyPressed(KEY_ENTER)) pause = !pause;
2022-03-27 20:40:15 +00:00
if (!pause) {
// Controls
2022-05-29 16:02:30 +00:00
if (IsKeyDown(KEY_LEFT)) player.hitbox.x -= GetFrameTime() * player.speed;
if (IsKeyDown(KEY_RIGHT)) player.hitbox.x += GetFrameTime() * player.speed;
if (IsKeyDown(KEY_UP)) player.hitbox.y -= GetFrameTime() * player.speed;
if (IsKeyDown(KEY_DOWN)) player.hitbox.y += GetFrameTime() * player.speed;
if (IsKeyDown(KEY_X)) {
// player.speed *= 2;
player.speed = 600.0f;
if (player.currentframe != 1) player.currentframe = 2;
} else player.speed = 300.0f;
2022-03-27 20:40:15 +00:00
2022-04-10 16:17:41 +00:00
player.sprite_pos = (Vector2){ player.hitbox.x, player.hitbox.y };
2022-05-29 16:02:30 +00:00
player.frameRec.x = (float)player.currentframe*(float)player.sprite.width/3;
2022-04-10 16:17:41 +00:00
2022-03-27 20:40:15 +00:00
// Player to da wallz collies
if ((player.hitbox.x + player.hitbox.width) >= GetScreenWidth()) player.hitbox.x = GetScreenWidth() - player.hitbox.width;
else if (player.hitbox.x <= 0) player.hitbox.x = 0;
if ((player.hitbox.y + player.hitbox.height) >= GetScreenHeight()) player.hitbox.y = GetScreenHeight() - player.hitbox.height;
else if (player.hitbox.y <= 0) player.hitbox.y = 0;
2022-05-30 16:16:22 +00:00
if (IsKeyPressed(KEY_B)) ball.active = !ball.active;
2022-05-30 16:16:22 +00:00
if (IsKeyPressed(KEY_D)) DebugMode = !DebugMode;
2022-05-04 00:17:40 +00:00
if (IsKeyPressed(KEY_R)) {
gameReset();
currentScreen = TITLE;
}
if (player.hp <= 0) {
gameReset();
currentScreen = GAMEOVER;
}
2022-03-27 20:40:15 +00:00
if (ball.active) {
2022-05-04 00:17:40 +00:00
score++;
2022-05-29 16:02:30 +00:00
// movement of the ball
2022-05-19 00:31:20 +00:00
ball.position.x += GetFrameTime() * ball.speed.x;
ball.position.y += GetFrameTime() * ball.speed.y;
2022-03-27 20:40:15 +00:00
2022-05-04 00:17:40 +00:00
if (score >= bestscore) bestscore = score;
2022-03-27 20:40:15 +00:00
// Ballz to da wallz collies
if ((ball.position.x >= (GetScreenWidth() - ball.radius)) || (ball.position.x <= ball.radius)) {
ball.speed.x *= -1.0f;
if (!mute) PlaySoundMulti(fxbounce);
}
if ((ball.position.y >= (GetScreenHeight() - ball.radius)) || (ball.position.y <= ball.radius)) {
ball.speed.y *= -1.0f;
if (!mute) PlaySoundMulti(fxbounce);
}
2022-03-27 20:40:15 +00:00
if (CheckCollisionCircleRec(ball.position, ball.radius, player.hitbox)) {
player.hp -= GetFrameTime() * 3.0f;
player.currentframe = 1;
} else player.currentframe = 0;
2022-03-27 20:40:15 +00:00
2022-04-10 16:17:41 +00:00
if (ball.radius <= 100) ball.radius += GetFrameTime() * ball.growth;
2022-03-27 20:40:15 +00:00
}
}
else pauseTimer++;
break;
case GAMEOVER:
if (IsKeyPressed(KEY_UP)) gameoverSelected++;
if (IsKeyPressed(KEY_DOWN)) gameoverSelected--;
if (gameoverSelected > 0) gameoverSelected--;
if (gameoverSelected < -1) gameoverSelected++;
if ((gameoverSelected == 0) && (IsKeyPressed(KEY_ENTER)))
2022-03-27 20:40:15 +00:00
currentScreen = GAMEPLAY;
if ((gameoverSelected == -1) && (IsKeyPressed(KEY_ENTER)))
currentScreen = TITLE;
2022-03-27 20:40:15 +00:00
break;
case CREDITS:
if (IsKeyPressed(KEY_ENTER)) currentScreen = TITLE;
default: break;
}
}
void drawGame(void)
2022-03-27 20:40:15 +00:00
{
// code to render the game to the game window
2022-03-27 20:40:15 +00:00
BeginDrawing();
ClearBackground(RAYWHITE);
switch(currentScreen) {
case TITLE:
DrawRectangle(0, 0, screenWidth, screenHeight, ORANGE);
DrawText("Controls", 10, 10, 30, PURPLE);
2022-05-04 00:17:40 +00:00
DrawText(TextFormat("BEST: %i", bestscore), 600, 0, 30, WHITE);
2022-05-29 16:02:30 +00:00
DrawText("Press the arrow keys to move and 'X' to dash", 10, 40, 10, RED);
DrawText("Press 'ENTER' to pause", 10, 60, 10, RED);
2022-03-27 20:40:15 +00:00
DrawText("Press 'M' to mute", 10, 80, 10, RED);
DrawText("Press 'Left-ALT' + 'F' for full screen", 10, 100, 10, RED);
2022-03-27 20:40:15 +00:00
DrawText("Press 'R' to restart", 10, 120, 10, RED);
DrawText("Press 'ENTER' to select an option", 10, 140, 10, RED);
DrawText("Avoid", 330, 20, 50, BLUE);
if (titleSelected == 0) DrawText("PLAY", 360, 220, 20, WHITE);
2022-03-27 20:40:15 +00:00
else DrawText("PLAY", 360, 220, 20, BLUE);
if (titleSelected == -1) DrawText("CREDITS", 340, 240, 20, WHITE);
2022-03-27 20:40:15 +00:00
else DrawText("CREDITS", 340, 240, 20, BLUE);
2022-03-27 20:58:24 +00:00
if (titleSelected == -2) DrawText("MORE GAMES", 320, 260, 20, WHITE);
else DrawText("MORE GAMES", 320, 260, 20, BLUE);
2022-03-27 20:40:15 +00:00
break;
case GAMEPLAY:
DrawRectangle(0, 0, screenWidth, screenHeight, BLACK);
DrawFPS(10, 430);
DrawText(TextFormat("HP: %i", player.hp), 10, 10, 20, RED);
2022-05-04 00:17:40 +00:00
DrawText(TextFormat("SCORE: %i", score), 10, 30, 20, BLUE);
2022-05-30 16:16:22 +00:00
if (DebugMode) {
DrawText(TextFormat("BALL SIZE: %f", ball.radius), 10, 50, 20, GREEN);
DrawText(TextFormat("BALL POS X: %f, BALL POS Y: %f", ball.position.x, ball.position.y), 10, 70, 20, GREEN);
DrawText(TextFormat("BALL SPEED X: %f, BALL SPEED Y: %f", ball.speed.x, ball.speed.y), 10, 90, 20, GREEN);
DrawRectangleRec(player.hitbox, BLUE);
}
2022-03-27 20:40:15 +00:00
if (ball.active) DrawCircleV(ball.position, (float)ball.radius, ball.color);
2022-04-10 16:17:41 +00:00
DrawTextureRec(player.sprite, player.frameRec, player.sprite_pos, WHITE);
2022-03-27 20:40:15 +00:00
if (pause && ((pauseTimer/30)%2)) DrawText("PAUSED", 330, 190, 30, PURPLE);
break;
case GAMEOVER:
DrawRectangle(0, 0, screenWidth, screenHeight, BLUE);
DrawText("GAMEOVER", 250, 20, 50, RED);
if (gameoverSelected == 0) DrawText("RETRY", 350, 200, 20, WHITE);
else DrawText("RETRY", 350, 200, 20, RED);
if (gameoverSelected == -1) DrawText("TITLE", 352, 230, 20, WHITE);
else DrawText("TITLE", 352, 230, 20, RED);
2022-03-27 20:40:15 +00:00
break;
case CREDITS:
DrawRectangle(0, 0, screenWidth, screenHeight, GREEN);
DrawText("Avoid", 330, 20, 50, MAGENTA);
DrawText("Programming and Art by Return0ne", 10, 210, 20, BLUE);
DrawText("Powered by raylib 4.0", 10, 240, 20, BLUE);
DrawText("A Canneddonuts project 2022", 10, 270, 40, RED);
2022-03-27 20:40:15 +00:00
DrawText("Press 'ENTER' ", 10, 350, 20, WHITE);
break;
default: break;
}
EndDrawing();
}
void gameReset(void)
{
// code to reset all variables without reloading assets
player.currentframe = 0;
2022-05-29 16:02:30 +00:00
player.speed = 300.0f;
player.hp = 30;
player.hitbox = (Rectangle) {
GetScreenWidth()/2.0f - 30,
GetScreenHeight()/2.0f - 30,
70,
70
};
ball.position = (Vector2){ 50, 50 };
ball.radius = 20;
ball.active = true;
2022-05-30 16:16:22 +00:00
DebugMode = 0;
pauseTimer = 0;
2022-05-04 00:17:40 +00:00
score = 0;
gameoverSelected = 0;
}
2022-03-27 20:40:15 +00:00
void gameLoop(void)
2022-03-27 20:40:15 +00:00
{
updateGame();
drawGame();
2022-03-27 20:40:15 +00:00
}
void unloadGame(void)
2022-03-27 20:40:15 +00:00
{
UnloadSound(fxbounce);
2022-04-10 16:17:41 +00:00
UnloadTexture(player.sprite);
2022-03-27 20:40:15 +00:00
}