Load entities from file, barrel roll!

main
Cameron Murphy Reikes 2 years ago
parent 1ee06fa381
commit fadae61b2b

@ -14,6 +14,10 @@
{ {
filepath: "_Attack.png", filepath: "_Attack.png",
} }
@image knight_roll:
{
filepath: "_Roll.png",
}
@image old_man: @image old_man:
{ {
filepath: "small_old_man.png", filepath: "small_old_man.png",

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -1,11 +1,4 @@
{ "compressionlevel":-1, { "compressionlevel":-1,
"editorsettings":
{
"export":
{
"format":"json"
}
},
"height":60, "height":60,
"infinite":false, "infinite":false,
"layers":[ "layers":[
@ -32,11 +25,11 @@
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 212, 213, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 212, 213, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 158, 210, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 158, 210, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 212, 159, 159, 159, 159, 159, 159, 159, 213, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 316, 367, 314, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 261, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 366, 314, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 366, 314, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 313, 367, 367, 367, 367, 367, 368, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 261, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 265, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
@ -89,12 +82,45 @@
"class":"", "class":"",
"height":32, "height":32,
"id":1, "id":1,
"name":"spawn", "name":"PLAYER",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":960, "x":960,
"y":928 "y":928
},
{
"class":"",
"height":32,
"id":2,
"name":"OLD_MAN",
"rotation":0,
"visible":true,
"width":32,
"x":804.666333333333,
"y":770.666333333333
},
{
"class":"",
"height":32,
"id":3,
"name":"OLD_MAN",
"rotation":0,
"visible":true,
"width":32,
"x":834,
"y":916
},
{
"class":"",
"height":32,
"id":4,
"name":"OLD_MAN",
"rotation":0,
"visible":true,
"width":32,
"x":970,
"y":761.333333333333
}], }],
"opacity":1, "opacity":1,
"type":"objectgroup", "type":"objectgroup",
@ -103,7 +129,7 @@
"y":0 "y":0
}], }],
"nextlayerid":6, "nextlayerid":6,
"nextobjectid":2, "nextobjectid":5,
"orientation":"orthogonal", "orientation":"orthogonal",
"renderorder":"right-down", "renderorder":"right-down",
"tiledversion":"1.9.2", "tiledversion":"1.9.2",

@ -30,7 +30,7 @@
"class":"", "class":"",
"height":31.604938271605, "height":31.604938271605,
"id":1, "id":1,
"name":"spawn", "name":"PLAYER",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":29.9415204678363, "width":29.9415204678363,

@ -48,6 +48,15 @@ void dump_root(MD_Node* from) {
} }
} }
bool has_decimal(MD_String8 s)
{
for(int i = 0; i < s.size; i++)
{
if(s.str[i] == '.') return true;
}
return false;
}
MD_Arena *cg_arena = NULL; MD_Arena *cg_arena = NULL;
MD_String8 ChildValue(MD_Node *n, MD_String8 name) { MD_String8 ChildValue(MD_Node *n, MD_String8 name) {
@ -114,7 +123,6 @@ int main(int argc, char **argv) {
MD_String8List load_list = {0}; MD_String8List load_list = {0};
MD_String8List level_decl_list = {0}; MD_String8List level_decl_list = {0};
MD_String8List tileset_decls = {0}; MD_String8List tileset_decls = {0};
MD_String8List object_decls_list = {0};
for(MD_EachNode(node, parse.node->first_child)) { for(MD_EachNode(node, parse.node->first_child)) {
if(MD_S8Match(node->first_tag->string, MD_S8Lit("image"), 0)) { if(MD_S8Match(node->first_tag->string, MD_S8Lit("image"), 0)) {
MD_String8 variable_name = MD_S8Fmt(cg_arena, "image_%.*s", MD_S8VArg(node->string)); MD_String8 variable_name = MD_S8Fmt(cg_arena, "image_%.*s", MD_S8VArg(node->string));
@ -172,20 +180,28 @@ int main(int argc, char **argv) {
log("New level variable %.*s\n", MD_S8VArg(variable_name)); log("New level variable %.*s\n", MD_S8VArg(variable_name));
MD_String8 filepath = asset_file_path(ChildValue(node, MD_S8Lit("filepath"))); MD_String8 filepath = asset_file_path(ChildValue(node, MD_S8Lit("filepath")));
MD_ParseResult level_parse = MD_ParseWholeFile(cg_arena, filepath); MD_ParseResult level_parse = MD_ParseWholeFile(cg_arena, filepath);
assert(level_parse.node != 0, MD_S8Lit("Failed to load level file")); assert(!MD_NodeIsNil(level_parse.node->first_child), MD_S8Lit("Failed to load level file"));
MD_Node *layers = MD_ChildFromString(level_parse.node->first_child, MD_S8Lit("layers"), 0); MD_Node *layers = MD_ChildFromString(level_parse.node->first_child, MD_S8Lit("layers"), 0);
fprintf(output, "Level %.*s = {\n", MD_S8VArg(variable_name)); fprintf(output, "Level %.*s = {\n", MD_S8VArg(variable_name));
for(MD_EachNode(lay, layers->first_child)) { for(MD_EachNode(lay, layers->first_child)) {
MD_String8 type = MD_ChildFromString(lay, MD_S8Lit("type"), 0)->first_child->string; MD_String8 type = MD_ChildFromString(lay, MD_S8Lit("type"), 0)->first_child->string;
if(MD_S8Match(type, MD_S8Lit("objectgroup"), 0)) { if(MD_S8Match(type, MD_S8Lit("objectgroup"), 0)) {
fprintf(output, ".initial_entities = {\n");
for(MD_EachNode(object, MD_ChildFromString(lay, MD_S8Lit("objects"), 0)->first_child)) { for(MD_EachNode(object, MD_ChildFromString(lay, MD_S8Lit("objects"), 0)->first_child)) {
dump(object); dump(object);
// negative numbers for object position aren't supported here
MD_String8 name = MD_ChildFromString(object, MD_S8Lit("name"), 0)->first_child->string; MD_String8 name = MD_ChildFromString(object, MD_S8Lit("name"), 0)->first_child->string;
MD_String8 x_string = MD_ChildFromString(object, MD_S8Lit("x"), 0)->first_child->string; MD_String8 x_string = MD_ChildFromString(object, MD_S8Lit("x"), 0)->first_child->string;
MD_String8 y_string = MD_ChildFromString(object, MD_S8Lit("y"), 0)->first_child->string; MD_String8 y_string = MD_ChildFromString(object, MD_S8Lit("y"), 0)->first_child->string;
list_printf(&object_decls_list, "Vec2 %.*s_tilepoint = { %.*s, %.*s };\n", MD_S8VArg(name), MD_S8VArg(x_string), MD_S8VArg(y_string)); y_string = MD_S8Fmt(cg_arena, "-%.*s", MD_S8VArg(y_string));
if(has_decimal(x_string)) x_string = MD_S8Fmt(cg_arena, "%.*sf", MD_S8VArg(x_string));
if(has_decimal(y_string)) y_string = MD_S8Fmt(cg_arena, "%.*sf", MD_S8VArg(y_string));
fprintf(output, "{ .exists = true, .kind = ENTITY_%.*s, .pos = { .X=%.*s, .Y=%.*s }, }, ", MD_S8VArg(name), MD_S8VArg(x_string), MD_S8VArg(y_string));
} }
fprintf(output, "\n}, // entities\n");
} }
if(MD_S8Match(type, MD_S8Lit("tilelayer"), 0)) { if(MD_S8Match(type, MD_S8Lit("tilelayer"), 0)) {
int width = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("width"), 0)->first_child->string)); int width = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("width"), 0)->first_child->string));
@ -215,10 +231,9 @@ int main(int argc, char **argv) {
MD_StringJoin join = MD_ZERO_STRUCT; MD_StringJoin join = MD_ZERO_STRUCT;
MD_String8 declarations = MD_S8ListJoin(cg_arena, declarations_list, &join); MD_String8 declarations = MD_S8ListJoin(cg_arena, declarations_list, &join);
MD_String8 object_declarations = MD_S8ListJoin(cg_arena, object_decls_list, &join);
MD_String8 loads = MD_S8ListJoin(cg_arena, load_list, &join); MD_String8 loads = MD_S8ListJoin(cg_arena, load_list, &join);
fprintf(output, "%.*s\nvoid load_assets() {\n%.*s\n}\n", MD_S8VArg(declarations), MD_S8VArg(loads)); fprintf(output, "%.*s\nvoid load_assets() {\n%.*s\n}\n", MD_S8VArg(declarations), MD_S8VArg(loads));
fprintf(output, "%.*s\n%.*s\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join)), MD_S8VArg(object_declarations)); fprintf(output, "%.*s\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join)));
fclose(output); fclose(output);
return 0; return 0;

158
main.c

@ -68,13 +68,49 @@ typedef struct AnimatedSprite
bool no_wrap; // does not wrap when playing bool no_wrap; // does not wrap when playing
} AnimatedSprite; } AnimatedSprite;
typedef enum CharacterState
{
CHARACTER_WALKING,
CHARACTER_IDLE,
CHARACTER_ATTACK,
} CharacterState;
typedef enum EntityKind
{
ENTITY_INVALID, // zero initialized is invalid entity
ENTITY_PLAYER,
ENTITY_OLD_MAN,
} EntityKind;
typedef struct Entity
{
bool exists;
EntityKind kind;
// fields for all entities
Vec2 pos;
bool facing_left;
// character
CharacterState state;
bool is_rolling; // can only roll in idle or walk states
float speed; // for lerping to the speed, so that roll gives speed boost which fades
double roll_progress;
double swing_progress;
} Entity;
#define LEVEL_TILES 60 #define LEVEL_TILES 60
#define TILE_SIZE 32 // in pixels #define TILE_SIZE 32 // in pixels
#define MAX_ENTITIES 128
#define PLAYER_SPEED 3.0f // in meters per second
#define PLAYER_ROLL_SPEED 7.0f
typedef struct Level typedef struct Level
{ {
TileInstance tiles[LEVEL_TILES][LEVEL_TILES]; TileInstance tiles[LEVEL_TILES][LEVEL_TILES];
Vec2 spawnpoint; Entity initial_entities[MAX_ENTITIES]; // shouldn't be directly modified, only used to initialize entities on loading of level
} Level; } Level;
typedef struct TileCoord typedef struct TileCoord
@ -134,6 +170,7 @@ char *tprint(const char *format, ...)
return to_return; return to_return;
} }
// tilecoord is integer tile position, not like tile coord
Vec2 tilecoord_to_world(TileCoord t) Vec2 tilecoord_to_world(TileCoord t)
{ {
return V2( (float)t.x * (float)TILE_SIZE * 1.0f, -(float)t.y * (float)TILE_SIZE * 1.0f ); return V2( (float)t.x * (float)TILE_SIZE * 1.0f, -(float)t.y * (float)TILE_SIZE * 1.0f );
@ -232,11 +269,9 @@ AnimatedSprite knight_idle =
.img = &image_knight_idle, .img = &image_knight_idle,
.time_per_frame = 0.3, .time_per_frame = 0.3,
.num_frames = 10, .num_frames = 10,
.start = .start = {16.0f, 0.0f},
{16.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0, .horizontal_diff_btwn_frames = 120.0,
.region_size = .region_size = {80.0f, 80.0f},
{80.0f, 80.0f},
}; };
AnimatedSprite knight_running = AnimatedSprite knight_running =
@ -249,6 +284,18 @@ AnimatedSprite knight_running =
.region_size = {80.0f, 80.0f}, .region_size = {80.0f, 80.0f},
}; };
AnimatedSprite knight_rolling =
{
.img = &image_knight_roll,
.time_per_frame = 0.05,
.num_frames = 12,
.start = {19.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0,
.region_size = {80.0f, 80.0f},
.no_wrap = true,
};
AnimatedSprite knight_attack = AnimatedSprite knight_attack =
{ {
.img = &image_knight_attack, .img = &image_knight_attack,
@ -284,34 +331,8 @@ static struct
sg_bindings bind; sg_bindings bind;
} state; } state;
typedef enum CharacterState
{
CHARACTER_WALKING,
CHARACTER_IDLE,
CHARACTER_ATTACK,
} CharacterState;
typedef enum EntityKind
{
Player,
OldMan,
} EntityKind;
typedef struct Entity
{
bool exists;
EntityKind kind;
Vec2 pos;
bool facing_left;
// character
CharacterState state;
double swing_progress;
} Entity; Entity entities[MAX_ENTITIES] = {0};
Entity entities[128] = {0};
Entity *player = NULL; Entity *player = NULL;
Entity *new_entity() Entity *new_entity()
@ -340,8 +361,23 @@ void init(void)
load_assets(); load_assets();
player = new_entity(); // load level
player->pos = tilepoint_to_world(spawn_tilepoint); Level *to_load = &level_level0;
{
assert(ARRLEN(to_load->initial_entities) == ARRLEN(entities));
memcpy(entities, to_load->initial_entities, sizeof(Entity) * MAX_ENTITIES);
player = NULL;
for(int i = 0; i < MAX_ENTITIES; i++)
{
if(entities[i].exists && entities[i].kind == ENTITY_PLAYER)
{
assert(player == NULL);
player = &entities[i];
}
}
assert(player != NULL); // level initial config must have player entity
}
// load font // load font
{ {
@ -459,8 +495,7 @@ typedef struct Camera
// everything is in pixels in world space, 43 pixels is approx 1 meter measured from // everything is in pixels in world space, 43 pixels is approx 1 meter measured from
// merchant sprite being 5'6" // merchant sprite being 5'6"
const float pixels_per_meter = 43.0f; const float pixels_per_meter = 43.0f;
Camera cam = Camera cam = {.scale = 2.0f };
{.scale = 2.0f };
Vec2 cam_offset() Vec2 cam_offset()
{ {
@ -859,7 +894,7 @@ Vec2 move_and_slide(Vec2 position, Vec2 movement_this_frame, Vec2 collision_aabb
TileCoord to_check = world_to_tilecoord(*it); TileCoord to_check = world_to_tilecoord(*it);
uint16_t tile_id = get_tile(&level_level0, to_check).kind; uint16_t tile_id = get_tile(&level_level0, to_check).kind;
if(tile_id == 53 || tile_id == 0 || tile_id == 367 || tile_id == 317 || tile_id == 313 || tile_id == 366 ) if(tile_id == 53 || tile_id == 0 || tile_id == 367 || tile_id == 317 || tile_id == 313 || tile_id == 366 || tile_id == 368)
{ {
dbgsquare(tilecoord_to_world(to_check)); dbgsquare(tilecoord_to_world(to_check));
AABB to_depenetrate_from = tile_aabb(to_check); AABB to_depenetrate_from = tile_aabb(to_check);
@ -929,6 +964,7 @@ void frame(void)
(float)keydown[SAPP_KEYCODE_W] - (float)keydown[SAPP_KEYCODE_S] (float)keydown[SAPP_KEYCODE_W] - (float)keydown[SAPP_KEYCODE_S]
); );
bool attack = keydown[SAPP_KEYCODE_J]; bool attack = keydown[SAPP_KEYCODE_J];
bool roll = keydown[SAPP_KEYCODE_K];
if(LenV2(movement) > 1.0) if(LenV2(movement) > 1.0)
{ {
movement = NormV2(movement); movement = NormV2(movement);
@ -1033,7 +1069,14 @@ void frame(void)
#endif // devtools #endif // devtools
draw_animated_sprite(&old_man_idle, time, false, V2(884.788635f, -928.000000f), WHITE); for(int i = 0; i < ARRLEN(entities); i++) if(entities[i].exists)
{
if(entities[i].kind == ENTITY_OLD_MAN)
{
draw_animated_sprite(&old_man_idle, time, false, entities[i].pos, WHITE);
}
}
// player character // player character
{ {
@ -1045,11 +1088,41 @@ void frame(void)
player->swing_progress = 0.0; player->swing_progress = 0.0;
} }
// rolling
if(roll && !player->is_rolling && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING))
{
player->is_rolling = true;
player->roll_progress = 0.0;
player->speed = PLAYER_ROLL_SPEED;
}
if(player->state != CHARACTER_IDLE && player->state != CHARACTER_WALKING)
{
player->roll_progress = 0.0;
player->is_rolling = false;
}
if(player->is_rolling)
{
player->roll_progress += dt;
if(player->roll_progress > anim_sprite_duration(&knight_rolling))
{
player->is_rolling = false;
}
}
cam.pos = LerpV2(cam.pos, dt*8.0f, MulV2F(player->pos, -1.0f * cam.scale)); cam.pos = LerpV2(cam.pos, dt*8.0f, MulV2F(player->pos, -1.0f * cam.scale));
if(player->state == CHARACTER_WALKING) if(player->state == CHARACTER_WALKING)
{ {
player->pos = move_and_slide(player->pos, MulV2F(movement, dt * pixels_per_meter * 4.0f), V2(TILE_SIZE, TILE_SIZE)); if(player->speed <= 0.01f) player->speed = PLAYER_SPEED;
player->speed = Lerp(player->speed, dt * 3.0f, PLAYER_SPEED);
player->pos = move_and_slide(player->pos, MulV2F(movement, dt * pixels_per_meter * player->speed), V2(TILE_SIZE, TILE_SIZE));
if(player->is_rolling)
{
draw_animated_sprite(&knight_rolling, player->roll_progress, player->facing_left, character_sprite_pos, WHITE);
}
else
{
draw_animated_sprite(&knight_running, time, player->facing_left, character_sprite_pos, WHITE); draw_animated_sprite(&knight_running, time, player->facing_left, character_sprite_pos, WHITE);
}
if(LenV2(movement) == 0.0) if(LenV2(movement) == 0.0)
{ {
player->state = CHARACTER_IDLE; player->state = CHARACTER_IDLE;
@ -1060,8 +1133,15 @@ void frame(void)
} }
} }
else if(player->state == CHARACTER_IDLE) else if(player->state == CHARACTER_IDLE)
{
if(player->is_rolling)
{
draw_animated_sprite(&knight_rolling, player->roll_progress, player->facing_left, character_sprite_pos, WHITE);
}
else
{ {
draw_animated_sprite(&knight_idle, time, player->facing_left, character_sprite_pos, WHITE); draw_animated_sprite(&knight_idle, time, player->facing_left, character_sprite_pos, WHITE);
}
if(LenV2(movement) > 0.01) player->state = CHARACTER_WALKING; if(LenV2(movement) > 0.01) player->state = CHARACTER_WALKING;
} }
else if(player->state == CHARACTER_ATTACK) else if(player->state == CHARACTER_ATTACK)

Loading…
Cancel
Save