From d1df87ce04f6d79fed94ab154fa098ccc83ebab8 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 30 Jan 2021 16:15:55 -0500 Subject: Added crouching/running --- res/lucas.png | Bin 5334 -> 10009 bytes res/lucas_anim.txt | 18 +++++- src/direction.h | 14 +++++ src/main.cpp | 4 ++ src/party.cpp | 165 ++++++++++++++++++++++++++++++++++++++--------------- src/party.h | 20 ++++++- src/vector.h | 4 ++ 7 files changed, 175 insertions(+), 50 deletions(-) diff --git a/res/lucas.png b/res/lucas.png index 4ac7157..c059f96 100644 Binary files a/res/lucas.png and b/res/lucas.png differ diff --git a/res/lucas_anim.txt b/res/lucas_anim.txt index ff37580..19b1d67 100644 --- a/res/lucas_anim.txt +++ b/res/lucas_anim.txt @@ -15,4 +15,20 @@ walk[down_right]: 9,10,11 walk[up]: 12,13,14 walk[right]: 15,16,17 walk[up_left]: 18,19,20 -walk[up_right]: 21,22,23 \ No newline at end of file +walk[up_right]: 21,22,23 +crouch[down]: 24 +crouch[down_left]: 25 +crouch[left]: 26 +crouch[up_left]: 27 +crouch[up]: 28 +crouch[up_right]: 29 +crouch[right]: 30 +crouch[down_right]: 31 +run[down]: 32,33,34,35 +run[right]: 36,37,38,39 +run[down_right]: 40,41,42,43 +run[up_right]: 44,45,46,47 +run[up]: 48,49,50,51 +run[left]: 52,53,54,55 +run[up_left]: 56,57,58,59 +run[down_left]: 60,61,62,63 \ No newline at end of file diff --git a/src/direction.h b/src/direction.h index 0679a00..ebc0e46 100644 --- a/src/direction.h +++ b/src/direction.h @@ -3,6 +3,7 @@ #include #include +#include "vector.h" enum class Direction { up, @@ -27,4 +28,17 @@ inline Direction directionFromString(std::string_view str) { throw std::invalid_argument("Invalid direction: " + std::string(str)); } +inline vec2i unitVecInDirection(Direction dir) { + switch (dir) { + case Direction::up: return { 0, -1 }; + case Direction::up_right: return { 1, -1 }; + case Direction::right: return { 1, 0 }; + case Direction::down_right: return { 1, 1 }; + case Direction::down: return { 0, 1 }; + case Direction::down_left: return { -1, 1 }; + case Direction::left: return { -1, 0 }; + case Direction::up_left: return { -1, -1 }; + } +} + #endif /* end of include guard: DIRECTION_H_AB66A90E */ diff --git a/src/main.cpp b/src/main.cpp index 9d889f2..f9db18d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,10 @@ void loop(Renderer& renderer) { while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) { return; + } else if (e.type == SDL_KEYDOWN && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) { + party.beginCrouch(game); + } else if (e.type == SDL_KEYUP && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) { + party.endCrouch(game); } } diff --git a/src/party.cpp b/src/party.cpp index 28492a9..2af252f 100644 --- a/src/party.cpp +++ b/src/party.cpp @@ -10,10 +10,7 @@ void Party::addMember(Game& game, int spriteId) { if (index > 0) { const Sprite& sprite = game.getSprite(spriteId); - for (int i = 0; i < PARTY_FRAME_DELAY * index; i++) { - newMember.nextPosition.push_back(sprite.loc()); - newMember.nextDirection.push_back(sprite.getDirection()); - } + newMember.movement = std::deque(PARTY_FRAME_DELAY * index, {.pos = sprite.loc(), .dir = sprite.getDirection()}); } members_.push_back(std::move(newMember)); @@ -26,65 +23,139 @@ void Party::move(Game& game, const Input& keystate) { return; } - const Sprite& p1 = game.getSprite(members_[0].spriteId); - vec2i pLoc = p1.loc(); Direction dir = Direction::left; - if (keystate.up) - { - pLoc.y() -= MOVEMENT_SPEED; - dir = Direction::up; - } else if (keystate.down) - { - pLoc.y() += MOVEMENT_SPEED; - dir = Direction::down; - } + if (!keystate.up && !keystate.down && !keystate.left && !keystate.right) { + if (state_ == State::Running) { + dir = lastDir_; + } else { + if (state_ == State::Normal) { + for (int i = 0; i < members_.size(); i++) { + game.setSpriteState(members_[i].spriteId, "still"); + } + } - if (keystate.left) - { - pLoc.x() -= MOVEMENT_SPEED; + return; + } + } else { + if (keystate.up) + { + dir = Direction::up; + } else if (keystate.down) + { + dir = Direction::down; + } - if (dir == Direction::up) { - dir = Direction::up_left; - } else if (dir == Direction::down) { - dir = Direction::down_left; - } else { - dir = Direction::left; + if (keystate.left) + { + if (dir == Direction::up) { + dir = Direction::up_left; + } else if (dir == Direction::down) { + dir = Direction::down_left; + } else { + dir = Direction::left; + } + } else if (keystate.right) + { + if (dir == Direction::up) { + dir = Direction::up_right; + } else if (dir == Direction::down) { + dir = Direction::down_right; + } else { + dir = Direction::right; + } } - } else if (keystate.right) - { - pLoc.x() += MOVEMENT_SPEED; - - if (dir == Direction::up) { - dir = Direction::up_right; - } else if (dir == Direction::down) { - dir = Direction::down_right; - } else { - dir = Direction::right; + } + + lastDir_ = dir; + + const Sprite& p1 = game.getSprite(members_[0].spriteId); + vec2i pLoc = p1.loc(); + + if (state_ == State::Crouching) { + for (int i = 0; i < members_.size(); i++) { + game.setSpriteDirection(members_[i].spriteId, dir); } + + return; + } else { + game.setSpriteDirection(members_[0].spriteId, dir); } - if (keystate.up || keystate.down || keystate.left || keystate.right) { + int speed = MOVEMENT_SPEED; + if (state_ == State::Running) { + speed *= 2; + } else { for (int i = 0; i < members_.size(); i++) { game.setSpriteState(members_[i].spriteId, "walk"); } + } - game.moveSprite(members_[0].spriteId, pLoc); - game.setSpriteDirection(members_[0].spriteId, dir); + pLoc += (unitVecInDirection(dir) * speed); + + game.moveSprite(members_[0].spriteId, pLoc); + for (int i = 1; i < members_.size(); i++) { + const Sprite& pNext = game.getSprite(members_[i].spriteId); + const Movement& posdir = members_[i].movement.front(); + game.moveSprite(members_[i].spriteId, posdir.pos); + game.setSpriteDirection(members_[i].spriteId, posdir.dir); + + members_[i].movement.pop_front(); + members_[i].movement.push_back({.pos = pLoc, .dir = dir}); + } +} + +void Party::beginCrouch(Game& game) { + if (state_ == State::Running) { + state_ = State::Normal; + + // Double the movement buffer for the followers. for (int i = 1; i < members_.size(); i++) { - const Sprite& pNext = game.getSprite(members_[i].spriteId); - members_[i].nextPosition.push_back(pLoc); - game.moveSprite(members_[i].spriteId, members_[i].nextPosition.front()); - members_[i].nextPosition.pop_front(); - - members_[i].nextDirection.push_back(dir); - game.setSpriteDirection(members_[i].spriteId, members_[i].nextDirection.front()); - members_[i].nextDirection.pop_front(); + std::deque newMove; + vec2i lastPos = game.getSprite(members_[i].spriteId).loc(); + + while (!members_[i].movement.empty()) { + Movement m1 = members_[i].movement.front(); + Movement m2 = m1; + m1.pos = (m1.pos + lastPos) / 2; + lastPos = m2.pos; + + newMove.push_back(m1); + newMove.push_back(m2); + members_[i].movement.pop_front(); + } + + members_[i].movement = std::move(newMove); } } else { + state_ = State::Crouching; + for (int i = 0; i < members_.size(); i++) { - game.setSpriteState(members_[i].spriteId, "still"); + game.setSpriteState(members_[i].spriteId, "crouch"); } } -} \ No newline at end of file +} + +void Party::endCrouch(Game& game) { + if (state_ == State::Crouching) { + state_ = State::Running; + + for (int i = 0; i < members_.size(); i++) { + game.setSpriteState(members_[i].spriteId, "run"); + + // Halve the movement buffer for the followers. + if (i > 0) { + std::deque newMove; + + while (!members_[i].movement.empty()) { + newMove.push_back(members_[i].movement.front()); + members_[i].movement.pop_front(); + members_[i].movement.pop_front(); + } + + members_[i].movement = std::move(newMove); + } + } + } +} diff --git a/src/party.h b/src/party.h index 9b0aa89..06f8639 100644 --- a/src/party.h +++ b/src/party.h @@ -12,15 +12,31 @@ public: void move(Game& game, const Input& keystate); + void beginCrouch(Game& game); + + void endCrouch(Game& game); + private: + enum class State { + Normal, + Crouching, + Running + }; + + struct Movement { + vec2i pos; + Direction dir; + }; + struct PartyMember { int spriteId; - std::deque nextPosition; - std::deque nextDirection; + std::deque movement; }; std::vector members_; + State state_ = State::Normal; + Direction lastDir_; }; #endif /* end of include guard: PARTY_H_826F91BA */ diff --git a/src/vector.h b/src/vector.h index 9973ea6..bf38bb2 100644 --- a/src/vector.h +++ b/src/vector.h @@ -80,6 +80,10 @@ public: return vec2(x() * s, y() * s); } + vec2 operator/(T s) const { + return vec2(x() / s, y() / s); + } + vec2& operator*=(T s) { x() *= s; y() *= s; -- cgit 1.4.1