From 8d7ef2b2ae3ddff204f5934fe67c535d7f1345e9 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 3 Feb 2021 02:03:59 -0500 Subject: Converted Party into CharacterSystem --- src/character_system.cpp | 229 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 src/character_system.cpp (limited to 'src/character_system.cpp') diff --git a/src/character_system.cpp b/src/character_system.cpp new file mode 100644 index 0000000..64e2f3b --- /dev/null +++ b/src/character_system.cpp @@ -0,0 +1,229 @@ +#include "character_system.h" +#include "consts.h" +#include "mixer.h" +#include "sprite.h" +#include "game.h" +#include "transform_system.h" +#include "animation_system.h" + +void CharacterSystem::addSpriteToParty(int leaderId, int followerId) { + Sprite& leader = game_.getSprite(leaderId); + Sprite& follower = game_.getSprite(followerId); + + int index = leader.followers.size() + 1; + follower.trail = std::deque(PARTY_FRAME_DELAY * index, {.pos = follower.loc, .dir = follower.dir}); + + leader.followers.push_back(followerId); + + game_.getSystem().setSpriteAnimation(followerId, "still"); +} + +void CharacterSystem::moveSprite(int spriteId, Mixer& mixer, const Input& keystate) { + Sprite& sprite = game_.getSprite(spriteId); + Direction dir = sprite.dir; + + if (!keystate.up && !keystate.down && !keystate.left && !keystate.right) { + if (sprite.characterState != CharacterState::Running) { + if (sprite.characterState == CharacterState::Normal) { + game_.getSystem().setSpriteAnimation(spriteId, "still"); + for (int followerId : sprite.followers) { + game_.getSystem().setSpriteAnimation(followerId, "still"); + } + } + + return; + } + } else { + if (keystate.up) + { + dir = Direction::up; + } else if (keystate.down) + { + dir = Direction::down; + } + + 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; + } + } + } + + vec2i pLoc = sprite.loc; + game_.getSystem().setSpriteDirection(spriteId, dir); + + if (sprite.characterState == CharacterState::Crouching) { + for (int followerId : sprite.followers) { + game_.getSystem().setSpriteDirection(followerId, dir); + } + + return; + } + + int speed = MOVEMENT_SPEED; + if (sprite.characterState == CharacterState::Running) { + speed *= 2; + } else { + game_.getSystem().setSpriteAnimation(spriteId, "walk"); + for (int followerId : sprite.followers) { + game_.getSystem().setSpriteAnimation(followerId, "walk"); + } + } + + pLoc += (unitVecInDirection(dir) * speed); + + // Check collision. + const Map& map = game_.getMap(); + bool blocked = false; + + const vec2i UL_COL_BOX = { 8, 8 }; + const vec2i DR_COL_BOX = { 4, 0 }; + vec2i oldColPosUL = (sprite.loc - UL_COL_BOX) / map.getTileSize(); + vec2i newColPosUL = (pLoc - UL_COL_BOX) / map.getTileSize(); + vec2i oldColPosDR = (sprite.loc + DR_COL_BOX) / map.getTileSize(); + vec2i newColPosDR = (pLoc + DR_COL_BOX) / map.getTileSize(); + + if (dirHasDir(dir, Direction::right) && + newColPosDR.x() > oldColPosDR.x()) { + for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { + if (map.isBlocked(newColPosDR.x(), y)) { + blocked = true; + pLoc.x() = sprite.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; + break; + } + } + } + + if (dirHasDir(dir, Direction::left) && + newColPosUL.x() < oldColPosUL.x()) { + for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { + if (map.isBlocked(newColPosUL.x(), y)) { + blocked = true; + pLoc.x() = sprite.loc.x();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; + break; + } + } + } + + if (dirHasDir(dir, Direction::down) && + newColPosDR.y() > oldColPosDR.y()) { + for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { + if (map.isBlocked(x, newColPosDR.y())) { + blocked = true; + pLoc.y() = sprite.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; + break; + } + } + } + + if (dirHasDir(dir, Direction::up) && + newColPosUL.y() < oldColPosUL.y()) { + for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { + if (map.isBlocked(x, newColPosUL.y())) { + blocked = true; + pLoc.y() = sprite.loc.y();//(newColPosDR * map.getTileSize() - (collisionBox / 2)).x() - 1; + break; + } + } + } + + if (blocked && sprite.characterState == CharacterState::Running) { + stopRunning(spriteId); + mixer.playSound("../res/bump.wav"); + } + + // Move everything + if (pLoc != sprite.loc) { + game_.getSystem().moveSprite(spriteId, pLoc); + + for (int followerId : sprite.followers) { + Sprite& pNext = game_.getSprite(followerId); + const Movement& posdir = pNext.trail.front(); + game_.getSystem().moveSprite(followerId, posdir.pos); + game_.getSystem().setSpriteDirection(followerId, posdir.dir); + + pNext.trail.pop_front(); + pNext.trail.push_back({.pos = pLoc, .dir = dir}); + } + } +} + +void CharacterSystem::beginCrouch(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + + if (sprite.characterState == CharacterState::Running) { + stopRunning(spriteId); + } else { + sprite.characterState = CharacterState::Crouching; + + game_.getSystem().setSpriteAnimation(spriteId, "crouch"); + for (int followerId : sprite.followers) { + game_.getSystem().setSpriteAnimation(followerId, "crouch"); + } + } +} + +void CharacterSystem::endCrouch(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + + if (sprite.characterState == CharacterState::Crouching) { + sprite.characterState = CharacterState::Running; + + game_.getSystem().setSpriteAnimation(spriteId, "run"); + for (int followerId : sprite.followers) { + game_.getSystem().setSpriteAnimation(followerId, "run"); + + // Halve the movement buffer for the followers. + Sprite& follower = game_.getSprite(followerId); + std::deque newMove; + + while (!follower.trail.empty()) { + newMove.push_back(follower.trail.front()); + follower.trail.pop_front(); + follower.trail.pop_front(); + } + + follower.trail = std::move(newMove); + } + } +} + +void CharacterSystem::stopRunning(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + sprite.characterState = CharacterState::Normal; + + // Double the movement buffer for the followers. + for (int followerId : sprite.followers) { + Sprite& follower = game_.getSprite(followerId); + + std::deque newMove; + vec2i lastPos = follower.loc; + + while (!follower.trail.empty()) { + Movement m1 = follower.trail.front(); + Movement m2 = m1; + m1.pos = (m1.pos + lastPos) / 2; + lastPos = m2.pos; + + newMove.push_back(m1); + newMove.push_back(m2); + follower.trail.pop_front(); + } + + follower.trail = std::move(newMove); + } +} -- cgit 1.4.1