Add FSM for player movement

master
En Yi 2020-01-01 16:10:32 +08:00
parent c48194ae12
commit c30e3efcae
5 changed files with 99 additions and 35 deletions

View File

@ -1,7 +1,8 @@
#include <raylib.h> #include <raylib.h>
#include <stdio.h> #include <stdio.h>
#define BEZIER_POINTS 10 // Global Constants
#define BEZIER_POINTS 7
#define LEFT KEY_LEFT #define LEFT KEY_LEFT
#define RIGHT KEY_RIGHT #define RIGHT KEY_RIGHT
#define JUMP KEY_SPACE #define JUMP KEY_SPACE
@ -13,6 +14,12 @@ struct kinematic_obj
Vector2 velocity; Vector2 velocity;
}; };
struct kinematic_obj_node
{
struct kinematic_obj *obj;
struct kinematic_obj_node *next;
};
enum PLAYER_STATE enum PLAYER_STATE
{ {
IDLE = 0, IDLE = 0,
@ -53,16 +60,6 @@ struct squishy_square
double right_offset; double right_offset;
}; };
// Placeholder collision checking structure. Use linked list for now
// Need to implement some sort of tree structure for efficient collision checking
struct obj_node
{
struct kinematic_obj *obj;
struct obj_node *next;
};
extern struct obj_node *HEAD;
// Object functions, kinematics.c // Object functions, kinematics.c
struct kinematic_obj init_kinematic_obj(int width, int height); struct kinematic_obj init_kinematic_obj(int width, int height);
void move(struct kinematic_obj *obj, Vector2 acceleration); void move(struct kinematic_obj *obj, Vector2 acceleration);
@ -75,7 +72,11 @@ int sign(float val);
Vector2 dir(Vector2 vec); Vector2 dir(Vector2 vec);
// Linked list, linked_list.c // Linked list, linked_list.c
extern struct kinematic_obj_node *kinematic_HEAD;
void create_list(void);
void add_node(struct kinematic_obj *obj);
//struct kinematic_obj_node **get_list();
void free_list(void);
// Squishy Square functions, squishy.c // Squishy Square functions, squishy.c
struct squishy_square init_squishy_square(Rectangle *rect, Color color); struct squishy_square init_squishy_square(Rectangle *rect, Color color);

18
main.c
View File

@ -20,7 +20,7 @@
********************************************************************************************/ ********************************************************************************************/
#include "header.h" #include "header.h"
struct obj_node *HEAD; extern struct kinematic_obj_node *kinematic_HEAD;
int PLAYER_ACCEL = 1500; int PLAYER_ACCEL = 1500;
int JUMP_ACCEL = 15000; int JUMP_ACCEL = 15000;
int JUMP_SPD = 350; int JUMP_SPD = 350;
@ -48,20 +48,23 @@ int main()
struct kinematic_obj tile = init_kinematic_obj(900, 100); struct kinematic_obj tile = init_kinematic_obj(900, 100);
struct kinematic_obj tile2 = init_kinematic_obj(100, 40); struct kinematic_obj tile2 = init_kinematic_obj(100, 40);
struct kinematic_obj tile3 = init_kinematic_obj(100, 40);
set_position(&player.kinematic, 400, 300); set_position(&player.kinematic, 400, 300);
set_position(&tile, -50, 380); set_position(&tile, -50, 380);
set_position(&tile2, 350, 280); set_position(&tile2, 350, 280);
set_position(&tile3, 250, 167);
struct squishy_square sqr = init_squishy_square(&player.kinematic.rect, RED); struct squishy_square sqr = init_squishy_square(&player.kinematic.rect, RED);
// TODO: get a linked list implementation // TODO: get a linked list implementation
struct obj_node tile_node = {.obj=&tile, .next=NULL}; //create_list();
struct obj_node tile2_node = {.obj=&tile2, .next=&tile_node}; add_node(&tile);
struct obj_node player_node = {.obj=&player.kinematic, .next=&tile2_node}; add_node(&tile2);
HEAD = &player_node; add_node(&tile3);
add_node(&player.kinematic);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
struct obj_node *current; struct kinematic_obj_node *current;
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
@ -81,7 +84,7 @@ int main()
draw_squishy(&sqr); draw_squishy(&sqr);
BeginMode2D(camera); BeginMode2D(camera);
current = HEAD; current = kinematic_HEAD;
while(current){ while(current){
DrawRectangleLinesEx(current->obj->rect, 1, BLACK); DrawRectangleLinesEx(current->obj->rect, 1, BLACK);
current = current->next; current = current->next;
@ -99,6 +102,7 @@ int main()
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
free_list();
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View File

@ -1,4 +1,5 @@
#include "header.h" #include "header.h"
extern struct kinematic_obj_node *kinematic_HEAD;
struct kinematic_obj init_kinematic_obj(int width, int height){ struct kinematic_obj init_kinematic_obj(int width, int height){
struct kinematic_obj obj = { struct kinematic_obj obj = {
@ -17,13 +18,33 @@ void set_position(struct kinematic_obj *obj, int x, int y){
void move(struct kinematic_obj *obj, Vector2 acceleration){ void move(struct kinematic_obj *obj, Vector2 acceleration){
// Use Euler method for moving // Use Euler method for moving
double delta = 1.0/60.0; double delta = 1.0/60.0;
obj->velocity.x += acceleration.x * delta;
obj->velocity.y += acceleration.y * delta;
obj->rect.x += obj->velocity.x * delta;
obj->rect.y += obj->velocity.y * delta;
//Simplistic Collision Handling for AABB, Could add coeff of restitution?
struct obj_node *current = HEAD;
Rectangle collide_rect; Rectangle collide_rect;
struct kinematic_obj_node *current;
//Simplistic Collision Handling for AABB, Could add coeff of restitution?
obj->velocity.x += acceleration.x * delta;
obj->rect.x += obj->velocity.x * delta;
current = kinematic_HEAD;
while(current != NULL){
if(current->obj != obj){
if (CheckCollisionRecs(obj->rect, current->obj->rect)){
collide_rect = GetCollisionRec(obj->rect, current->obj->rect);
if(collide_rect.width < collide_rect.height){
obj->rect.x -= sign(obj->velocity.x) * collide_rect.width;
obj->velocity.x = 0;
}else{
obj->rect.y -= sign(obj->velocity.y) * collide_rect.height;
obj->velocity.y = 0;
}
}
}
current = current->next;
}
// Repeat for y
obj->velocity.y += acceleration.y * delta;
obj->rect.y += obj->velocity.y * delta;
current = kinematic_HEAD;
while(current != NULL){ while(current != NULL){
if(current->obj != obj){ if(current->obj != obj){
if (CheckCollisionRecs(obj->rect, current->obj->rect)){ if (CheckCollisionRecs(obj->rect, current->obj->rect)){
@ -42,7 +63,7 @@ void move(struct kinematic_obj *obj, Vector2 acceleration){
}; };
bool place_meeting(struct kinematic_obj *obj, Vector2 dir){ bool place_meeting(struct kinematic_obj *obj, Vector2 dir){
struct obj_node *current = HEAD; struct kinematic_obj_node *current = kinematic_HEAD;
Rectangle rect_check = obj->rect; Rectangle rect_check = obj->rect;
rect_check.x += dir.x; rect_check.x += dir.x;
rect_check.y += dir.y; rect_check.y += dir.y;

View File

@ -3,9 +3,9 @@
#define PLAYER_ACCEL 1600 #define PLAYER_ACCEL 1600
#define AIR_ACCEL 400 #define AIR_ACCEL 400
#define RUN_INIT_SPD 250 #define RUN_INIT_SPD 270
#define JUMP_SPD 500 #define JUMP_SPD 500
#define GRAV 1000 #define GRAV 1200
static bool allow_move = true; static bool allow_move = true;
static bool allow_friction = true; static bool allow_friction = true;
@ -16,9 +16,9 @@ static unsigned int frame_counter = 0;
static int run_dir = 1; static int run_dir = 1;
static enum PLAYER_STATE state_buffer = IDLE; static enum PLAYER_STATE state_buffer = IDLE;
const unsigned int run_start_frames = 8; const unsigned int run_start_frames = 10;
const unsigned int jump_squat_frames = 5; const unsigned int jump_squat_frames = 4;
const unsigned int land_lag_frames = 4; const unsigned int land_lag_frames = 6;
// The player FSM // The player FSM
void player_input_check(struct player_obj *player){ void player_input_check(struct player_obj *player){
@ -30,7 +30,7 @@ void player_input_check(struct player_obj *player){
case IDLE: case IDLE:
if (IsKeyDown(LEFT) || IsKeyDown(RIGHT)){ if (IsKeyDown(LEFT) || IsKeyDown(RIGHT)){
player->state = RUN_START; player->state = RUN_START;
allow_friction = false; //allow_friction = false;
player->kinematic.velocity.x = (IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT)) * RUN_INIT_SPD; player->kinematic.velocity.x = (IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT)) * RUN_INIT_SPD;
} }
break; break;
@ -39,12 +39,15 @@ void player_input_check(struct player_obj *player){
// Run Opposite Direction // Run Opposite Direction
if ((IsKeyPressed(LEFT) && run_dir == 1) || (IsKeyPressed(RIGHT) && run_dir == -1)){ if ((IsKeyPressed(LEFT) && run_dir == 1) || (IsKeyPressed(RIGHT) && run_dir == -1)){
frame_counter = 0; frame_counter = 0;
player->kinematic.velocity.x *= -1; player->kinematic.velocity.x = -run_dir * RUN_INIT_SPD;
}else{ }else{
// Complete the run startup // Complete the run startup
if(frame_counter<run_start_frames) if(frame_counter<run_start_frames){
++frame_counter; ++frame_counter;
else{ if (IsKeyDown(LEFT) || IsKeyDown(RIGHT)){
player->kinematic.velocity.x = run_dir * RUN_INIT_SPD;
}
}else{
frame_counter = 0; frame_counter = 0;
allow_friction = true; allow_friction = true;
player->state = RUNNING; player->state = RUNNING;

View File

@ -0,0 +1,35 @@
#include "header.h"
#include <stdlib.h>
// Placeholder collision checking structure. Use linked list for now
// Need to implement some sort of tree structure for efficient collision checking
struct kinematic_obj_node *kinematic_HEAD = NULL;
void add_node(struct kinematic_obj *obj){
struct kinematic_obj_node *node = malloc(sizeof(struct kinematic_obj_node));
if (node){
node->obj = obj;
node->next = NULL;
}
if (kinematic_HEAD == NULL){
kinematic_HEAD = node;
}else{
node->next = kinematic_HEAD;
kinematic_HEAD = node;
}
}
/**struct kinematic_obj_node **get_list(){
return &kinematic_HEAD;
}*/
void free_list(){
struct kinematic_obj_node *current = kinematic_HEAD;
struct kinematic_obj_node *next;
while(current){
next = current->next;
free(current);
current = next;
}
kinematic_HEAD = NULL;
}