Spawnpoint and animated sprites

main
parent 8b7ad42e79
commit fa3f9865aa

@ -2,6 +2,14 @@
{ {
filepath: "copyrighted/merchant.png", filepath: "copyrighted/merchant.png",
} }
@image knight_idle:
{
filepath: "_Idle.png",
}
@image knight_run:
{
filepath: "_Run.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: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -174,25 +174,42 @@ int main(int argc, char **argv) {
assert(level_parse.node != 0, MD_S8Lit("Failed to load level file")); assert(level_parse.node != 0, 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);
int width = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("width"), 0)->first_child->string)); fprintf(output, "Level %.*s = {\n", MD_S8VArg(variable_name));
int height = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("height"), 0)->first_child->string)); for(MD_EachNode(lay, layers->first_child)) {
MD_Node *data = MD_ChildFromString(layers->first_child, MD_S8Lit("data"), 0); MD_String8 type = MD_ChildFromString(lay, MD_S8Lit("type"), 0)->first_child->string;
if(MD_S8Match(type, MD_S8Lit("objectgroup"), 0)) {
fprintf(output, "Level %.*s = {\n.tiles = {\n", MD_S8VArg(variable_name)); for(MD_EachNode(object, MD_ChildFromString(lay, MD_S8Lit("objects"), 0)->first_child)) {
int num_index = 0; dump(object);
fprintf(output, "{ "); if(MD_S8Match(MD_ChildFromString(object, MD_S8Lit("name"), 0)->first_child->string, MD_S8Lit("spawn"), 0)) {
for(MD_EachNode(tile_id_node, data->first_child)) { MD_String8 x_string = MD_ChildFromString(object, MD_S8Lit("x"), 0)->first_child->string;
fprintf(output, "%.*s, ", MD_S8VArg(tile_id_node->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));
if(num_index % width == width - 1) { }
if(MD_NodeIsNil(tile_id_node->next)) { }
fprintf(output, "},\n}\n}; // %.*s\n", MD_S8VArg(variable_name)); }
} else { if(MD_S8Match(type, MD_S8Lit("tilelayer"), 0)) {
fprintf(output, "},\n{ "); int width = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("width"), 0)->first_child->string));
int height = atoi(nullterm(MD_ChildFromString(layers->first_child, MD_S8Lit("height"), 0)->first_child->string));
MD_Node *data = MD_ChildFromString(layers->first_child, MD_S8Lit("data"), 0);
int num_index = 0;
fprintf(output, ".tiles = {\n");
fprintf(output, "{ ");
for(MD_EachNode(tile_id_node, data->first_child)) {
fprintf(output, "%.*s, ", MD_S8VArg(tile_id_node->string));
if(num_index % width == width - 1) {
if(MD_NodeIsNil(tile_id_node->next)) {
fprintf(output, "},\n},\n");
} else {
fprintf(output, "},\n{ ");
}
}
num_index += 1;
} }
} }
num_index += 1;
} }
fprintf(output, "\n}; // %.*s\n", MD_S8VArg(variable_name));
} }
} }

@ -36,10 +36,21 @@ typedef struct TileSet {
AnimatedTile animated[128]; AnimatedTile animated[128];
} TileSet; } TileSet;
typedef struct AnimatedSprite {
sg_image *img;
double time_per_frame;
int num_frames;
HMM_Vec2 start;
float horizontal_diff_btwn_frames;
HMM_Vec2 region_size;
} AnimatedSprite;
#define LEVEL_TILES 60 #define LEVEL_TILES 60
#define TILE_SIZE 32 // in pixels #define TILE_SIZE 32 // in pixels
typedef struct Level { typedef struct Level {
TileInstance tiles[LEVEL_TILES][LEVEL_TILES]; TileInstance tiles[LEVEL_TILES][LEVEL_TILES];
HMM_Vec2 spawnpoint;
} Level; } Level;
HMM_Vec2 tilecoord_to_world(int x, int y) { HMM_Vec2 tilecoord_to_world(int x, int y) {
@ -74,6 +85,24 @@ sg_image load_image(const char *path) {
#include "quad-sapp.glsl.h" #include "quad-sapp.glsl.h"
#include "assets.gen.c" #include "assets.gen.c"
AnimatedSprite knight_idle = {
.img = &image_knight_idle,
.time_per_frame = 0.3,
.num_frames = 10,
.start = {16.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0,
.region_size = {80.0f, 80.0f},
};
AnimatedSprite knight_running = {
.img = &image_knight_run,
.time_per_frame = 0.06,
.num_frames = 10,
.start = {19.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0,
.region_size = {80.0f, 80.0f},
};
sg_image image_font = {0}; sg_image image_font = {0};
const float font_size = 64.0; const float font_size = 64.0;
stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
@ -87,6 +116,8 @@ static struct {
sg_bindings bind; sg_bindings bind;
} state; } state;
HMM_Vec2 character_pos = {0}; // world space point
void init(void) { void init(void) {
stm_setup(); stm_setup();
sg_setup(&(sg_desc){ sg_setup(&(sg_desc){
@ -95,6 +126,10 @@ void init(void) {
load_assets(); load_assets();
// player spawnpoint
HMM_Vec2 spawnpoint_tilecoord = HMM_MulV2F(level_level0.spawnpoint, 1.0/TILE_SIZE);
character_pos = tilecoord_to_world((int)spawnpoint_tilecoord.X, (int)spawnpoint_tilecoord.Y);
// load font // load font
{ {
FILE* fontFile = fopen("assets/orange kid.ttf", "rb"); FILE* fontFile = fopen("assets/orange kid.ttf", "rb");
@ -172,7 +207,10 @@ void init(void) {
}); });
state.pass_action = (sg_pass_action) { state.pass_action = (sg_pass_action) {
.colors[0] = { .action=SG_ACTION_CLEAR, .value={12.5f/255.0f, 12.5f/255.0f, 12.5f/255.0f, 1.0f } } //.colors[0] = { .action=SG_ACTION_CLEAR, .value={12.5f/255.0f, 12.5f/255.0f, 12.5f/255.0f, 1.0f } }
//.colors[0] = { .action=SG_ACTION_CLEAR, .value={255.5f/255.0f, 255.5f/255.0f, 255.5f/255.0f, 1.0f } }
// 0x898989 is the color in tiled
.colors[0] = { .action=SG_ACTION_CLEAR, .value={137.0f/255.0f, 137.0f/255.0f, 137.0f/255.0f, 1.0f } }
}; };
} }
@ -354,6 +392,31 @@ void draw_quad(bool world_space, HMM_Vec2 *points_in, sg_image image, AABB image
sg_draw(0, 6, 1); sg_draw(0, 6, 1);
} }
void swap(HMM_Vec2 *p1, HMM_Vec2 *p2) {
HMM_Vec2 tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void draw_animated_sprite(AnimatedSprite *s, double time, bool flipped, HMM_Vec2 pos, Color tint) {
sg_image spritesheet_img = *s->img;
int index = (int)floor(time/s->time_per_frame) % s->num_frames;
HMM_Vec2 points[4] = {0};
quad_points_centered_size(points, pos, s->region_size);
if(flipped) {
swap(&points[0], &points[1]);
swap(&points[3], &points[2]);
}
AABB region;
region.upper_left = HMM_AddV2(s->start, HMM_V2(index * s->horizontal_diff_btwn_frames, 0.0f));
region.lower_right = HMM_V2(region.upper_left.X + (float)s->region_size.X, (float)s->region_size.Y);
draw_quad(true, points, spritesheet_img, region, tint);
}
void colorbox(bool world_space, HMM_Vec2 upper_left, HMM_Vec2 lower_right, Color color) { void colorbox(bool world_space, HMM_Vec2 upper_left, HMM_Vec2 lower_right, Color color) {
HMM_Vec2 size = HMM_SubV2(lower_right, upper_left); HMM_Vec2 size = HMM_SubV2(lower_right, upper_left);
@ -443,7 +506,7 @@ double time = 0.0;
double last_frame_processing_time = 0.0; double last_frame_processing_time = 0.0;
uint64_t last_frame_time; uint64_t last_frame_time;
HMM_Vec2 mouse_pos = {0}; // in screen space HMM_Vec2 mouse_pos = {0}; // in screen space
HMM_Vec2 character_pos = {0}; // world space point bool character_facing_left = false;
bool keydown[SAPP_KEYCODE_MENU] = {0}; bool keydown[SAPP_KEYCODE_MENU] = {0};
#ifdef DEVTOOLS #ifdef DEVTOOLS
bool mouse_frozen = false; bool mouse_frozen = false;
@ -551,22 +614,14 @@ void frame(void) {
} }
#endif #endif
#endif #endif // devtools
// merchant if(HMM_LenV2(movement) > 0.01) {
int index = (int)floor(time/0.3); character_facing_left = movement.X < 0.0;
float size = img_size(image_merchant).Y; draw_animated_sprite(&knight_running, time, character_facing_left, character_pos, WHITE);
HMM_Vec2 points[4] = {0}; } else {
quad_points_centered_size(points, character_pos, HMM_V2(size, size)); draw_animated_sprite(&knight_idle, time, character_facing_left, character_pos, WHITE);
}
int cell_size = 110;
assert((int)img_size(image_merchant).X % cell_size == 0);
AABB region;
region.upper_left = HMM_V2( (float)((index % ((int)img_size(image_merchant).X/cell_size)) * cell_size), 0.0);
region.lower_right = HMM_V2(region.upper_left.X + (float)cell_size, (float)cell_size);
draw_quad(true, points, image_merchant, region, WHITE);
sg_end_pass(); sg_end_pass();
sg_commit(); sg_commit();

Loading…
Cancel
Save