#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, } 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 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) { 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, .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); }