Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Player & Weapons Refactor #10

Merged
22 changes: 22 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"files.associations": {
"*.scss": "postcss",
"*.sass": "bat",
"*.dot": "dot",
"*.m": "c",
"atomic": "c",
"*.tcc": "c",
"compare": "c",
"concepts": "c",
"functional": "c",
"memory": "c",
"numeric": "c",
"ostream": "c",
"stdexcept": "c",
"streambuf": "c",
"system_error": "c",
"type_traits": "c",
"typeinfo": "c",
"utility": "c"
}
}
23 changes: 14 additions & 9 deletions src/CRougeLite.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "CRougeLite.h" // NOTE: declare global extern vars

#include "game/player.h"
#include "system/atlas.h"
#include "system/draw.h"
#include "system/input.h"
Expand All @@ -40,7 +41,7 @@ GameState *gameState = NULL;
//========================================================
// Local Functions Headers
//========================================================
static void loadResources(Settings *settings);
static void loadResources();
static void update();
static void clearResources();

Expand All @@ -49,10 +50,12 @@ static void clearResources();
//========================================================
int main(void) {
gameState = initGameState();
initSettings();
initDictionary();
Settings *settings = &(gameState->settings);

InitWindow(settings->screenWidth, settings->screenHeight, "C rougelite game");
// printf("TEST\n");

initAtlas();

loadResources(settings);
Expand All @@ -73,27 +76,29 @@ int main(void) {
return 0;
}

static void loadResources(Settings *settings) {
static void loadResources() {
// load global assets
Settings settings = gameState->settings;
InitAudioDevice();
music = LoadMusicStream("./src/"
"./resources/ambient.ogg");
// NOTE: All paths must start from the src dir

SetMusicVolume(music, settings->musicVolume / 100.0);
SetMusicVolume(music, settings.musicVolume / 100.0);
PlayMusicStream(music);

Player *player = initPlayer(
"Marcus", CAT, P_GUN,
(Vector2){settings->screenWidth / 2.0, settings->screenHeight / 2.0}, 0);
setupPlayers();

initEnemy(E_CIVILIAN, E_SWORD, (Vector2){128, 128});

initEnemy(E_FARMER, E_SWORD,
(Vector2){settings->screenWidth - 128 - 64, 128});
(Vector2){settings.screenWidth - 128 - 64, 128});
}

static void update() { UpdateMusicStream(music); }
static void update() {
updatePlayers();
UpdateMusicStream(music);
}

static void clearResources() {
clearGameState();
Expand Down
16 changes: 5 additions & 11 deletions src/CRougeLite.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,27 @@

#ifndef CROUGELITE_H
#define CROUGELITE_H
#include <raylib.h>
#include "defs.h"
#include "structs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#include "common.h"

//========================================================
// Global Shared Variables
//========================================================
extern Music music;
extern GameState* gameState;
extern GameState *gameState;

//========================================================
// Global Functions
//========================================================
// Init Functions
GameState *initGameState();
void initDictionary();
void initSettings();
Player *initPlayer(const char *name, P_TYPE type, P_WEAPON weapon,Vector2 position, int ID);
Enemy *initEnemy(E_TYPE type, E_WEAPON weapon, Vector2 position);
Bullet *initBullet(int ID, BulletInfo* bulletInfo, Vector2 src, Vector2 dest);
Bullet *initBullet(int ID, BulletInfo *bulletInfo, Vector2 src, Vector2 dest);

// Clear Resources Functions
void clearGameState();
void clearPlayer(Player **player);
void clearEnemy(Enemy **enemy);

#endif // CROUGELITE_H
Expand Down
15 changes: 15 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,19 @@
*
*
**************************************************************/
#ifndef COMMON_H
#define COMMON_H

#include <raylib.h>
#include <raymath.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#include "defs.h"
#include "structs.h"



#endif // COMMON_H
2 changes: 1 addition & 1 deletion src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#define DEFAULT_MAX_ENEMIES 100
#define DEFAULT_MAX_COMBAT_ACTIONS 100

#define PLAYER_SPEED 5
#define PLAYER_SPEED 10

#define MAX_FILENAME_LENGTH 256

Expand Down
218 changes: 218 additions & 0 deletions src/game/player.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/***************************************************************
*
*
* ██████╗ ██╗ █████╗ ██╗ ██╗███████╗██████╗
* ██╔══██╗██║ ██╔══██╗╚██╗ ██╔╝██╔════╝██╔══██╗
* ██████╔╝██║ ███████║ ╚████╔╝ █████╗ ██████╔╝
* ██╔═══╝ ██║ ██╔══██║ ╚██╔╝ ██╔══╝ ██╔══██╗
* ██║ ███████╗██║ ██║ ██║ ███████╗██║ ██║
* ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
*
* Player Module Unit. (Game Object)
* Exposes the logic for the player object.
*
* - Setup Player
* - Update Player
* - Draw Player
* - Clear Player
*
**************************************************************/

#include "player.h"

#include "../system/anime.h"
// FIXME: delete me later
#include "../system/init.h"
#include <raymath.h>

// ***************************
// Private Function Prototypes
// ***************************
static Player *initPlayer(const char *name, P_TYPE type, P_WEAPON weapon,
Vector2 position, int ID);
static void clearPlayer(Player **player);

/* setupPlayers
*
* Setup the players in the game. Create a new player and adds it to
* the state of the game to draw and update.
*
*/
void setupPlayers() {
Player *player = initPlayer("Marcus", CAT, P_GUN,
(Vector2){gameState->settings.screenWidth / 2.0,
gameState->settings.screenHeight / 2.0},
0);
}

/* drawPlayers
*
* Draw the players in the game.
*
*/
void drawPlayers() {
Player *players = gameState->players;
int player_num = gameState->numOfPlayers;

// FIXME: This is a temporary solution
// Move this animation into the animator object
// And setup them up at the setup of the player.
SpriteAnimation idle = createSpriteAnimation(6,
(char *[]){
"Meow-Knight_Idle_0_0",
"Meow-Knight_Idle_1_0",
"Meow-Knight_Idle_2_0",
"Meow-Knight_Idle_3_0",
"Meow-Knight_Idle_4_0",
"Meow-Knight_Idle_5_0",
},
6, true);

SpriteAnimation walk = createSpriteAnimation(8,
(char *[]){
"Meow-Knight_Run_0_0",
"Meow-Knight_Run_1_0",
"Meow-Knight_Run_2_0",
"Meow-Knight_Run_3_0",
"Meow-Knight_Run_4_0",
"Meow-Knight_Run_5_0",
"Meow-Knight_Run_6_0",
"Meow-Knight_Run_7_0",
},
12, true);


while (player_num--) {
Vector2 pos = players->object.transform.position;
bool flip = (players->drawDirection == -1) ? true : false;
if (players->isMoving) {
drawSpriteAnimationPro(&walk, (Rectangle){pos.x, pos.y, 64, 64},
(Vector2){0, 0}, 0, WHITE, flip);
} else {
drawSpriteAnimationPro(&idle, (Rectangle){pos.x, pos.y, 64, 64},
(Vector2){0, 0}, 0, WHITE, flip);
}

players++;
}

disposeSpriteAnimation(&idle);
disposeSpriteAnimation(&walk);
}

/* updatePlayers
*
* Update the players in the game.
* it handles it's input and state too.
*
*/
void updatePlayers() {
Player *player = gameState->players;
Input input = player->input;
double speed = player->stats.speed;

Vector2 direction = {0, 0};
if (IsKeyDown(input.up))
direction.y -= 1;
if (IsKeyDown(input.down))
direction.y += 1;
if (IsKeyDown(input.left))
direction.x -= 1;
if (IsKeyDown(input.right))
direction.x += 1;

Vector2 velocity =
Vector2Scale(Vector2Normalize(direction), speed);

Vector2 position = Vector2Add(
player->object.transform.position, velocity);

if (Vector2Length(velocity) > 0) {
player->isMoving = true;
} else {
player->isMoving = false;
}

if (velocity.x < 0) {
player->drawDirection = -1;
} else {
player->drawDirection = 1;
}

// NOTE: this makes the player unable to go out of frame
player->object.rigidBody.velocity = velocity;
player->object.transform.position =
Vector2Clamp(position, (Vector2){0, 0},
(Vector2){gameState->settings.screenWidth - 64,
gameState->settings.screenHeight - 64});
// FIXME: replace with sprite size
}

void clearPlayers() {
int player_num = gameState->numOfPlayers;
Player *players = gameState->players;

while (player_num--) {
printf("Deleting Player: %s\n", players->name);
clearPlayer(&players);
players++;
}
}

// *****************
// PRIVATE FUNCTIONS
// *****************

static void addPlayer(Player *player) {
Player *players = gameState->players;
players[gameState->numOfPlayers++] = *player;
}

static Player *initPlayer(const char *name, P_TYPE type, P_WEAPON weapon,
Vector2 position, int ID) {
Settings settings = gameState->settings;
Dictionary *dict = gameState->characterDictionary;
Player *player = &(gameState->players[gameState->numOfPlayers++]);
int l = 0, r = NUM_OF_E_TYPE - 1;

while (l <= r) {
int mid = l + (r - l) / 2;
int cmp = dict[mid].opcode - type;
if (!cmp) {
*player = dict[mid].entry.player;
break;
}
if (cmp < 0)
l = mid + 1;
else
r = mid - 1;
}
printf("Adding Player #%d\n", ID);
player->name = strdup(name);
player->ID = ID;
player->type = type;
Weapon selectedWeapon = initWeapon(weapon, true);
player->inventory = initInventory();
player->inventory.weapons[player->inventory.currentNumOfWeapons++] = selectedWeapon;
player->object.transform.position = position;
player->score = 0;
player->drawDirection = 1;
player->direction = RIGHT;
player->fire = 0;
player->ID = ID;
player->experience = (Experience){.xp = 0, .level = 0};
// TODO: Make dictionary for infos related to each type of character.
// Input
player->input = (Input){.up = KEY_W, .down = KEY_S, .left = KEY_A, .right = KEY_D, .action = KEY_E };

return player;
}

static void clearPlayer(Player **player) {
if (player == NULL || *player == NULL)
return;

free((*player)->name);
free(*player);
*player = NULL;
}
Loading