summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBoredGuy <osome3717@gmail.com>2025-08-26 12:33:32 +0300
committerBoredGuy <osome3717@gmail.com>2025-08-26 12:33:32 +0300
commit87d07175058ee4ae18fce608de81c68d7d9bb178 (patch)
tree1eb459ff40aded29f6433bcd413d47ff870fd4e0 /src
parent978c543891af8dbe9e95b27c4e2c46645d45138c (diff)
Player Improvements
Diffstat (limited to 'src')
-rw-r--r--src/assets.c21
-rw-r--r--src/game.c42
-rw-r--r--src/main.c6
-rw-r--r--src/player.c111
4 files changed, 151 insertions, 29 deletions
diff --git a/src/assets.c b/src/assets.c
index b08201a..f6d4792 100644
--- a/src/assets.c
+++ b/src/assets.c
@@ -19,6 +19,11 @@ Asset assets[] = {
.type = Texture_Asset,
.name = "human-shadow",
.filePath = "assets/art/characters/shadow.png"
+ },
+ {
+ .type = Texture_Asset,
+ .name = "player-body",
+ .filePath = "assets/art/characters/player.png"
}
};
@@ -32,6 +37,11 @@ void LoadAssets() {
switch (c->type) {
case Texture_Asset:
c->texture = LoadTexture(c->filePath);
+
+ if (c->texture.id == 0) {
+ TraceLog(LOG_ERROR, "Failed to load texture %s, exitting!", c->filePath);
+ exit(EXIT_FAILURE);
+ }
break;
default:
@@ -51,6 +61,17 @@ Asset* GetMatchingAssetWithType(const char* targetName, AssetType targetType) {
return NULL;
}
+Asset* GetMatchingAssetExitOnFail(const char* targetName, AssetType targetType) {
+ Asset* matchingAsset = GetMatchingAssetWithType(targetName, targetType);
+
+ if (!matchingAsset) {
+ TraceLog(LOG_ERROR, "Failed to load asset %s, exitting!", targetName);
+ exit(EXIT_FAILURE);
+ }
+
+ return matchingAsset;
+}
+
void UnloadAssets() {
for (size_t i = 0; i < ASSET_COUNT; i++) {
Asset* c = &assets[i];
diff --git a/src/game.c b/src/game.c
index 4a10830..d6e8ce3 100644
--- a/src/game.c
+++ b/src/game.c
@@ -87,6 +87,12 @@ void DrawEntitySprite(const Entity* e, int spriteIndex) {
float rotation = 0.0f;
Rectangle destRect = GetSpriteDrawDestinationRectGlobal(e, spriteIndex);
+ if (drawnSprite->flipX)
+ srcRect.width = -srcRect.width;
+
+ if (drawnSprite->flipY)
+ srcRect.height = -srcRect.width;
+
DrawTexturePro(drawnSprite->texture, srcRect, destRect, origin, rotation, WHITE);
}
@@ -193,3 +199,39 @@ void UpdateCurrentSpriteAnimation(Sprite* sprite, float dt) {
}
}
}
+
+Rectangle GetSrcRectFromIndex(Texture texture, int framesX, int framesY, int index) {
+ const float frameWidth = (float)texture.width / framesX;
+ const float frameHeight = (float)texture.height / framesY;
+
+ return (Rectangle) {
+ .x = (index % framesY) * frameWidth,
+ .y = (index / framesY) * frameHeight,
+ .width = frameWidth,
+ .height = frameHeight
+ };
+}
+
+Animation AnimationFromIndices(AnimationFromIndicesParams params) {
+ int numFrames = params.numFrames;
+ bool isLooping = params.isLooping;
+ Texture texture = params.texture;
+ int framesX = params.framesX;
+ int framesY = params.framesY;
+ int* indices = params.indices;
+ float* frameTimes = params.frameTimes;
+
+ Animation animation = (Animation) {
+ .numFrames = numFrames,
+ .isLooping = isLooping,
+
+ .currentFrame = 0
+ };
+
+ for (int i = 0; i < numFrames; i++) {
+ animation.srcRects[i] = GetSrcRectFromIndex(texture, framesX, framesY, indices[i]);
+ animation.frameTimes[i] = frameTimes[i];
+ }
+
+ return animation;
+}
diff --git a/src/main.c b/src/main.c
index 317b51c..f5be59f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,14 +7,14 @@
int main() {
InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "My BeatEmup");
- SetTargetFPS(60);
+ SetTargetFPS(120);
LoadAssets();
InitGame();
AddBackground("bar-background");
- AddPlayer(0, 0);
- AddWall(100, 100, 1000, 100);
+ AddPlayer(0, 400);
+ AddWall(0, 160, 1000000, 100);
while(!WindowShouldClose()) {
UpdateGame(GetFrameTime());
diff --git a/src/player.c b/src/player.c
index 9340ffd..ca5d3c0 100644
--- a/src/player.c
+++ b/src/player.c
@@ -3,27 +3,22 @@
#include "constants.h"
#include "game.h"
#include "player.h"
+#include "player_data.h"
#include "physics.h"
#include "assets.h"
#include "utils.h"
extern Game game;
-#define PLAYER_SPEED 300.0f
-
-const Rectangle shadowDestRect = (Rectangle) {
- .x = 0,
- .y = 100,
- .width = 100,
- .height = 40
-};
+static void AddPlayerSprites(Entity* player);
+static inline Sprite* GetBodySprite(Entity* player) {
+ return &player->sprites[player->bodySpriteIndex];
+}
-const Rectangle physicsCollider = (Rectangle) {
- .x = 0,
- .y = 0,
- .width = 100,
- .height = 100
-};
+typedef enum PlayerStates {
+ PLAYER_IDLE = 0,
+ PLAYER_WALKING = 1,
+} PlayerStates;
Vector2 GetMovementDirection() {
Vector2 movementDirection = {0.0f, 0.0f};
@@ -51,13 +46,33 @@ void CameraFollow(const Entity* player) {
(Vector2) {fmaxf(WINDOW_WIDTH / 2.0f, player->position.x), 0.0f};
}
+void UpdateAnimationState(Entity* player) {
+ Sprite* bodySprite = GetBodySprite(player);
+
+ if (Vector2Length(player->velocity) > 0.0)
+ bodySprite->currentAnimation = PLAYER_WALKING;
+ else
+ bodySprite->currentAnimation = PLAYER_IDLE;
+}
+
+void UpdateBodyFacing(Entity* player) {
+ Sprite* bodySprite = GetBodySprite(player);
+
+ if (player->velocity.x < 0)
+ bodySprite->flipX = true;
+ else if (player->velocity.x > 0)
+ bodySprite->flipX = false;
+}
+
void UpdatePlayer(Entity* player, float deltaTime) {
player->velocity =
Vector2Scale(GetMovementDirection(), PLAYER_SPEED);
+ UpdateAnimationState(player);
+ UpdateBodyFacing(player);
MoveAndSlide(player, deltaTime);
-
CameraFollow(player);
+ UpdateCurrentSpriteAnimation(GetBodySprite(player), deltaTime);
}
void AddPlayer(float xpos, float ypos) {
@@ -73,18 +88,62 @@ void AddPlayer(float xpos, float ypos) {
player.physicsColliderColor = RED;
#endif
- Asset* shadowTexture = GetMatchingAssetWithType("human-shadow", Texture_Asset);
+ AddPlayerSprites(&player);
+ AddEntity(&player);
+}
- if (shadowTexture == NULL) {
- TraceLog(LOG_ERROR, "Failed to find texture asset human-shadow, exitting!");
- exit(EXIT_FAILURE);
- }
+static void AddPlayerSprites(Entity* player) {
+ Asset* shadowTexture = GetMatchingAssetExitOnFail("human-shadow", Texture_Asset);
- AddSpriteToEntity(&player, (Sprite){
- .texture = shadowTexture->texture,
- .layer = Foreground_Layer,
- .destRect = shadowDestRect
- });
+ Sprite shadowSprite = (Sprite) {
+ .texture = shadowTexture->texture,
+ .layer = Foreground_Layer,
+ .destRect = shadowDestRect,
- AddEntity(&player);
+ .numAnimations = 0, //Not an animated sprite
+ };
+ AddSpriteToEntity(player, shadowSprite);
+
+ Asset* bodyTexture = GetMatchingAssetExitOnFail("player-body", Texture_Asset);
+
+ Sprite bodySprite = (Sprite) {
+ .texture = bodyTexture->texture,
+ .layer = Foreground_Layer,
+
+ .destRect = bodyDestRect,
+ .numAnimations = 0
+ };
+
+ //The body texture devided into a 10x10 grid
+ //with one cell representing a frame of animation
+ Animation idleAnimation =
+ AnimationFromIndices((AnimationFromIndicesParams){
+ .texture = bodyTexture->texture,
+ .isLooping = true,
+ .numFrames = 4,
+
+ .framesX = 10,
+ .framesY = 10,
+
+ .indices = (int[]) {0, 1, 2, 3},
+ .frameTimes = (float[]) {0.1f, 0.1f, 0.1f, 0.1f}
+ });
+ bodySprite.animations[PLAYER_IDLE] = idleAnimation;
+
+ Animation walkingAnimation =
+ AnimationFromIndices((AnimationFromIndicesParams){
+ .texture = bodyTexture->texture,
+ .isLooping = true,
+ .numFrames = 7,
+
+ .framesX = 10,
+ .framesY = 10,
+
+ .indices = (int[]) {10, 11, 12, 13, 14, 15, 16, 17},
+ .frameTimes = (float[]) {0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f}
+ });
+ bodySprite.animations[PLAYER_WALKING] = walkingAnimation;
+
+ bodySprite.numAnimations = 2;
+ player->bodySpriteIndex = AddSpriteToEntity(player, bodySprite);
}