Entity array, codegen all object spawnpoints

main
Cameron Murphy Reikes 2 years ago
parent 639f6fb4c9
commit 1ee06fa381

@ -14,6 +14,10 @@
{ {
filepath: "_Attack.png", filepath: "_Attack.png",
} }
@image old_man:
{
filepath: "small_old_man.png",
}
@image animated_terrain: @image animated_terrain:
{ {
filepath: "copyrighted/animated_terrain.png", filepath: "copyrighted/animated_terrain.png",

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

@ -114,6 +114,7 @@ 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));
@ -180,11 +181,10 @@ int main(int argc, char **argv) {
if(MD_S8Match(type, MD_S8Lit("objectgroup"), 0)) { if(MD_S8Match(type, MD_S8Lit("objectgroup"), 0)) {
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);
if(MD_S8Match(MD_ChildFromString(object, MD_S8Lit("name"), 0)->first_child->string, MD_S8Lit("spawn"), 0)) { 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;
fprintf(output, ".spawnpoint = { %.*s, %.*s },\n", MD_S8VArg(x_string), MD_S8VArg(y_string)); list_printf(&object_decls_list, "Vec2 %.*s_tilepoint = { %.*s, %.*s };\n", MD_S8VArg(name), MD_S8VArg(x_string), MD_S8VArg(y_string));
}
} }
} }
if(MD_S8Match(type, MD_S8Lit("tilelayer"), 0)) { if(MD_S8Match(type, MD_S8Lit("tilelayer"), 0)) {
@ -215,9 +215,10 @@ 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", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join))); fprintf(output, "%.*s\n%.*s\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join)), MD_S8VArg(object_declarations));
fclose(output); fclose(output);
return 0; return 0;

108
main.c

@ -16,6 +16,8 @@
#include <math.h> #include <math.h>
#define ARRLEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
typedef struct AABB typedef struct AABB
{ {
Vec2 upper_left; Vec2 upper_left;
@ -137,6 +139,13 @@ 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 );
} }
// points from tiled editor have their own strange and alien coordinate system (local to the tilemap Y+ down)
Vec2 tilepoint_to_world(Vec2 tilepoint)
{
Vec2 tilecoord = MulV2F(tilepoint, 1.0/TILE_SIZE);
return tilecoord_to_world((TileCoord){(int)tilecoord.X, (int)tilecoord.Y});
}
TileCoord world_to_tilecoord(Vec2 w) TileCoord world_to_tilecoord(Vec2 w)
{ {
// world = V2(tilecoord.x * tile_size, -tilecoord.y * tile_size) // world = V2(tilecoord.x * tile_size, -tilecoord.y * tile_size)
@ -251,6 +260,16 @@ AnimatedSprite knight_attack =
.no_wrap = true, .no_wrap = true,
}; };
AnimatedSprite old_man_idle =
{
.img = &image_old_man,
.time_per_frame = 0.4,
.num_frames = 4,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 16.0f,
.region_size = {16.0f, 16.0f},
};
sg_image image_font = {0}; sg_image image_font = {0};
const float font_size = 32.0; const float font_size = 32.0;
stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
@ -272,17 +291,44 @@ typedef enum CharacterState
CHARACTER_ATTACK, CHARACTER_ATTACK,
} CharacterState; } CharacterState;
typedef struct Character typedef enum EntityKind
{ {
CharacterState state; Player,
OldMan,
} EntityKind;
typedef struct Entity
{
bool exists;
EntityKind kind;
Vec2 pos; Vec2 pos;
bool facing_left; bool facing_left;
// swinging // character
CharacterState state;
double swing_progress; double swing_progress;
} Character;
Character player = {0}; } Entity;
Entity entities[128] = {0};
Entity *player = NULL;
Entity *new_entity()
{
for(int i = 0; i < ARRLEN(entities); i++)
{
if(!entities[i].exists)
{
Entity *to_return = &entities[i];
*to_return = (Entity){0};
to_return->exists = true;
return to_return;
}
}
assert(false);
return NULL;
}
void init(void) void init(void)
{ {
@ -294,9 +340,8 @@ void init(void)
load_assets(); load_assets();
// player spawnpoint player = new_entity();
Vec2 spawnpoint_tilecoord = MulV2F(level_level0.spawnpoint, 1.0/TILE_SIZE); player->pos = tilepoint_to_world(spawn_tilepoint);
player.pos = tilecoord_to_world((TileCoord){(int)spawnpoint_tilecoord.X, (int)spawnpoint_tilecoord.Y});
// load font // load font
{ {
@ -555,8 +600,7 @@ bool overlapping(AABB a, AABB b)
return true; // both segments overlapping return true; // both segments overlapping
} }
// points must be of length 4, and be in the order: upper left, upper right, lower right, lower left // The image region is in pixel space of the image
// the points are in pixels in screen space. The image region is in pixel space of the image
void draw_quad(bool world_space, Quad quad, sg_image image, AABB image_region, Color tint) void draw_quad(bool world_space, Quad quad, sg_image image, AABB image_region, Color tint)
{ {
Vec2 *points = quad.points; Vec2 *points = quad.points;
@ -597,6 +641,7 @@ void draw_quad(bool world_space, Quad quad, sg_image image, AABB image_region, C
AddV2(image_region.upper_left, V2(region_size.X, region_size.Y)), AddV2(image_region.upper_left, V2(region_size.X, region_size.Y)),
AddV2(image_region.upper_left, V2(0.0, region_size.Y)), AddV2(image_region.upper_left, V2(0.0, region_size.Y)),
}; };
// convert to uv space // convert to uv space
sg_image_info info = sg_query_image_info(image); sg_image_info info = sg_query_image_info(image);
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
@ -935,7 +980,7 @@ void frame(void)
} }
#endif #endif
//if(LengthV2(movement) > 0.01 && player.state == CHARACTER_) //if(LengthV2(movement) > 0.01 && player->state == CHARACTER_)
#ifdef DEVTOOLS #ifdef DEVTOOLS
dbgsquare(screen_to_world(mouse_pos)); dbgsquare(screen_to_world(mouse_pos));
@ -950,7 +995,7 @@ void frame(void)
// line test // line test
{ {
dbgline(player.pos, screen_to_world(mouse_pos)); dbgline(player->pos, screen_to_world(mouse_pos));
} }
// debug draw font image // debug draw font image
@ -973,7 +1018,7 @@ void frame(void)
#if 0 #if 0
const char *text = "great idea\nother idea"; const char *text = "great idea\nother idea";
// measure text // measure text
Vec2 pos = player.pos; Vec2 pos = player->pos;
{ {
AABB bounds = draw_text(true, true, text, strlen(text), pos, WHITE); AABB bounds = draw_text(true, true, text, strlen(text), pos, WHITE);
@ -988,43 +1033,44 @@ void frame(void)
#endif // devtools #endif // devtools
draw_animated_sprite(&old_man_idle, time, false, V2(884.788635f, -928.000000f), WHITE);
// player character // player character
{ {
Vec2 character_sprite_pos = AddV2(player.pos, V2(0.0, 20.0f)); Vec2 character_sprite_pos = AddV2(player->pos, V2(0.0, 20.0f));
if(attack && (player.state == CHARACTER_IDLE || player.state == CHARACTER_WALKING)) if(attack && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING))
{ {
player.state = CHARACTER_ATTACK; player->state = CHARACTER_ATTACK;
player.swing_progress = 0.0; player->swing_progress = 0.0;
} }
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)); player->pos = move_and_slide(player->pos, MulV2F(movement, dt * pixels_per_meter * 4.0f), V2(TILE_SIZE, TILE_SIZE));
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;
} }
else else
{ {
player.facing_left = movement.X < 0.0f; player->facing_left = movement.X < 0.0f;
} }
} }
else if(player.state == CHARACTER_IDLE) else if(player->state == CHARACTER_IDLE)
{ {
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)
{ {
player.swing_progress += dt; player->swing_progress += dt;
draw_animated_sprite(&knight_attack, player.swing_progress, player.facing_left, character_sprite_pos, WHITE); draw_animated_sprite(&knight_attack, player->swing_progress, player->facing_left, character_sprite_pos, WHITE);
if(player.swing_progress > anim_sprite_duration(&knight_attack)) if(player->swing_progress > anim_sprite_duration(&knight_attack))
{ {
player.state = CHARACTER_IDLE; player->state = CHARACTER_IDLE;
} }
} }
} }

Loading…
Cancel
Save