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 <stdio.h>
#define BEZIER_POINTS 10
// Global Constants
#define BEZIER_POINTS 7
#define LEFT KEY_LEFT
#define RIGHT KEY_RIGHT
#define JUMP KEY_SPACE
@ -13,6 +14,12 @@ struct kinematic_obj
Vector2 velocity;
};
struct kinematic_obj_node
{
struct kinematic_obj *obj;
struct kinematic_obj_node *next;
};
enum PLAYER_STATE
{
IDLE = 0,
@ -53,16 +60,6 @@ struct squishy_square
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
struct kinematic_obj init_kinematic_obj(int width, int height);
void move(struct kinematic_obj *obj, Vector2 acceleration);
@ -75,7 +72,11 @@ int sign(float val);
Vector2 dir(Vector2 vec);
// 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
struct squishy_square init_squishy_square(Rectangle *rect, Color color);

18
main.c
View File

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

View File

@ -1,4 +1,5 @@
#include "header.h"
extern struct kinematic_obj_node *kinematic_HEAD;
struct kinematic_obj init_kinematic_obj(int width, int height){
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){
// Use Euler method for moving
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;
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){
if(current->obj != obj){
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){
struct obj_node *current = HEAD;
struct kinematic_obj_node *current = kinematic_HEAD;
Rectangle rect_check = obj->rect;
rect_check.x += dir.x;
rect_check.y += dir.y;

View File

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