#include #include #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; static void AddPlayerSprites(Entity* player); static inline Sprite* GetBodySprite(Entity* player) { return &player->sprites[player->bodySpriteIndex]; } typedef enum PlayerStates { PLAYER_IDLE = 0, PLAYER_WALKING = 1, PLAYER_ATTACK = 2, } PlayerStates; Vector2 GetMovementDirection() { Vector2 movementDirection = {0.0f, 0.0f}; if (IsKeyDown(KEY_W)) { movementDirection.y = -1.0f; } else if (IsKeyDown(KEY_S)) { movementDirection.y = 1.0f; } if (IsKeyDown(KEY_A)) { movementDirection.x = -1.0f; } else if (IsKeyDown(KEY_D)) { movementDirection.x = 1.0f; } if (Vector2Length(movementDirection) > 0.0f) return Vector2Normalize(movementDirection); return movementDirection; } void CameraFollow(const Entity* player) { game.camera.target = (Vector2) {fmaxf(WINDOW_WIDTH / 2.0f, player->position.x), 0.0f}; } 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 HandleMovement(Entity* player) { Sprite* bodySprite = GetBodySprite(player); if (Vector2Length(player->velocity) > 0.0) bodySprite->currentAnimation = PLAYER_WALKING; else bodySprite->currentAnimation = PLAYER_IDLE; } void HandleInput(Entity* player) { player->velocity = Vector2Scale(GetMovementDirection(), PLAYER_SPEED); } void UpdateAnimation(Entity* player, float deltaTime) { Sprite* bodySprite = GetBodySprite(player); UpdateCurrentSpriteAnimation(bodySprite, deltaTime); } void FlipBody(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) { HandleInput(player); HandleMovement(player); FlipBody(player); MoveAndSlide(player, deltaTime); UpdateAnimation(player, deltaTime); CameraFollow(player); } void AddPlayer(float xpos, float ypos) { Entity player = {0}; player.type = Player_Entity; player.position = (Vector2) {xpos, ypos}; player.flags |= (ENTITY_PHYSICS_ACTIVE | ENTITY_VISIBLE); player.physicsCollider = physicsCollider; #ifdef BEATEMUP_DEBUG player.physicsColliderColor = RED; #endif AddPlayerSprites(&player); AddEntity(&player); } static void AddPlayerSprites(Entity* player) { Asset* shadowTexture = GetMatchingAssetExitOnFail("human-shadow", Texture_Asset); Sprite shadowSprite = (Sprite) { .texture = shadowTexture->texture, .layer = Foreground_Layer, .destRect = shadowDestRect, .srcRect = { 0, 0, shadowTexture->texture.width, shadowTexture->texture.height }, .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; Animation punchAnimation = AnimationFromIndices((AnimationFromIndicesParams){ .texture = bodyTexture->texture, .isLooping = false, .numFrames = 4, .framesX = 10, .framesY = 10, .indices = (int[]) {20, 21, 22, 23}, .frameTimes = (float[]) {0.05f, 0.05f, 0.05f, 0.05f} }); bodySprite.animations[PLAYER_ATTACK] = punchAnimation; bodySprite.numAnimations = 2; player->bodySpriteIndex = AddSpriteToEntity(player, bodySprite); }