Add FSM to player movement
parent
0a3fefb194
commit
6540e27b0e
|
@ -1,4 +1,4 @@
|
|||
*
|
||||
!*.c
|
||||
!*.h
|
||||
!.gitignore
|
||||
Make*
|
||||
main.code-workspace
|
||||
main
|
||||
.vscode
|
||||
|
|
|
@ -2,12 +2,37 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#define BEZIER_POINTS 10
|
||||
#define LEFT KEY_LEFT
|
||||
#define RIGHT KEY_RIGHT
|
||||
#define JUMP KEY_SPACE
|
||||
#define DASH KEY_Z
|
||||
|
||||
struct kinematic_obj
|
||||
{
|
||||
Rectangle rect;
|
||||
Vector2 velocity;
|
||||
Color color;
|
||||
};
|
||||
|
||||
enum PLAYER_STATE
|
||||
{
|
||||
IDLE = 0,
|
||||
JUMP_SQUAT,
|
||||
JUMPING,
|
||||
FALLING,
|
||||
LANDING,
|
||||
DASH_START,
|
||||
DASHING,
|
||||
DASH_END,
|
||||
RUN_START,
|
||||
RUNNING,
|
||||
RUN_END,
|
||||
TURN_AROUND
|
||||
};
|
||||
|
||||
struct player_obj
|
||||
{
|
||||
struct kinematic_obj kinematic;
|
||||
enum PLAYER_STATE state;
|
||||
};
|
||||
|
||||
struct squishy_square
|
||||
|
@ -51,7 +76,15 @@ Vector2 dir(Vector2 vec);
|
|||
|
||||
// Linked list, linked_list.c
|
||||
|
||||
|
||||
// Squishy Square functions, squishy.c
|
||||
struct squishy_square init_squishy_square(Rectangle *rect, Color color);
|
||||
void update_squishy(struct squishy_square *square);
|
||||
void draw_squishy(struct squishy_square *square);
|
||||
|
||||
//Player stuff, player.c
|
||||
struct player_obj init_player_obj();
|
||||
void player_input_check(struct player_obj *player);
|
||||
|
||||
//Debug stuff, debug.c
|
||||
void state_string(char *str, enum PLAYER_STATE state);
|
46
main.c
46
main.c
|
@ -23,13 +23,16 @@
|
|||
struct obj_node *HEAD;
|
||||
int PLAYER_ACCEL = 1500;
|
||||
int JUMP_ACCEL = 15000;
|
||||
int GRAV = 750;
|
||||
int JUMP_SPD = 350;
|
||||
int GRAV = 1000;
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
char current_state[20];
|
||||
char current_spd[50];
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib");
|
||||
|
||||
|
@ -38,16 +41,19 @@ int main()
|
|||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
struct kinematic_obj player = init_kinematic_obj(40, 40);
|
||||
player.color = BLUE;
|
||||
struct player_obj player = {
|
||||
.kinematic = init_kinematic_obj(40, 40),
|
||||
.state = IDLE
|
||||
};
|
||||
|
||||
struct kinematic_obj tile = init_kinematic_obj(900, 100);
|
||||
set_position(&player, 400, 300);
|
||||
set_position(&tile, -50, 380);
|
||||
struct squishy_square sqr = init_squishy_square(&player.rect, RED);
|
||||
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 player_node = {.obj=&player, .next=&tile_node};
|
||||
struct obj_node player_node = {.obj=&player.kinematic, .next=&tile_node};
|
||||
HEAD = &player_node;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
@ -58,26 +64,10 @@ int main()
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
//UpdateCamera(&camera);
|
||||
Vector2 accel = (Vector2){
|
||||
.x = PLAYER_ACCEL*(IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT)),
|
||||
.y = 0
|
||||
};
|
||||
|
||||
if (!place_meeting(&player, (Vector2){0,1})){
|
||||
accel.y = GRAV;
|
||||
}
|
||||
accel.x -= player.velocity.x * 6.5;
|
||||
|
||||
if (IsKeyDown(KEY_SPACE) && place_meeting(&player, (Vector2){0,1}))
|
||||
accel.y -= JUMP_ACCEL;
|
||||
move(&player, accel);
|
||||
player_input_check(&player);
|
||||
|
||||
update_squishy(&sqr);
|
||||
Vector2 center = (Vector2){
|
||||
.x = (sqr.topleft.x + sqr.topright.x)/2,
|
||||
.y = (sqr.topleft.y + sqr.bottomleft.y)/2
|
||||
};
|
||||
update_squishy(&sqr);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
@ -85,15 +75,19 @@ int main()
|
|||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
draw_squishy(&sqr);
|
||||
|
||||
BeginMode2D(camera);
|
||||
current = HEAD;
|
||||
while(current){
|
||||
DrawRectangleRec(current->obj->rect, current->obj->color);
|
||||
DrawRectangleLinesEx(current->obj->rect, 1, BLACK);
|
||||
current = current->next;
|
||||
}
|
||||
DrawFPS(100,100);
|
||||
draw_squishy(&sqr);
|
||||
DrawFPS(0,0);
|
||||
state_string(current_state, player.state);
|
||||
DrawText(current_state, 250, 0, 12, BLACK);
|
||||
sprintf(current_spd, "Velocity: {%.2f,%.2f}", player.kinematic.velocity.x,player.kinematic.velocity.y);
|
||||
DrawText(current_spd, 350, 0, 12, BLACK);
|
||||
EndMode2D();
|
||||
|
||||
EndDrawing();
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
struct kinematic_obj init_kinematic_obj(int width, int height){
|
||||
struct kinematic_obj obj = {
|
||||
.velocity = {0.0f,0.0f},
|
||||
.rect = {0,0,width,height},
|
||||
.color = BLACK
|
||||
.rect = {0,0,width,height}
|
||||
};
|
||||
|
||||
return obj;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
#include "header.h"
|
||||
|
||||
|
||||
#define PLAYER_ACCEL 1500
|
||||
#define RUN_INIT_SPD 200
|
||||
#define JUMP_SPD 500
|
||||
#define GRAV 1000
|
||||
|
||||
static bool allow_move = true;
|
||||
static int jumps = 1;
|
||||
static frame_counter = 0;
|
||||
static int run_dir = 1;
|
||||
static bool allow_friction = true;
|
||||
const unsigned int run_start_frames = 8;
|
||||
const unsigned int jump_squat_frames = 6;
|
||||
const unsigned int land_lag_frames = 5;
|
||||
|
||||
// The player FSM
|
||||
void player_input_check(struct player_obj *player){
|
||||
Vector2 accel = (Vector2){
|
||||
.x = 0,
|
||||
.y = 0
|
||||
};
|
||||
switch(player->state){
|
||||
case IDLE:
|
||||
if (IsKeyDown(LEFT) || IsKeyDown(RIGHT)){
|
||||
player->state = RUN_START;
|
||||
allow_friction = false;
|
||||
player->kinematic.velocity.x = (IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT)) * RUN_INIT_SPD;
|
||||
}
|
||||
break;
|
||||
case RUN_START:
|
||||
run_dir = sign(player->kinematic.velocity.x);
|
||||
// Run Opposite Direction
|
||||
if ((IsKeyPressed(LEFT) && run_dir == 1) || (IsKeyPressed(RIGHT) && run_dir == -1)){
|
||||
frame_counter = 0;
|
||||
player->kinematic.velocity.x *= -1;
|
||||
}else{
|
||||
// Complete the run startup
|
||||
if(frame_counter<run_start_frames)
|
||||
++frame_counter;
|
||||
else{
|
||||
frame_counter = 0;
|
||||
allow_friction = true;
|
||||
player->state = RUNNING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RUNNING:
|
||||
run_dir = sign(player->kinematic.velocity.x);
|
||||
if ((IsKeyPressed(LEFT) && run_dir == 1) || (IsKeyPressed(RIGHT) && run_dir == -1)){
|
||||
player->state = RUN_END;
|
||||
}else{
|
||||
if (!IsKeyDown(LEFT) && !IsKeyDown(RIGHT)){
|
||||
player->state = RUN_END;
|
||||
}else{
|
||||
accel.x = PLAYER_ACCEL*(IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RUN_END:
|
||||
if(player->kinematic.velocity.x < 10 && player->kinematic.velocity.x > -10){
|
||||
if(IsKeyDown(LEFT) || IsKeyDown(RIGHT)){
|
||||
player->state = RUNNING;
|
||||
}else{
|
||||
player->state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TURN_AROUND:
|
||||
|
||||
break;
|
||||
case JUMP_SQUAT:
|
||||
if(frame_counter<jump_squat_frames)
|
||||
++frame_counter;
|
||||
else{
|
||||
frame_counter = 0;
|
||||
if (IsKeyDown(JUMP))
|
||||
player->kinematic.velocity.y = -JUMP_SPD;
|
||||
else
|
||||
player->kinematic.velocity.y = -JUMP_SPD/2;
|
||||
player->state = JUMPING;
|
||||
}
|
||||
break;
|
||||
case JUMPING:
|
||||
accel.x = PLAYER_ACCEL*(IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT));
|
||||
if (player->kinematic.velocity.y > 0)
|
||||
player->state = FALLING;
|
||||
break;
|
||||
case FALLING:
|
||||
accel.x = PLAYER_ACCEL*(IsKeyDown(KEY_RIGHT)-IsKeyDown(KEY_LEFT));
|
||||
if (place_meeting(&player->kinematic, (Vector2){0,1})){
|
||||
player->state = LANDING;
|
||||
}
|
||||
break;
|
||||
case LANDING:
|
||||
if(frame_counter<land_lag_frames)
|
||||
++frame_counter;
|
||||
else{
|
||||
jumps = 1;
|
||||
frame_counter = 0;
|
||||
if (IsKeyDown(LEFT) || IsKeyDown(RIGHT)){
|
||||
player->state = RUNNING;
|
||||
}else{
|
||||
player->state = IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DASH_START:
|
||||
|
||||
break;
|
||||
case DASHING:
|
||||
|
||||
break;
|
||||
case DASH_END:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(JUMP) && jumps > 0){
|
||||
player->state = JUMP_SQUAT;
|
||||
allow_friction = true;
|
||||
--jumps;
|
||||
}
|
||||
|
||||
if (allow_friction == true)
|
||||
accel.x -= player->kinematic.velocity.x * 8;
|
||||
|
||||
if (!place_meeting(&player, (Vector2){0,1})){
|
||||
accel.y = GRAV;
|
||||
}
|
||||
|
||||
move(&player->kinematic, accel);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include "header.h"
|
||||
|
||||
void state_string(char *str, enum PLAYER_STATE state){
|
||||
switch(state){
|
||||
case IDLE: sprintf(str, "%s", "IDLE");break;
|
||||
case JUMP_SQUAT: sprintf(str, "%s", "JUMP_SQUAT");break;
|
||||
case JUMPING: sprintf(str, "%s", "JUMPING");break;
|
||||
case FALLING: sprintf(str, "%s", "FALLING");break;
|
||||
case LANDING: sprintf(str, "%s", "LANDING");break;
|
||||
case DASH_START: sprintf(str, "%s", "DASH_START");break;
|
||||
case DASHING: sprintf(str, "%s", "DASHING");break;
|
||||
case DASH_END: sprintf(str, "%s", "DASH_END");break;
|
||||
case RUN_START: sprintf(str, "%s", "RUN_START");break;
|
||||
case RUNNING: sprintf(str, "%s", "RUNNING");break;
|
||||
case RUN_END: sprintf(str, "%s", "RUN_END");break;
|
||||
case TURN_AROUND: sprintf(str, "%s", "TURN_AROUND");break;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue