Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a5757748cf | |||
| f4e4728ce3 |
@@ -23,13 +23,54 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
bool LocalCharacter::ProcessCollisionGrid(std::list<BoundingBox> boxList) {
|
bool LocalCharacter::ProcessCollisionGrid(std::list<BoundingBox> boxList, Uint8* keyState) {
|
||||||
for(auto& box : boxList) {
|
//skip this if there's no movement
|
||||||
if (box.CheckOverlap(origin + bounds)) {
|
if (motion == 0) {
|
||||||
origin -= motion;
|
|
||||||
motion = {0, 0};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
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.CheckCollision(origin + bounds)) {
|
||||||
|
//push the character to the closest non-contact position
|
||||||
|
Vector2 shift = box.CalcShift(origin + bounds);
|
||||||
|
origin += shift;
|
||||||
|
|
||||||
|
//set any motion in that direction to zero
|
||||||
|
if (shift.x != 0) {
|
||||||
|
newMotion.x = 0;
|
||||||
|
}
|
||||||
|
if (shift.y != 0) {
|
||||||
|
newMotion.y = 0;
|
||||||
|
}
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//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();
|
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|||||||
//has the user selected a server on the list?
|
//has the user selected a server on the list?
|
||||||
BoundingBox tmpBox = listBox;
|
BoundingBox tmpBox = listBox;
|
||||||
tmpBox.h *= serverInfo.size();
|
tmpBox.h *= serverInfo.size();
|
||||||
if (tmpBox.CheckOverlap({button.x, button.y})) {
|
if (tmpBox.CheckCollision({button.x, button.y, 0, 0})) {
|
||||||
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
|
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#ifndef BOUNDINGBOX_HPP_
|
#ifndef BOUNDINGBOX_HPP_
|
||||||
#define BOUNDINGBOX_HPP_
|
#define BOUNDINGBOX_HPP_
|
||||||
|
|
||||||
|
#include "vector2.hpp"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -32,16 +34,15 @@ public:
|
|||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
BoundingBox() = default;
|
BoundingBox() = default;
|
||||||
BoundingBox(int i, int j): x(i), y(j), w(0), h(0) {};
|
|
||||||
BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {};
|
BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {};
|
||||||
~BoundingBox() = default;
|
~BoundingBox() = default;
|
||||||
BoundingBox& operator=(BoundingBox const&) = default;
|
BoundingBox& operator=(BoundingBox const&) = default;
|
||||||
|
|
||||||
int Size() {
|
int Size() {
|
||||||
return std::max(w*h,0);
|
return (w-x) * (h-y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckOverlap(BoundingBox rhs) {
|
bool CheckCollision(BoundingBox rhs) {
|
||||||
return !(
|
return !(
|
||||||
x >= rhs.x + rhs.w ||
|
x >= rhs.x + rhs.w ||
|
||||||
y >= rhs.y + rhs.h ||
|
y >= rhs.y + rhs.h ||
|
||||||
@@ -49,24 +50,25 @@ public:
|
|||||||
rhs.y >= y + h);
|
rhs.y >= y + h);
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox CalcOverlap(BoundingBox rhs) {
|
Vector2 CalcShift(BoundingBox rhs) {
|
||||||
if (!CheckOverlap(rhs)) {
|
if (!CheckCollision(rhs)) {
|
||||||
return {0, 0, 0, 0};
|
return {0, 0};
|
||||||
}
|
}
|
||||||
BoundingBox ret;
|
|
||||||
ret.x = std::max(x, rhs.x);
|
//DOCS: Given two BoundingBox objects, how does the other have to move so that they are no longer colliding?
|
||||||
ret.y = std::max(y, rhs.y);
|
Vector2 horizontal = {0, 0};
|
||||||
ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x;
|
Vector2 vertical = {0, 0};
|
||||||
ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y;
|
|
||||||
return ret;
|
horizontal.x = std::abs(x + w - rhs.x) < std::abs(rhs.x + rhs.w - x) ? x + w - rhs.x -1 : -(rhs.x + rhs.w - x -1);
|
||||||
|
vertical.y = std::abs(y + h - rhs.x) < std::abs(rhs.y + rhs.h - y) ? y + h - rhs.y -1 : -(rhs.y + rhs.h - y -1);
|
||||||
|
|
||||||
|
return std::abs(vertical.y) < std::abs(horizontal.x) ? vertical : horizontal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//This is explicitly a POD
|
//This is explicitly a POD
|
||||||
static_assert(std::is_pod<BoundingBox>::value, "BoundingBox is not a POD");
|
static_assert(std::is_pod<BoundingBox>::value, "BoundingBox is not a POD");
|
||||||
|
|
||||||
#include "vector2.hpp"
|
|
||||||
|
|
||||||
//operators
|
//operators
|
||||||
inline BoundingBox operator+(BoundingBox b, Vector2 v) {
|
inline BoundingBox operator+(BoundingBox b, Vector2 v) {
|
||||||
return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};
|
return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};
|
||||||
|
|||||||
Reference in New Issue
Block a user