diff --git a/client/entities/local_character.cpp b/client/entities/local_character.cpp index 16c1eff..dc563d9 100644 --- a/client/entities/local_character.cpp +++ b/client/entities/local_character.cpp @@ -23,13 +23,48 @@ #include -bool LocalCharacter::ProcessCollisionGrid(std::list boxList) { +bool LocalCharacter::ProcessCollisionGrid(std::list boxList, Uint8* keyState) { + //skip this if there's no movement + if (motion == 0) { + return false; + } + + //determine the simple movement based on input + Vector2 newMotion = {0, 0}; + if (keyState[SDLK_w]) { + newMotion.y -= CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_a]) { + newMotion.x -= CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_s]) { + newMotion.y += CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_d]) { + newMotion.x += CHARACTER_WALKING_SPEED; + } + + bool ret = false; + for(auto& box : boxList) { if (box.CheckOverlap(origin + bounds)) { - origin -= motion; - motion = {0, 0}; - return true; + //push the character to the closest non-contact position + //TODO + + //set any motion in that direction to zero + //TODO + ret = true; } } - return false; + + //handle diagonals + if (newMotion.x != 0 && newMotion.y != 0) { + newMotion *= CHARACTER_WALKING_MOD; + } + + //set the new motion + motion = newMotion; + + //signal for updates + return ret; } \ No newline at end of file diff --git a/client/entities/local_character.hpp b/client/entities/local_character.hpp index a462ddc..73cc6c6 100644 --- a/client/entities/local_character.hpp +++ b/client/entities/local_character.hpp @@ -33,7 +33,7 @@ public: LocalCharacter() = default; virtual ~LocalCharacter() = default; - bool ProcessCollisionGrid(std::list); + bool ProcessCollisionGrid(std::list, Uint8* keyState); private: //NOTE: NO MEMBERS diff --git a/client/gameplay_scenes/in_world.hpp b/client/gameplay_scenes/in_world.hpp index 7dfa1fc..c38f1c5 100644 --- a/client/gameplay_scenes/in_world.hpp +++ b/client/gameplay_scenes/in_world.hpp @@ -107,6 +107,7 @@ protected: void HandleMonsterAttack(MonsterPacket* const); //player movement + void ProcessLocalCharacterMovement(); void SendLocalCharacterMovement(); std::list GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight); @@ -150,6 +151,7 @@ protected: //ugly references; I hate this ConfigUtility& config = ConfigUtility::GetSingleton(); UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton(); + Uint8* keyState = nullptr; }; #endif diff --git a/client/gameplay_scenes/in_world_entities.cpp b/client/gameplay_scenes/in_world_entities.cpp index 7fd7155..9189af6 100644 --- a/client/gameplay_scenes/in_world_entities.cpp +++ b/client/gameplay_scenes/in_world_entities.cpp @@ -175,7 +175,39 @@ void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { //player movement //------------------------- -//TODO: add a "movement" packet type +void InWorld::ProcessLocalCharacterMovement() { + //character movement + if (!localCharacter) { + return; + } + + Vector2 newMotion = {0, 0}; + if (keyState[SDLK_w]) { + newMotion.y -= CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_a]) { + newMotion.x -= CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_s]) { + newMotion.y += CHARACTER_WALKING_SPEED; + } + if (keyState[SDLK_d]) { + newMotion.x += CHARACTER_WALKING_SPEED; + } + + //handle diagonals + if (newMotion.x != 0 && newMotion.y != 0) { + newMotion *= CHARACTER_WALKING_MOD; + } + + //set the info + if (localCharacter->GetMotion() != newMotion) { + localCharacter->SetMotion(newMotion); + localCharacter->CorrectSprite(); + SendLocalCharacterMovement(); + } +} + void InWorld::SendLocalCharacterMovement() { CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/in_world_scene.cpp index 284d892..7c76f08 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/in_world_scene.cpp @@ -36,7 +36,8 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): clientIndex(*argClientIndex), - accountIndex(*argAccountIndex) + accountIndex(*argAccountIndex), + keyState(SDL_GetKeyState(nullptr)) { //setup the utility objects buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); @@ -144,7 +145,7 @@ void InWorld::Update() { std::list boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH()); //process the collisions - if (localCharacter->ProcessCollisionGrid(boxList)) { + if (localCharacter->ProcessCollisionGrid(boxList, keyState)) { localCharacter->CorrectSprite(); SendLocalCharacterMovement(); } @@ -219,88 +220,34 @@ void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) { } void InWorld::KeyDown(SDL_KeyboardEvent const& key) { - //hotkeys + //hotkeys & player input switch(key.keysym.sym) { case SDLK_ESCAPE: //TODO: the escape key should actually control menus and stuff SendLogoutRequest(); return; - } - - //character movement - if (!localCharacter) { - return; - } - Vector2 motion = localCharacter->GetMotion(); - switch(key.keysym.sym) { case SDLK_w: - motion.y -= CHARACTER_WALKING_SPEED; - break; case SDLK_a: - motion.x -= CHARACTER_WALKING_SPEED; - break; case SDLK_s: - motion.y += CHARACTER_WALKING_SPEED; - break; case SDLK_d: - motion.x += CHARACTER_WALKING_SPEED; + ProcessLocalCharacterMovement(); break; default: //DOCS: prevents wrong keys screwing with character movement return; } - //handle diagonals - if (motion.x != 0 && motion.y != 0) { - motion *= CHARACTER_WALKING_MOD; - } - //set the info - localCharacter->SetMotion(motion); - localCharacter->CorrectSprite(); - SendLocalCharacterMovement(); } void InWorld::KeyUp(SDL_KeyboardEvent const& key) { - //character movement - if (!localCharacter) { - return; - } - Vector2 motion = localCharacter->GetMotion(); switch(key.keysym.sym) { case SDLK_w: - motion.y = std::min(0.0, motion.y += CHARACTER_WALKING_SPEED); - break; case SDLK_a: - motion.x = std::min(0.0, motion.x += CHARACTER_WALKING_SPEED); - break; case SDLK_s: - motion.y = std::max(0.0, motion.y -= CHARACTER_WALKING_SPEED); - break; case SDLK_d: - motion.x = std::max(0.0, motion.x -= CHARACTER_WALKING_SPEED); + ProcessLocalCharacterMovement(); break; default: //DOCS: prevents wrong keys screwing with character movement return; } - //BUGFIX: reset cardinal direction speed on key release - if (motion.x > 0) { - motion.x = CHARACTER_WALKING_SPEED; - } - else if (motion.x < 0) { - motion.x = -CHARACTER_WALKING_SPEED; - } - if (motion.y > 0) { - motion.y = CHARACTER_WALKING_SPEED; - } - else if (motion.y < 0) { - motion.y = -CHARACTER_WALKING_SPEED; - } - //handle diagonals - if (motion.x != 0 && motion.y != 0) { - motion *= CHARACTER_WALKING_MOD; - } - //set the info - localCharacter->SetMotion(motion); - localCharacter->CorrectSprite(); - SendLocalCharacterMovement(); } \ No newline at end of file