Partial solution for collision problems
This commit is contained in:
@@ -23,13 +23,48 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
bool LocalCharacter::ProcessCollisionGrid(std::list<BoundingBox> boxList) {
|
bool LocalCharacter::ProcessCollisionGrid(std::list<BoundingBox> 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) {
|
for(auto& box : boxList) {
|
||||||
if (box.CheckOverlap(origin + bounds)) {
|
if (box.CheckOverlap(origin + bounds)) {
|
||||||
origin -= motion;
|
//push the character to the closest non-contact position
|
||||||
motion = {0, 0};
|
//TODO
|
||||||
return true;
|
|
||||||
|
//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;
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
LocalCharacter() = default;
|
LocalCharacter() = default;
|
||||||
virtual ~LocalCharacter() = default;
|
virtual ~LocalCharacter() = default;
|
||||||
|
|
||||||
bool ProcessCollisionGrid(std::list<BoundingBox>);
|
bool ProcessCollisionGrid(std::list<BoundingBox>, Uint8* keyState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//NOTE: NO MEMBERS
|
//NOTE: NO MEMBERS
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ protected:
|
|||||||
void HandleMonsterAttack(MonsterPacket* const);
|
void HandleMonsterAttack(MonsterPacket* const);
|
||||||
|
|
||||||
//player movement
|
//player movement
|
||||||
|
void ProcessLocalCharacterMovement();
|
||||||
void SendLocalCharacterMovement();
|
void SendLocalCharacterMovement();
|
||||||
std::list<BoundingBox> GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight);
|
std::list<BoundingBox> GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight);
|
||||||
|
|
||||||
@@ -150,6 +151,7 @@ protected:
|
|||||||
//ugly references; I hate this
|
//ugly references; I hate this
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
|
||||||
|
Uint8* keyState = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -175,7 +175,39 @@ void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) {
|
|||||||
//player movement
|
//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() {
|
void InWorld::SendLocalCharacterMovement() {
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_MOVEMENT;
|
newPacket.type = SerialPacketType::CHARACTER_MOVEMENT;
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
|
|
||||||
InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
|
InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex):
|
||||||
clientIndex(*argClientIndex),
|
clientIndex(*argClientIndex),
|
||||||
accountIndex(*argAccountIndex)
|
accountIndex(*argAccountIndex),
|
||||||
|
keyState(SDL_GetKeyState(nullptr))
|
||||||
{
|
{
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||||
@@ -144,7 +145,7 @@ void InWorld::Update() {
|
|||||||
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
|
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
|
||||||
|
|
||||||
//process the collisions
|
//process the collisions
|
||||||
if (localCharacter->ProcessCollisionGrid(boxList)) {
|
if (localCharacter->ProcessCollisionGrid(boxList, keyState)) {
|
||||||
localCharacter->CorrectSprite();
|
localCharacter->CorrectSprite();
|
||||||
SendLocalCharacterMovement();
|
SendLocalCharacterMovement();
|
||||||
}
|
}
|
||||||
@@ -219,88 +220,34 @@ void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
|
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
|
||||||
//hotkeys
|
//hotkeys & player input
|
||||||
switch(key.keysym.sym) {
|
switch(key.keysym.sym) {
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
//TODO: the escape key should actually control menus and stuff
|
//TODO: the escape key should actually control menus and stuff
|
||||||
SendLogoutRequest();
|
SendLogoutRequest();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
//character movement
|
|
||||||
if (!localCharacter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Vector2 motion = localCharacter->GetMotion();
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_w:
|
case SDLK_w:
|
||||||
motion.y -= CHARACTER_WALKING_SPEED;
|
|
||||||
break;
|
|
||||||
case SDLK_a:
|
case SDLK_a:
|
||||||
motion.x -= CHARACTER_WALKING_SPEED;
|
|
||||||
break;
|
|
||||||
case SDLK_s:
|
case SDLK_s:
|
||||||
motion.y += CHARACTER_WALKING_SPEED;
|
|
||||||
break;
|
|
||||||
case SDLK_d:
|
case SDLK_d:
|
||||||
motion.x += CHARACTER_WALKING_SPEED;
|
ProcessLocalCharacterMovement();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//DOCS: prevents wrong keys screwing with character movement
|
//DOCS: prevents wrong keys screwing with character movement
|
||||||
return;
|
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) {
|
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
|
||||||
//character movement
|
|
||||||
if (!localCharacter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Vector2 motion = localCharacter->GetMotion();
|
|
||||||
switch(key.keysym.sym) {
|
switch(key.keysym.sym) {
|
||||||
case SDLK_w:
|
case SDLK_w:
|
||||||
motion.y = std::min(0.0, motion.y += CHARACTER_WALKING_SPEED);
|
|
||||||
break;
|
|
||||||
case SDLK_a:
|
case SDLK_a:
|
||||||
motion.x = std::min(0.0, motion.x += CHARACTER_WALKING_SPEED);
|
|
||||||
break;
|
|
||||||
case SDLK_s:
|
case SDLK_s:
|
||||||
motion.y = std::max(0.0, motion.y -= CHARACTER_WALKING_SPEED);
|
|
||||||
break;
|
|
||||||
case SDLK_d:
|
case SDLK_d:
|
||||||
motion.x = std::max(0.0, motion.x -= CHARACTER_WALKING_SPEED);
|
ProcessLocalCharacterMovement();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//DOCS: prevents wrong keys screwing with character movement
|
//DOCS: prevents wrong keys screwing with character movement
|
||||||
return;
|
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();
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user