Initial work on player & input

This commit is contained in:
Edgaru089 2024-03-01 14:37:59 +08:00
parent 058865f29e
commit f9d4d17163
8 changed files with 116 additions and 2 deletions

4
.gitignore vendored
View File

@ -361,3 +361,7 @@ MigrationBackup/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
*.o
*.exe

40
Input.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
// Types of input the player might want
typedef enum {
input_Key_Left,
input_Key_Right,
input_Key_Up,
input_Key_Down,
input_Key_Jump,
input_Key_Attack,
input_Key_Spell,
input_Key_Use,
input_Key_Count
} input_Key;
// States a key might in
typedef enum {
Pressed,
JustPressed,
Released,
JustReleased
} input_KeyState;
typedef struct {
input_KeyState keys[input_Key_Count]; // States of keys
} System_Input;
#ifdef __cplusplus
}
#endif

View File

@ -60,7 +60,7 @@ void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime);
void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime); void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime);
inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Duration deltaTime) { static inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Duration deltaTime) {
ASSERT(e->position && "_physics_AdvanceEntity() called on entity with no position"); ASSERT(e->position && "_physics_AdvanceEntity() called on entity with no position");
// Short path // Short path

View File

@ -16,6 +16,9 @@ typedef struct _Entity Entity;
extern double physics_Gravity; extern double physics_Gravity;
// Position component.
//
// If not exist, it's like it's at (0,0)
typedef struct { typedef struct {
Entity *super; Entity *super;
Vec2 position; Vec2 position;
@ -23,6 +26,9 @@ typedef struct {
} Component_Position; } Component_Position;
// Handler called when hitboxes are hit
typedef void (*physics_HitHandler)(Entity *me, Entity *other, Vec2 triedDelta);
// Box is relative to Position if exists // Box is relative to Position if exists
// if not, Box is absolute // if not, Box is absolute
// //
@ -31,6 +37,8 @@ typedef struct {
Entity *super; Entity *super;
Box2 box; Box2 box;
bool fixed; bool fixed;
physics_HitHandler onHit;
} Component_Hitbox; } Component_Hitbox;
// Returns the absolute version of the hitbox. // Returns the absolute version of the hitbox.

View File

@ -13,6 +13,11 @@ static inline double dabs(double x) {
return x < 0 ? -x : x; return x < 0 ? -x : x;
} }
static inline void call_hithandler(Entity *me, Entity *other, Vec2 triedDelta) {
if (me->hitbox->onHit)
me->hitbox->onHit(me, other, triedDelta);
}
void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) { void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) {
double delta = e->position->velocity.x * duration_Seconds(deltaTime); double delta = e->position->velocity.x * duration_Seconds(deltaTime);
@ -29,6 +34,7 @@ void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) {
continue; continue;
if (box2_Intersects(tohit, box2_OffsetX(mybox, delta), NULL)) { if (box2_Intersects(tohit, box2_OffsetX(mybox, delta), NULL)) {
call_hithandler(e, tohit_comp->super, vec2(delta, 0));
if (delta > 0) { if (delta > 0) {
// Moves right, hits left edge // Moves right, hits left edge
double maxdelta = tohit.lefttop.x - mybox.lefttop.x - mybox.size.x; double maxdelta = tohit.lefttop.x - mybox.lefttop.x - mybox.size.x;
@ -63,6 +69,7 @@ void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime) {
continue; continue;
if (box2_Intersects(tohit, box2_OffsetY(mybox, delta), NULL)) { if (box2_Intersects(tohit, box2_OffsetY(mybox, delta), NULL)) {
call_hithandler(e, tohit_comp->super, vec2(0, delta));
if (delta > 0) { if (delta > 0) {
// Moves down, hits top edge // Moves down, hits top edge
double maxdelta = tohit.lefttop.y - mybox.lefttop.y - mybox.size.y; double maxdelta = tohit.lefttop.y - mybox.lefttop.y - mybox.size.y;

35
Player_Component.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _Entity Entity;
// Player controller component.
// Only one entity should have this.
typedef struct {
Entity *super;
int jumpCount; // Number of times the player has jumped since leaving ground
// (Initial jump does not count)
bool onGround; // If the player is on the ground?
bool moveLeft, moveRight; // If the player is moving left/right?
} Component_Player;
// Player controller instance.
// Reads input from the app.
typedef struct {
// The player in the world.
// Control is paused if equals NULL.
Component_Player *player;
} System_Player;
#ifdef __cplusplus
}
#endif

View File

@ -68,3 +68,11 @@ Box2 box2_OffsetY(Box2 box, double offsetY) {
box.lefttop.y += offsetY; box.lefttop.y += offsetY;
return box; return box;
} }
Duration duration_Now() {
// TODO Use Windows.h
// Reference: https://github.com/SFML/SFML/blob/2.6.x/src/SFML/System/Win32/ClockImpl.cpp
Duration d = {.microseconds = 0};
return d;
}

12
Types.h
View File

@ -14,6 +14,11 @@ typedef struct {
} Vec2; } Vec2;
inline Vec2 vec2(double x, double y) {
Vec2 v = {.x = x, .y = y};
return v;
}
Vec2 vec2_Add(Vec2 x, Vec2 y); Vec2 vec2_Add(Vec2 x, Vec2 y);
Vec2 vec2_Scale(Vec2 v, double scale); Vec2 vec2_Scale(Vec2 v, double scale);
@ -33,6 +38,7 @@ Box2 box2_OffsetX(Box2 box, double offsetX);
Box2 box2_OffsetY(Box2 box, double offsetY); Box2 box2_OffsetY(Box2 box, double offsetY);
// Time duration.
typedef struct { typedef struct {
uint64_t microseconds; uint64_t microseconds;
} Duration; } Duration;
@ -40,6 +46,12 @@ typedef struct {
static inline double duration_Seconds(const Duration t) { return ((double)t.microseconds) / 1000.0 / 1000.0; } static inline double duration_Seconds(const Duration t) { return ((double)t.microseconds) / 1000.0 / 1000.0; }
static inline double duration_Milliseconds(const Duration t) { return ((double)t.microseconds) / 1000.0; } static inline double duration_Milliseconds(const Duration t) { return ((double)t.microseconds) / 1000.0; }
// Returns a relative duration since
// a static time point in the past.
//
// Its absolute value has no meaning.
Duration duration_Now();
#ifdef __cplusplus #ifdef __cplusplus
} }