summary refs log tree commit diff
path: root/src/player.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/player.c')
-rw-r--r--src/player.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/player.c b/src/player.c
new file mode 100644
index 0000000..4eba788
--- /dev/null
+++ b/src/player.c
@@ -0,0 +1,142 @@
+#include "main.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)
+
+enum {
+	PLAYER_IDLE,
+	PLAYER_JUMP,
+	PLAYER_FALL,
+};
+
+#define SIZE 8
+#define ACCELERATION 1
+#define FRICTION 2
+#define MAX_SPEED 12
+#define GRAVITY 1
+
+static int move(struct entity *self) {
+	int dx = (input_right(input_now) - input_left(input_now)) * ACCELERATION;
+	self->velocity.x += dx;
+	if (dx == 0) {
+		if (self->velocity.x < -FRICTION) {
+			self->velocity.x += FRICTION;
+		} else if (self->velocity.x > FRICTION) {
+			self->velocity.x -= FRICTION;
+		} else {
+			self->velocity.x = 0;
+		}
+	}
+	if (self->velocity.x > MAX_SPEED) {
+		self->velocity.x = MAX_SPEED;
+	} else if (self->velocity.x < -MAX_SPEED) {
+		self->velocity.x = -MAX_SPEED;
+	}
+	self->x += self->velocity.x;
+	if (collision_solid(tilemap_area(tilemap, from_fixed(self->x), from_fixed(self->y), from_fixed(self->x) + SIZE, from_fixed(self->y) + SIZE))) {
+		if (self->velocity.x < 0) {
+			self->x += to_fixed(8) - ((self->x) % to_fixed(8)); // left
+		} else if (self->velocity.x == 0) {
+			//fputs("what?\n", stderr);
+		} else {
+			self->x -= ((self->x + to_fixed(SIZE)) % to_fixed(8)); // right
+		}
+		self->velocity.x = 0;
+	}
+	self->velocity.y += GRAVITY;
+	self->y += self->velocity.y;
+	//self->y += (input_down(input_now) - input_up(input_now)) * 8;
+	if (collision_solid(tilemap_area(tilemap, from_fixed(self->x), from_fixed(self->y), from_fixed(self->x) + SIZE, from_fixed(self->y) + SIZE))) {
+		if (self->velocity.y < 0) {
+			self->y += to_fixed(8) - ((self->y) % to_fixed(8)); // up
+			self->velocity.y = 0;
+		} else if (self->velocity.y == 0) {
+			//fputs("what?\n", stderr);
+		} else {
+			self->y -= ((self->y + to_fixed(SIZE)) % to_fixed(8)); // down
+			self->velocity.y = to_fixed(1); // crazy but it works
+			return true;
+		}
+	}
+	return false;
+}
+
+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 {
+				self->state = PLAYER_FALL;
+			}
+			break;
+		
+		case PLAYER_JUMP:
+			if (!input_a(input_now)) {
+				self->velocity.y /= 2;
+				self->state = PLAYER_FALL;
+			}
+			if (self->velocity.y > 0) {
+				self->state = PLAYER_FALL;
+			}
+			if (move(self) == true) {
+				self->state = PLAYER_IDLE;
+			}
+			break;
+		
+		case PLAYER_FALL:
+			if (move(self) == true) {
+				self->state = PLAYER_IDLE;
+			}
+			break;
+	}
+	return 0;
+}
+
+static int player_hurt(struct entity *self, int damage) {
+	return 0;
+}
+
+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});
+	return 0;
+}
+
+struct entity *player_new(void) {
+	player[0] = (struct entity) {
+		.update = player_update,
+		.hurt = player_hurt,
+		.draw = player_draw,
+		.x = 0, .y = 0,
+		.velocity = {.x = 0, .y = 0},
+		.hitbox = {
+			0, 0, 0, 0,
+		},
+		.state = PLAYER_IDLE,
+		.hp = 3,
+		.timer = 0,
+		.texture = NULL,
+		.ext = NULL,
+	};
+	player[0].texture = res_get_texture("fywi").data;
+	return player + 0;
+}
+
+int player_property(struct entity *const restrict self, char const *const restrict property, char const *const restrict value) {
+	if (strcmp(property, "x") == 0) {
+		self->x = to_fixed(atoi(value));
+	} else if (strcmp(property, "y") == 0) {
+		self->y = to_fixed(atoi(value));
+	} else {
+		return 1;
+	}
+	return 0;
+}