diff options
author | zlago | 2024-09-30 10:52:14 +0200 |
---|---|---|
committer | zlago | 2024-09-30 10:52:14 +0200 |
commit | 45512bbc85188e3adb4eda597d0d2fa5530de651 (patch) | |
tree | 3d159b6baad17c828e42f4594353599b879cb2c8 | |
parent | 5ead22e91fe1165f3a9208c0d1c965b3edd104be (diff) |
player animations
-rw-r--r-- | src/entity.h | 28 | ||||
-rw-r--r-- | src/incbin.h | 2 | ||||
-rw-r--r-- | src/loader.h | 2 | ||||
-rw-r--r-- | src/main.h | 21 | ||||
-rw-r--r-- | src/player.c | 107 | ||||
-rw-r--r-- | src/tilemap.h | 1 | ||||
-rw-r--r-- | src/util.h | 2 | ||||
-rw-r--r-- | utl/json2map/main.c | 2 |
8 files changed, 132 insertions, 33 deletions
diff --git a/src/entity.h b/src/entity.h new file mode 100644 index 0000000..5b34bac --- /dev/null +++ b/src/entity.h @@ -0,0 +1,28 @@ +#pragma once + +#include "loader.h" + +struct entity { + int (*update)(struct entity *self); + int (*hurt)(struct entity *self, int damage); + int (*draw)(struct entity *self, int camx, int camy); + int x, y; // unsigned results in a bunch of weird edge cases + struct velocity { + signed x, y; + } velocity; + struct hitbox { + unsigned left, right, top, bottom; + } hitbox; + struct anim { + unsigned frame; + SDL_Rect rect; + unsigned length; + } anim; + unsigned state; + int hp; + int timer; + int iframes; + signed facing; + void *texture; + void *ext; +}; diff --git a/src/incbin.h b/src/incbin.h index 72c149b..d768006 100644 --- a/src/incbin.h +++ b/src/incbin.h @@ -1,3 +1,5 @@ +#pragma once + #if defined(__APPLE__) extern char const game_icon[], game_icon_end[]; #else diff --git a/src/loader.h b/src/loader.h index 6ffb60e..b1563bb 100644 --- a/src/loader.h +++ b/src/loader.h @@ -1,3 +1,5 @@ +#pragma once + typedef char * name_T; struct blob { diff --git a/src/main.h b/src/main.h index 26c4cf1..ad0951f 100644 --- a/src/main.h +++ b/src/main.h @@ -1,23 +1,10 @@ +#pragma once + #include <SDL2/SDL.h> +#include "entity.h" extern SDL_Window *window; extern SDL_Renderer *renderer; extern unsigned input_now; -extern struct entity { - int (*update)(struct entity *self); - int (*hurt)(struct entity *self, int damage); - int (*draw)(struct entity *self, int camx, int camy); - int x, y; // unsigned results in a bunch of weird edge cases - struct velocity { - signed x, y; - } velocity; - struct hitbox { - unsigned left, right, top, bottom; - } hitbox; - unsigned state; - int hp; - int timer; - void *texture; - void *ext; -} player[1]; +extern struct entity player[1]; diff --git a/src/player.c b/src/player.c index 4eba788..9eed3a8 100644 --- a/src/player.c +++ b/src/player.c @@ -1,25 +1,53 @@ #include "main.h" +#include "entity.h" #include "input.h" -#include "loader.h" #include "tilemap.h" #include <stdbool.h> #define from_fixed(a) (a / 16) #define to_fixed(a) (a * 16) +#define SIZE 8 +#define ACCELERATION 1 +#define FRICTION 2 +#define MAX_SPEED 12 +#define GRAVITY 1 +#define JUMP 30 + enum { + PLAYER_NONE, PLAYER_IDLE, + PLAYER_WALK, PLAYER_JUMP, PLAYER_FALL, }; -#define SIZE 8 -#define ACCELERATION 1 -#define FRICTION 2 -#define MAX_SPEED 12 -#define GRAVITY 1 +enum { + PLAYER_A_IDLE, + PLAYER_A_IDLE2, + PLAYER_A_WALK, + PLAYER_A_WALK2, + PLAYER_A_WALK3, + PLAYER_A_WALK4, + PLAYER_A_JUMP, + PLAYER_A_FALL, + PLAYER_A_FALL2, +}; + +struct anim player_anims[] = { + {PLAYER_A_IDLE2, {0, 0, 16, 16}, 300}, + {PLAYER_A_IDLE, {0, 32, 16, 16}, 2}, + {PLAYER_A_WALK2, {0, 0, 16, 16}, 6}, + {PLAYER_A_WALK3, {16, 0, 16, 16}, 6}, + {PLAYER_A_WALK4, {32, 0, 16, 16}, 6}, + {PLAYER_A_WALK, {48, 0, 16, 16}, 6}, + {PLAYER_A_JUMP, {16, 0, 16, 16}, 300}, + {PLAYER_A_FALL2, {32, 0, 16, 16}, 15}, + {PLAYER_A_FALL2, {48, 0, 16, 16}, 15}, +}; static int move(struct entity *self) { + int on_ground = false; int dx = (input_right(input_now) - input_left(input_now)) * ACCELERATION; self->velocity.x += dx; if (dx == 0) { @@ -47,6 +75,11 @@ static int move(struct entity *self) { } self->velocity.x = 0; } + if (self->velocity.x < 0) { + self->facing = -1; + } else if (self->velocity.x > 0) { + self->facing = +1; + } self->velocity.y += GRAVITY; self->y += self->velocity.y; //self->y += (input_down(input_now) - input_up(input_now)) * 8; @@ -59,44 +92,81 @@ static int move(struct entity *self) { } else { self->y -= ((self->y + to_fixed(SIZE)) % to_fixed(8)); // down self->velocity.y = to_fixed(1); // crazy but it works - return true; + on_ground = true; } } - return false; + self->hitbox.left = self->x; + self->hitbox.right = self->x + SIZE; + self->hitbox.top = self->y; + self->hitbox.bottom = self->y + SIZE; + return on_ground; +} + +void anim(struct entity *self, unsigned anim) { + self->anim = player_anims[anim]; } static int player_update(struct entity *self) { switch (self->state) { case PLAYER_IDLE: - if (move(self) == true) { - if (input_a(input_now)) { - self->velocity.y = -30; - self->state = PLAYER_JUMP; - } - } else { + if (move(self) == false) { + anim(self, PLAYER_A_FALL); self->state = PLAYER_FALL; } + if (input_right(input_now) - input_left(input_now)) { + anim(self, PLAYER_A_WALK); + self->state = PLAYER_WALK; + } + if (input_a(input_now)) { + self->velocity.y = -JUMP; + anim(self, PLAYER_A_JUMP); + self->state = PLAYER_JUMP; + } + break; + + case PLAYER_WALK: + if (move(self) == false) { + anim(self, PLAYER_A_FALL); + self->state = PLAYER_FALL; + } + if (!(input_right(input_now) - input_left(input_now))) { + anim(self, PLAYER_A_IDLE); + self->state = PLAYER_IDLE; + } + if (input_a(input_now)) { + self->velocity.y = -JUMP; + anim(self, PLAYER_A_JUMP); + self->state = PLAYER_JUMP; + } break; case PLAYER_JUMP: if (!input_a(input_now)) { self->velocity.y /= 2; + anim(self, PLAYER_A_FALL); self->state = PLAYER_FALL; } if (self->velocity.y > 0) { + anim(self, PLAYER_A_FALL); self->state = PLAYER_FALL; } if (move(self) == true) { + anim(self, PLAYER_A_IDLE); self->state = PLAYER_IDLE; } break; case PLAYER_FALL: if (move(self) == true) { + anim(self, PLAYER_A_IDLE); self->state = PLAYER_IDLE; } break; } + self->anim.length--; + if (self->anim.length == 0) { + anim(self, self->anim.frame); + } return 0; } @@ -106,7 +176,11 @@ static int player_hurt(struct entity *self, int damage) { static int player_draw(struct entity *self, int camX, int camY) { SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); - SDL_RenderCopy(renderer, self->texture, &(SDL_Rect) {0, 0, 16, 16}, &(SDL_Rect) {from_fixed(self->x) - camX - 4, from_fixed(self->y) - camY - 4, 16, 16}); + SDL_Rect rect = self->anim.rect; + if (self->facing == -1) { + rect.y += 16; + } + SDL_RenderCopy(renderer, self->texture, &rect, &(SDL_Rect) {from_fixed(self->x) - camX - 4, from_fixed(self->y) - camY - 4, 16, 16}); return 0; } @@ -123,9 +197,12 @@ struct entity *player_new(void) { .state = PLAYER_IDLE, .hp = 3, .timer = 0, + .facing = 1, + .iframes = 0, .texture = NULL, .ext = NULL, }; + anim(player, PLAYER_A_IDLE); player[0].texture = res_get_texture("fywi").data; return player + 0; } diff --git a/src/tilemap.h b/src/tilemap.h index ae42c9c..0f2bebe 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -1,4 +1,5 @@ #pragma once + #include "collision.h" extern struct tilemap { diff --git a/src/util.h b/src/util.h index 1fe3a9d..9e882fc 100644 --- a/src/util.h +++ b/src/util.h @@ -1,2 +1,4 @@ +#pragma once + void *util_loadFile(FILE *const restrict file, size_t *const restrict outsize); char *util_executableRelativePath(char *path, char *execPath, size_t dirLength); // allocated on the heap diff --git a/utl/json2map/main.c b/utl/json2map/main.c index b298626..684e0ed 100644 --- a/utl/json2map/main.c +++ b/utl/json2map/main.c @@ -72,7 +72,7 @@ struct tilemap_T make_tilemap(cJSON const *const layer, int const wangStart, int int d = (in.tilemap[x + (y + 1) * in.width] - wangStart) >> 4; int e = (in.tilemap[(x + 1) + (y + 1) * in.width] - wangStart) >> 4; int f = b == c && b == d && b == e; - if (f) { + if (f && ((a - wangStart) & 0x8)) { out.tilemap[x + y * out.width] = b + 0xf0; } else { out.tilemap[x + y * out.width] = 0; |