Compare commits
No commits in common. "6182a2db85ba210f4c91e90ffe4449733f7b08aa" and "ac3b277d05a9ef6c9413380a884a1f61a3727d11" have entirely different histories.
6182a2db85
...
ac3b277d05
4
main.c
4
main.c
@ -22,7 +22,7 @@ int main() {
|
|||||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
|
||||||
Player player = {0};
|
Player player = {0};
|
||||||
player_init(&player, renderer, (SDL_Rect){ .x = 50, .y = 600, .w = 100, .h = 64 });
|
player_init(&player, renderer, (SDL_Rect){ .x = 50, .y = 100, .w = 100, .h = 64 });
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
|
||||||
@ -31,6 +31,8 @@ int main() {
|
|||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
|
player_events(&player, &event);
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
running = false;
|
running = false;
|
||||||
|
196
player.c
196
player.c
@ -1,45 +1,21 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "SDL_keycode.h"
|
||||||
|
#include "SDL_render.h"
|
||||||
#include "animation_player.h"
|
#include "animation_player.h"
|
||||||
#include "state_machine.h"
|
#include "state_machine.h"
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <SDL2/SDL_keyboard.h>
|
|
||||||
#include <SDL2/SDL_scancode.h>
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define SPRITE_WIDTH 100
|
#define SPRITE_WIDTH 100
|
||||||
#define SPRITE_HEIGHT 64
|
#define SPRITE_HEIGHT 64
|
||||||
|
|
||||||
void print_state (Player *player) {
|
State *update_state(Player *player, uint32_t state);
|
||||||
switch(player->current_state) {
|
State *idle_state(StateMachine *sm, Player *player);
|
||||||
case PLAYER_STATE_IDLE:
|
State *walk_state(StateMachine *sm, Player *player);
|
||||||
printf("IDLE\n");
|
State *dash_state(StateMachine *sm, Player *player);
|
||||||
break;
|
|
||||||
case PLAYER_STATE_WALK:
|
|
||||||
printf("WALK\n");
|
|
||||||
break;
|
|
||||||
case PLAYER_STATE_DASH:
|
|
||||||
printf("DASH\n");
|
|
||||||
break;
|
|
||||||
case PLAYER_STATE_JUMP:
|
|
||||||
printf("JUMP\n");
|
|
||||||
break;
|
|
||||||
case PLAYER_STATE_FALL:
|
|
||||||
printf("FALL\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void get_player_controls(Player *player);
|
|
||||||
State *update_state (Player *player, uint32_t state);
|
|
||||||
State *idle_state (StateMachine *sm, Player *player);
|
|
||||||
State *walk_state (StateMachine *sm, Player *player);
|
|
||||||
State *dash_state (StateMachine *sm, Player *player);
|
|
||||||
State *jump_state (StateMachine *sm, Player *player);
|
|
||||||
State *fall_state (StateMachine *sm, Player *player);
|
|
||||||
|
|
||||||
void player_init(Player *player, SDL_Renderer *renderer, SDL_Rect position) {
|
void player_init(Player *player, SDL_Renderer *renderer, SDL_Rect position) {
|
||||||
player->base_y = position.y;
|
|
||||||
player->position = position;
|
player->position = position;
|
||||||
player->movement = (Movement){0};
|
player->movement = (Movement){0};
|
||||||
player->x_direction = PLAYER_DIRECTION_RIGHT;
|
player->x_direction = PLAYER_DIRECTION_RIGHT;
|
||||||
@ -51,42 +27,27 @@ void player_init(Player *player, SDL_Renderer *renderer, SDL_Rect position) {
|
|||||||
ap_init(renderer, "knight_player/Walking_KG_2.png", 125, SPRITE_WIDTH, SPRITE_HEIGHT, true);
|
ap_init(renderer, "knight_player/Walking_KG_2.png", 125, SPRITE_WIDTH, SPRITE_HEIGHT, true);
|
||||||
player->animations[PLAYER_STATE_DASH] =
|
player->animations[PLAYER_STATE_DASH] =
|
||||||
ap_init(renderer, "knight_player/Dashing_KG_1.png", 125, SPRITE_WIDTH, SPRITE_HEIGHT, false);
|
ap_init(renderer, "knight_player/Dashing_KG_1.png", 125, SPRITE_WIDTH, SPRITE_HEIGHT, false);
|
||||||
player->animations[PLAYER_STATE_JUMP] =
|
|
||||||
ap_init(renderer, "knight_player/Jump_KG_2.png", 100, SPRITE_WIDTH, SPRITE_HEIGHT, false);
|
|
||||||
player->animations[PLAYER_STATE_FALL] =
|
|
||||||
ap_init(renderer, "knight_player/Fall_KG_2.png", 80, SPRITE_WIDTH, SPRITE_HEIGHT, false);
|
|
||||||
|
|
||||||
player->states[PLAYER_STATE_IDLE] = (State){ .state_func = (StateFunc *)idle_state };
|
player->states[PLAYER_STATE_IDLE] = (State){ .state_func = (StateFunc *)idle_state };
|
||||||
player->states[PLAYER_STATE_WALK] = (State){ .state_func = (StateFunc *)walk_state };
|
player->states[PLAYER_STATE_WALK] = (State){ .state_func = (StateFunc *)walk_state };
|
||||||
player->states[PLAYER_STATE_DASH] = (State){ .state_func = (StateFunc *)dash_state };
|
player->states[PLAYER_STATE_DASH] = (State){ .state_func = (StateFunc *)dash_state };
|
||||||
player->states[PLAYER_STATE_JUMP] = (State){ .state_func = (StateFunc *)jump_state };
|
|
||||||
player->states[PLAYER_STATE_FALL] = (State){ .state_func = (StateFunc *)fall_state };
|
|
||||||
|
|
||||||
|
player->event_data = (PlayerEventData){0};
|
||||||
player->state_machine = (StateMachine){ .current_state = &(player->states[PLAYER_STATE_IDLE]) };
|
player->state_machine = (StateMachine){ .current_state = &(player->states[PLAYER_STATE_IDLE]) };
|
||||||
player->current_state = PLAYER_STATE_IDLE;
|
player->current_state = PLAYER_STATE_IDLE;
|
||||||
player->controls = (PlayerControl){0};
|
}
|
||||||
|
|
||||||
|
void player_events(Player *player, const SDL_Event *event) {
|
||||||
|
if (!player || !event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->event_data.event = event;
|
||||||
|
sm_run(&(player->state_machine), (void *)player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_update(Player *player, uint32_t ticks) {
|
void player_update(Player *player, uint32_t ticks) {
|
||||||
get_player_controls(player);
|
|
||||||
|
|
||||||
if (player->controls.walk_left) {
|
|
||||||
player->movement.x = PLAYER_DIRECTION_LEFT * player->velocity;
|
|
||||||
player->x_direction = PLAYER_DIRECTION_LEFT;
|
|
||||||
} else if (player->controls.walk_right) {
|
|
||||||
player->movement.x = PLAYER_DIRECTION_RIGHT * player->velocity;
|
|
||||||
player->x_direction = PLAYER_DIRECTION_RIGHT;
|
|
||||||
} else if (!(player->controls.walk_left) && !(player->controls.walk_right)) {
|
|
||||||
player->movement.x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sm_run(&(player->state_machine), (void *)player);
|
|
||||||
|
|
||||||
player->position.x += player->movement.x;
|
player->position.x += player->movement.x;
|
||||||
player->position.y += player->movement.y;
|
|
||||||
if (player->position.y > player->base_y) {
|
|
||||||
player->position.y = player->base_y;
|
|
||||||
}
|
|
||||||
ap_update(&(player->animations[player->current_state]), ticks);
|
ap_update(&(player->animations[player->current_state]), ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,21 +55,6 @@ void player_draw(const Player *player, SDL_Renderer *renderer) {
|
|||||||
ap_draw(renderer, &(player->animations[player->current_state]), &(player->position), player->x_direction == PLAYER_DIRECTION_LEFT);
|
ap_draw(renderer, &(player->animations[player->current_state]), &(player->position), player->x_direction == PLAYER_DIRECTION_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_player_controls(Player *player) {
|
|
||||||
const uint8_t *keys = SDL_GetKeyboardState(NULL);
|
|
||||||
|
|
||||||
player->controls.walk_left = keys[SDL_SCANCODE_LEFT] == SDL_PRESSED;
|
|
||||||
player->controls.walk_right = keys[SDL_SCANCODE_RIGHT] == SDL_PRESSED;
|
|
||||||
|
|
||||||
player->controls.space_last = player->controls.space_pressed;
|
|
||||||
player->controls.space_pressed = keys[SDL_SCANCODE_SPACE] == SDL_PRESSED;
|
|
||||||
player->controls.jump = player->controls.space_last && !(player->controls.space_pressed);
|
|
||||||
|
|
||||||
player->controls.lctrl_last = player->controls.lctrl_pressed;
|
|
||||||
player->controls.lctrl_pressed = keys[SDL_SCANCODE_LCTRL] == SDL_PRESSED;
|
|
||||||
player->controls.dash = player->controls.lctrl_last && !(player->controls.lctrl_pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
State *update_state(Player *player, uint32_t state) {
|
State *update_state(Player *player, uint32_t state) {
|
||||||
if (state >= COUNT_PLAYER_STATES) {
|
if (state >= COUNT_PLAYER_STATES) {
|
||||||
return &(player->states[player->current_state]);
|
return &(player->states[player->current_state]);
|
||||||
@ -119,34 +65,50 @@ State *update_state(Player *player, uint32_t state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
State *idle_state(StateMachine *sm, Player *player) {
|
State *idle_state(StateMachine *sm, Player *player) {
|
||||||
uint32_t state = PLAYER_STATE_IDLE;
|
const SDL_Event *event = player->event_data.event;
|
||||||
|
uint32_t state = PLAYER_STATE_IDLE;
|
||||||
|
|
||||||
if (player->controls.jump) {
|
switch (event->type) {
|
||||||
player->movement.y = player->velocity * 6 * -1;
|
case SDL_KEYDOWN:
|
||||||
state = PLAYER_STATE_JUMP;
|
switch (event->key.keysym.sym) {
|
||||||
} else if (player->controls.walk_left) {
|
case SDLK_LEFT:
|
||||||
state = PLAYER_STATE_WALK;
|
player->movement.x = PLAYER_DIRECTION_LEFT * player->velocity;
|
||||||
} else if (player->controls.walk_right) {
|
player->x_direction = PLAYER_DIRECTION_LEFT;
|
||||||
state = PLAYER_STATE_WALK;
|
state = PLAYER_STATE_WALK;
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
player->movement.x = PLAYER_DIRECTION_RIGHT * player->velocity;
|
||||||
|
player->x_direction = PLAYER_DIRECTION_RIGHT;
|
||||||
|
state = PLAYER_STATE_WALK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return update_state(player, state);
|
return update_state(player, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
State *walk_state(StateMachine *sm, Player *player) {
|
State *walk_state(StateMachine *sm, Player *player) {
|
||||||
|
const SDL_Event *event = player->event_data.event;
|
||||||
uint32_t state = PLAYER_STATE_WALK;
|
uint32_t state = PLAYER_STATE_WALK;
|
||||||
|
|
||||||
if (player->controls.jump) {
|
switch (event->type) {
|
||||||
player->movement.y = player->velocity * 6 * -1;
|
case SDL_KEYUP:
|
||||||
state = PLAYER_STATE_JUMP;
|
switch (event->key.keysym.sym) {
|
||||||
} else if (player->controls.dash) {
|
case SDLK_LCTRL:
|
||||||
player->controls.dash_in_air = false;
|
player->movement.x = player->x_direction * player->velocity * 3;
|
||||||
player->movement.x = player->x_direction * player->velocity * 2;
|
state = PLAYER_STATE_DASH;
|
||||||
state = PLAYER_STATE_DASH;
|
break;
|
||||||
}
|
case SDLK_LEFT:
|
||||||
|
player->movement.x = 0;
|
||||||
if (!(player->controls.walk_left) && !(player->controls.walk_right)) {
|
state = PLAYER_STATE_IDLE;
|
||||||
state = PLAYER_STATE_IDLE;
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
player->movement.x = 0;
|
||||||
|
state = PLAYER_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return update_state(player, state);
|
return update_state(player, state);
|
||||||
@ -156,18 +118,12 @@ State *dash_state(StateMachine *sm, Player *player) {
|
|||||||
bool reset = false;
|
bool reset = false;
|
||||||
uint32_t state = PLAYER_STATE_DASH;
|
uint32_t state = PLAYER_STATE_DASH;
|
||||||
|
|
||||||
player->movement.x += player->x_direction * 20;
|
player->movement.x += player->x_direction * 3;
|
||||||
|
|
||||||
if (player->animations[PLAYER_STATE_DASH].finished) {
|
if (player->animations[PLAYER_STATE_DASH].finished) {
|
||||||
if (player->controls.dash_in_air) {
|
player->movement.x = 0;
|
||||||
player->movement.y = player->velocity * 6;
|
reset = true;
|
||||||
state = PLAYER_STATE_FALL;
|
state = PLAYER_STATE_IDLE;
|
||||||
} else {
|
|
||||||
player->movement.x = 0;
|
|
||||||
state = PLAYER_STATE_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
@ -176,45 +132,3 @@ State *dash_state(StateMachine *sm, Player *player) {
|
|||||||
|
|
||||||
return update_state(player, state);
|
return update_state(player, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
State *jump_state(StateMachine *sm, Player *player) {
|
|
||||||
bool reset = false;
|
|
||||||
uint32_t state = PLAYER_STATE_JUMP;
|
|
||||||
|
|
||||||
player->movement.y += player->velocity * 0.5;
|
|
||||||
|
|
||||||
if (player->controls.dash) {
|
|
||||||
player->controls.dash_in_air = true;
|
|
||||||
player->movement.x = player->x_direction * player->velocity * 2;
|
|
||||||
player->movement.y = player->velocity * 0.5;
|
|
||||||
reset = true;
|
|
||||||
state = PLAYER_STATE_DASH;
|
|
||||||
} else if (player->animations[PLAYER_STATE_JUMP].finished) {
|
|
||||||
player->movement.y = player->velocity * 6;
|
|
||||||
reset = true;
|
|
||||||
state = PLAYER_STATE_FALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reset) {
|
|
||||||
ap_reset(&(player->animations[PLAYER_STATE_JUMP]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return update_state(player, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
State *fall_state(StateMachine *sm, Player *player) {
|
|
||||||
bool reset = false;
|
|
||||||
uint32_t state = PLAYER_STATE_FALL;
|
|
||||||
|
|
||||||
if (player->animations[PLAYER_STATE_FALL].finished) {
|
|
||||||
player->movement.y = 0;
|
|
||||||
reset = true;
|
|
||||||
state = PLAYER_STATE_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reset) {
|
|
||||||
ap_reset(&(player->animations[PLAYER_STATE_FALL]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return update_state(player, state);
|
|
||||||
}
|
|
||||||
|
19
player.h
19
player.h
@ -12,8 +12,6 @@ enum player_states {
|
|||||||
PLAYER_STATE_IDLE,
|
PLAYER_STATE_IDLE,
|
||||||
PLAYER_STATE_WALK,
|
PLAYER_STATE_WALK,
|
||||||
PLAYER_STATE_DASH,
|
PLAYER_STATE_DASH,
|
||||||
PLAYER_STATE_JUMP,
|
|
||||||
PLAYER_STATE_FALL,
|
|
||||||
|
|
||||||
COUNT_PLAYER_STATES,
|
COUNT_PLAYER_STATES,
|
||||||
};
|
};
|
||||||
@ -25,17 +23,9 @@ enum player_direction {
|
|||||||
PLAYER_DIRECTION_DOWN = 1,
|
PLAYER_DIRECTION_DOWN = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct player_control PlayerControl;
|
typedef struct player_event_data PlayerEventData;
|
||||||
struct player_control {
|
struct player_event_data {
|
||||||
bool walk_left;
|
const SDL_Event *event;
|
||||||
bool walk_right;
|
|
||||||
bool space_last;
|
|
||||||
bool space_pressed;
|
|
||||||
bool jump;
|
|
||||||
bool lctrl_last;
|
|
||||||
bool lctrl_pressed;
|
|
||||||
bool dash;
|
|
||||||
bool dash_in_air;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct movement Movement;
|
typedef struct movement Movement;
|
||||||
@ -48,14 +38,13 @@ typedef struct player Player;
|
|||||||
struct player {
|
struct player {
|
||||||
uint32_t current_state;
|
uint32_t current_state;
|
||||||
uint32_t velocity;
|
uint32_t velocity;
|
||||||
int32_t base_y;
|
|
||||||
int32_t x_direction;
|
int32_t x_direction;
|
||||||
Movement movement;
|
Movement movement;
|
||||||
SDL_Rect position;
|
SDL_Rect position;
|
||||||
|
PlayerEventData event_data;
|
||||||
StateMachine state_machine;
|
StateMachine state_machine;
|
||||||
State states[COUNT_PLAYER_STATES];
|
State states[COUNT_PLAYER_STATES];
|
||||||
AnimPlayer animations[COUNT_PLAYER_STATES];
|
AnimPlayer animations[COUNT_PLAYER_STATES];
|
||||||
PlayerControl controls;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void player_init (Player *player, SDL_Renderer *renderer, SDL_Rect position);
|
void player_init (Player *player, SDL_Renderer *renderer, SDL_Rect position);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user