summary refs log tree commit diff
diff options
context:
space:
mode:
authorzlago2024-09-30 10:52:14 +0200
committerzlago2024-09-30 10:52:14 +0200
commit45512bbc85188e3adb4eda597d0d2fa5530de651 (patch)
tree3d159b6baad17c828e42f4594353599b879cb2c8
parent5ead22e91fe1165f3a9208c0d1c965b3edd104be (diff)
player animations
-rw-r--r--src/entity.h28
-rw-r--r--src/incbin.h2
-rw-r--r--src/loader.h2
-rw-r--r--src/main.h21
-rw-r--r--src/player.c107
-rw-r--r--src/tilemap.h1
-rw-r--r--src/util.h2
-rw-r--r--utl/json2map/main.c2
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;