aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/player.h31
-rw-r--r--src/player.c195
2 files changed, 144 insertions, 82 deletions
diff --git a/include/player.h b/include/player.h
index f77de50..99a3ce9 100644
--- a/include/player.h
+++ b/include/player.h
@@ -1,24 +1,33 @@
-#ifndef PLAYER_H
-#define PLAYER_H
+#pragma once
-#include "map_manager.h"
#include "raylib.h"
+#include "raytmx.h"
-typedef struct Player {
+#include "map.h"
+
+typedef enum { PLAYER_IDLE, PLAYER_WALK, PLAYER_ATTACK } PlayerState;
+
+typedef struct {
+ int potions;
+ int bombs;
+ int currency;
+} Inventory;
+
+typedef struct {
Vector2 position;
float speed;
Rectangle bounds;
-
- // Animation state
+
TmxTileset tileset;
int currentFrame;
float frameTime;
- int state; // 0: idle, 1: walk, etc.
+ PlayerState state;
bool facingRight;
+ int health;
+ int maxHealth;
+ Inventory inventory;
} Player;
-void UpdatePlayer(Player *p, MapManager *mapMgr);
-void DrawPlayer(Player *p);
-
-#endif
+void UpdatePlayer(Player *player, Map *map, struct Entities *entities);
+void DrawPlayer(Player *player);
diff --git a/src/player.c b/src/player.c
index f25c1fc..ba342ae 100644
--- a/src/player.c
+++ b/src/player.c
@@ -1,106 +1,159 @@
#include "player.h"
+#include "entities.h"
+#include "raylib.h"
#include "raymath.h"
-#include "globals.h"
-void UpdatePlayer(Player *p, MapManager *mapMgr) {
- Vector2 move = {0};
- if (IsKeyDown(KEY_W)) move.y -= 1;
- if (IsKeyDown(KEY_S)) move.y += 1;
- if (IsKeyDown(KEY_A)) move.x -= 1;
- if (IsKeyDown(KEY_D)) move.x += 1;
-
- int newState = (Vector2Length(move) > 0) ? 1 : 0;
- bool newFacingRight = p->facingRight;
- if (move.x > 0) newFacingRight = true;
- else if (move.x < 0) newFacingRight = false;
-
- if (newState != p->state || newFacingRight != p->facingRight) {
- p->state = newState;
- p->facingRight = newFacingRight;
- p->currentFrame = 0;
- p->frameTime = 0;
- }
+Vector2 GetInputVector() {
+ Vector2 input = {0};
+ if (IsKeyDown(KEY_W))
+ input.y -= 1;
+ if (IsKeyDown(KEY_S))
+ input.y += 1;
+ if (IsKeyDown(KEY_A))
+ input.x -= 1;
+ if (IsKeyDown(KEY_D))
+ input.x += 1;
+ return input;
+}
- // Update bounds based on current position (Feet hitbox: 8x6 centered horizontally, offset bottom)
- p->bounds = (Rectangle){ p->position.x - 4, p->position.y + 2, 8, 6 };
+static void CollectPickups(Player *player, Entities *entities) {
+ for (int i = 0; i < entities->pickupsCount; i++) {
+ Pickup *p = &entities->pickups[i];
+ if (!p->active)
+ continue;
+ if (!CheckCollisionRecs(player->bounds, p->bounds))
+ continue;
- if (Vector2Length(move) > 0) {
- move = Vector2Scale(Vector2Normalize(move), p->speed * GetFrameTime());
-
- // Try moving X
- Rectangle nextX = p->bounds;
- nextX.x += move.x;
- if (!IsWallCollision(mapMgr, nextX)) {
- p->position.x += move.x;
- p->bounds.x += move.x;
+ switch (p->type) {
+ case PICKUP_FULL_HEART:
+ if (player->health >= player->maxHealth)
+ continue;
+ player->health = Clamp(player->health + 2, 0, player->maxHealth);
+ break;
+ case PICKUP_HALF_HEART:
+ if (player->health >= player->maxHealth)
+ continue;
+ player->health = Clamp(player->health + 1, 0, player->maxHealth);
+ break;
+ case PICKUP_COIN:
+ player->inventory.currency += 1;
+ break;
+ case PICKUP_GOLD_NUGGET:
+ player->inventory.currency += 5;
+ break;
+ case PICKUP_GOLD_BAR:
+ player->inventory.currency += 10;
+ break;
+ case PICKUP_POTION:
+ player->inventory.potions += 1;
+ break;
+ case PICKUP_BOMB:
+ player->inventory.bombs += 1;
+ break;
}
- // Try moving Y
- Rectangle nextY = p->bounds;
- nextY.y += move.y;
- if (!IsWallCollision(mapMgr, nextY)) {
- p->position.y += move.y;
- p->bounds.y += move.y;
- }
+ p->active = false;
}
+}
- // Determine base tile ID from tileset for current animation
+void AnimatePlayer(Player *player) {
int baseTileId = 0;
- if (p->state == 0) baseTileId = p->facingRight ? 0 : 7;
- else if (p->state == 1) baseTileId = p->facingRight ? 14 : 21;
+ if (player->state == 0)
+ baseTileId = player->facingRight ? 0 : 7;
+ else if (player->state == 1)
+ baseTileId = player->facingRight ? 14 : 21;
- // Animation Update using Tiled metadata
TmxTilesetTile *tileData = NULL;
- for (uint32_t i = 0; i < p->tileset.tilesLength; i++) {
- if (p->tileset.tiles[i].id == (uint32_t)baseTileId) {
- tileData = &p->tileset.tiles[i];
+ for (uint32_t i = 0; i < player->tileset.tilesLength; i++) {
+ if (player->tileset.tiles[i].id == (uint32_t)baseTileId) {
+ tileData = &player->tileset.tiles[i];
break;
}
}
if (tileData && tileData->hasAnimation) {
- p->frameTime += GetFrameTime(); // raytmx stores durations in seconds
- float duration = tileData->animation.frames[p->currentFrame].duration;
- if (p->frameTime >= duration) {
- p->frameTime -= duration;
- p->currentFrame = (p->currentFrame + 1) % tileData->animation.framesLength;
+ player->frameTime += GetFrameTime(); // raytmx stores durations in seconds
+ float duration = tileData->animation.frames[player->currentFrame].duration;
+ if (player->frameTime >= duration) {
+ player->frameTime -= duration;
+ player->currentFrame =
+ (player->currentFrame + 1) % tileData->animation.framesLength;
+ }
+ }
+}
+
+void UpdatePlayer(Player *player, Map *map, struct Entities *entities) {
+ Vector2 move = GetInputVector();
+
+ PlayerState newState = (Vector2Length(move) > 0) ? PLAYER_WALK : PLAYER_IDLE;
+ bool newFacingRight = player->facingRight;
+ if (move.x > 0)
+ newFacingRight = true;
+ else if (move.x < 0)
+ newFacingRight = false;
+
+ if (newState != player->state || newFacingRight != player->facingRight) {
+ player->state = newState;
+ player->facingRight = newFacingRight;
+ player->currentFrame = 0;
+ player->frameTime = 0;
+ }
+
+ if (Vector2Length(move) > 0) {
+ move = Vector2Scale(Vector2Normalize(move), player->speed * GetFrameTime());
+
+ Rectangle nextX = player->bounds;
+ nextX.x += move.x;
+
+ if (!isCollision(map, nextX)) {
+ player->position.x += move.x;
+ player->bounds.x += move.x;
+ }
+
+ Rectangle nextY = player->bounds;
+ nextY.y += move.y;
+
+ if (!isCollision(map, nextY)) {
+ player->position.y += move.y;
+ player->bounds.y += move.y;
}
}
+
+ if (entities)
+ CollectPickups(player, entities);
+
+ AnimatePlayer(player);
}
-void DrawPlayer(Player *p) {
+void DrawPlayer(Player *player) {
int baseTileId = 0;
- if (p->state == 0) baseTileId = p->facingRight ? 0 : 7;
- else if (p->state == 1) baseTileId = p->facingRight ? 14 : 21;
+ if (player->state == 0)
+ baseTileId = player->facingRight ? 0 : 7;
+ else if (player->state == 1)
+ baseTileId = player->facingRight ? 14 : 21;
TmxTilesetTile *tileData = NULL;
- for (uint32_t i = 0; i < p->tileset.tilesLength; i++) {
- if (p->tileset.tiles[i].id == (uint32_t)baseTileId) {
- tileData = &p->tileset.tiles[i];
+ for (uint32_t i = 0; i < player->tileset.tilesLength; i++) {
+ if (player->tileset.tiles[i].id == (uint32_t)baseTileId) {
+ tileData = &player->tileset.tiles[i];
break;
}
}
int displayTileId = baseTileId;
if (tileData && tileData->hasAnimation) {
- displayTileId = tileData->animation.frames[p->currentFrame].gid;
+ displayTileId = tileData->animation.frames[player->currentFrame].gid;
}
- // Calculate source rectangle from tile ID
- int col = displayTileId % p->tileset.columns;
- int row = displayTileId / p->tileset.columns;
+ int col = displayTileId % player->tileset.columns;
+ int row = displayTileId / player->tileset.columns;
- Rectangle source = {
- (float)(col * TILE_SIZE),
- (float)(row * TILE_SIZE),
- (float)TILE_SIZE,
- (float)TILE_SIZE
- };
-
- Vector2 pos = { p->position.x - (float)TILE_SIZE / 2.0f, p->position.y - (float)TILE_SIZE / 2.0f };
- DrawTextureRec(p->tileset.image.texture, source, pos, WHITE);
+ Rectangle source = {(float)(col * player->tileset.tileWidth),
+ (float)(row * player->tileset.tileHeight),
+ (float)player->tileset.tileWidth,
+ (float)player->tileset.tileHeight};
- if (debugMode) {
- DrawRectangleLinesEx(p->bounds, 1, GREEN);
- }
+ Vector2 pos = {player->position.x - (float)player->tileset.tileWidth / 2.0f,
+ player->position.y - (float)player->tileset.tileHeight / 2.0f};
+ DrawTextureRec(player->tileset.image.texture, source, pos, WHITE);
}