Working on the client side map code (read more)

I've also added in some debug code to the map classes, because I was
hunting down a std::bad_alloc beingthrown. Turns out I forgot to set the
map sizes in the client's InWorld constructor. I'm committing the fix, and
the debug code.
This commit is contained in:
Kayne Ruse
2014-04-06 02:25:55 +11:00
parent 962f3f5dd0
commit 27bda5dc28
7 changed files with 113 additions and 24 deletions
+52 -12
View File
@@ -55,6 +55,11 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
disconnectButton.SetText("Disconnect"); disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down"); shutDownButton.SetText("Shut Down");
//setup the map object
mapPager.SetRegionWidth(REGION_WIDTH);
mapPager.SetRegionHeight(REGION_HEIGHT);
mapPager.SetRegionDepth(REGION_DEPTH);
//create the server-side player object //create the server-side player object
NetworkPacket packet; NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PLAYER_NEW; packet.meta.type = NetworkPacket::Type::PLAYER_NEW;
@@ -73,6 +78,9 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE; packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
serialize(&packet, buffer); serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
//debug
mapPager.GetRegion(0, 0);
} }
InWorld::~InWorld() { InWorld::~InWorld() {
@@ -90,17 +98,6 @@ void InWorld::FrameStart() {
void InWorld::Update(double delta) { void InWorld::Update(double delta) {
NetworkPacket packet; NetworkPacket packet;
//update the camera
if(localCharacter) {
int marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
int marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
camera.x = localCharacter->GetPosition().x - marginX;
camera.y = localCharacter->GetPosition().y - marginY;
}
//check the map
UpdateMap();
//suck in all waiting packets //suck in all waiting packets
while(network.Receive()) { while(network.Receive()) {
deserialize(&packet, network.GetInData()); deserialize(&packet, network.GetInData());
@@ -108,9 +105,20 @@ void InWorld::Update(double delta) {
HandlePacket(packet); HandlePacket(packet);
} }
//update the characters
for (auto& it : playerCharacters) { for (auto& it : playerCharacters) {
it.second.Update(delta); it.second.Update(delta);
} }
//TODO: sort the players and entities by Y position
//update the camera
if(localCharacter) {
camera.x = localCharacter->GetPosition().x - camera.marginX;
camera.y = localCharacter->GetPosition().y - camera.marginY;
}
//check the map
UpdateMap();
} }
void InWorld::FrameEnd() { void InWorld::FrameEnd() {
@@ -118,9 +126,15 @@ void InWorld::FrameEnd() {
} }
void InWorld::Render(SDL_Surface* const screen) { void InWorld::Render(SDL_Surface* const screen) {
//draw the map
//TODO
//draw characters
for (auto& it : playerCharacters) { for (auto& it : playerCharacters) {
it.second.DrawTo(screen, camera.x, camera.y); it.second.DrawTo(screen, camera.x, camera.y);
} }
//draw UI
disconnectButton.DrawTo(screen); disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen); shutDownButton.DrawTo(screen);
} }
@@ -242,6 +256,9 @@ void InWorld::HandlePacket(NetworkPacket packet) {
case NetworkPacket::Type::PLAYER_UPDATE: case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet); HandlePlayerUpdate(packet);
break; break;
case NetworkPacket::Type::REGION_CONTENT:
HandleRegionContent(packet);
break;
//handle errors //handle errors
default: default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered")); throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
@@ -269,6 +286,9 @@ void InWorld::HandlePlayerNew(NetworkPacket packet) {
if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) { if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) {
playerIndex = packet.playerInfo.playerIndex; playerIndex = packet.playerInfo.playerIndex;
localCharacter = &playerCharacters[playerIndex]; localCharacter = &playerCharacters[playerIndex];
//center on the player's character
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
} }
} }
@@ -300,6 +320,15 @@ void InWorld::HandlePlayerUpdate(NetworkPacket packet) {
playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
} }
void InWorld::HandleRegionContent(NetworkPacket packet) {
//replace existing regions
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
mapPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
}
mapPager.PushRegion(packet.regionInfo.region);
packet.regionInfo.region = nullptr;
}
//------------------------- //-------------------------
//Server control //Server control
//------------------------- //-------------------------
@@ -348,5 +377,16 @@ void InWorld::UpdateMap() {
} }
void InWorld::RequestRegion(int x, int y) { void InWorld::RequestRegion(int x, int y) {
// NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//pack the region's data
packet.meta.type = NetworkPacket::Type::REGION_REQUEST;
packet.regionInfo.width = mapPager.GetRegionWidth();
packet.regionInfo.height = mapPager.GetRegionHeight();
packet.regionInfo.depth = mapPager.GetRegionDepth();
packet.regionInfo.x = x;
packet.regionInfo.y = y;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
} }
+2
View File
@@ -74,6 +74,7 @@ protected:
void HandlePlayerNew(NetworkPacket); void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket); void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket); void HandlePlayerUpdate(NetworkPacket);
void HandleRegionContent(NetworkPacket);
//Server control //Server control
void SendState(); void SendState();
@@ -99,6 +100,7 @@ protected:
Button shutDownButton; Button shutDownButton;
struct { struct {
int x = 0, y = 0; int x = 0, y = 0;
int marginX = 0, marginY = 0;
} camera; } camera;
//game //game
+2 -2
View File
@@ -24,11 +24,11 @@
#include <stdexcept> #include <stdexcept>
void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) { void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
//TODO //EMPTY
} }
void DummyFormat::Save(Region* const ptr) { void DummyFormat::Save(Region* const ptr) {
//TODO //EMPTY
} }
/* /*
void VerboseFormat::Load(Region** const ptr, int x, int y) { void VerboseFormat::Load(Region** const ptr, int x, int y) {
+9 -3
View File
@@ -21,6 +21,12 @@
*/ */
#include "region.hpp" #include "region.hpp"
#include <stdexcept>
#include <iostream>
//decorator
#define TRY(x) try { x } catch(std::exception& e) { throw std::runtime_error(std::string() + e.what() + ": " + #x); }
Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY): Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY):
width(argWidth), width(argWidth),
height(argHeight), height(argHeight),
@@ -28,11 +34,11 @@ Region::Region(int argWidth, int argHeight, int argDepth, int argX, int argY):
x(argX), x(argX),
y(argY) y(argY)
{ {
tiles = new type_t**[width]; TRY(tiles = new type_t**[width];)
for (register int i = 0; i < width; ++i) { for (register int i = 0; i < width; ++i) {
tiles[i] = new type_t*[height]; TRY(tiles[i] = new type_t*[height];)
for (register int j = 0; j < height; ++j) { for (register int j = 0; j < height; ++j) {
tiles[i][j] = new type_t[depth]; TRY(tiles[i][j] = new type_t[depth];)
for (register int k = 0; k < depth; ++k) { for (register int k = 0; k < depth; ++k) {
tiles[i][j][k] = 0; tiles[i][j][k] = 0;
} }
+41 -5
View File
@@ -23,6 +23,11 @@
#include "utility.hpp" #include "utility.hpp"
#include <stdexcept>
#include <iostream>
using namespace std;
RegionPagerBase::RegionPagerBase(int argWidth, int argHeight, int argDepth): RegionPagerBase::RegionPagerBase(int argWidth, int argHeight, int argDepth):
regionWidth(argWidth), regionWidth(argWidth),
regionHeight(argHeight), regionHeight(argHeight),
@@ -50,15 +55,46 @@ Region* RegionPagerBase::GetRegion(int x, int y) {
x = snapToBase(regionWidth, x); x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y); y = snapToBase(regionHeight, y);
//get the region by various means
//TODO: revert this try/catch point
Region* ptr = nullptr;
try {
ptr = FindRegion(x, y);
if (ptr) return ptr;
}
catch(exception& e) {
cerr << "FindRegion Error: " << e.what() << endl;
}
try {
ptr = LoadRegion(x, y);
if (ptr) return ptr;
}
catch(exception& e) {
cerr << "LoadRegion Error: " << e.what() << endl;
}
try {
return CreateRegion(x, y);
}
catch(exception& e) {
cerr << "CreateRegion Error: " << e.what() << endl;
}
return nullptr;
}
Region* RegionPagerBase::FindRegion(int x, int y) {
//find the region //find the region
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) { for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
if ((*it)->GetX() == x && (*it)->GetY() == y) { if ((*it)->GetX() == x && (*it)->GetY() == y) {
return *it; return *it;
} }
} }
return nullptr;
//get the region by other means }
Region* ptr = LoadRegion(x, y);
if (ptr) return ptr; Region* RegionPagerBase::PushRegion(Region* ptr) {
return CreateRegion(x, y); regionList.push_front(ptr);
return regionList.front();
} }
+6 -1
View File
@@ -33,18 +33,23 @@ public:
RegionPagerBase(int regionWidth, int regionHeight, int regionDepth); RegionPagerBase(int regionWidth, int regionHeight, int regionDepth);
virtual ~RegionPagerBase(); virtual ~RegionPagerBase();
//tile manipulation
Region::type_t SetTile(int x, int y, int z, Region::type_t v); Region::type_t SetTile(int x, int y, int z, Region::type_t v);
Region::type_t GetTile(int x, int y, int z); Region::type_t GetTile(int x, int y, int z);
//region manipulation
Region* GetRegion(int x, int y); Region* GetRegion(int x, int y);
Region* FindRegion(int x, int y);
Region* PushRegion(Region*);
//interface //interface
virtual Region* LoadRegion(int x, int y) = 0; virtual Region* LoadRegion(int x, int y) = 0;
virtual Region* SaveRegion(int x, int y) = 0; virtual Region* SaveRegion(int x, int y) = 0;
virtual Region* CreateRegion(int x, int y) = 0; virtual Region* CreateRegion(int x, int y) = 0;
virtual void UnloadRegion(int x, int y) = 0; virtual void UnloadRegion(int x, int y) = 0;
//TODO: delete?
//accessors //accessors & mutators
//NOTE: don't change the sizes mid-program, it will cause issues //NOTE: don't change the sizes mid-program, it will cause issues
int SetRegionWidth(int i) { return regionWidth = i; } int SetRegionWidth(int i) { return regionWidth = i; }
int SetRegionHeight(int i) { return regionHeight = i; } int SetRegionHeight(int i) { return regionHeight = i; }
+1 -1
View File
@@ -114,7 +114,7 @@ void ServerApplication::Init(int argc, char** argv) {
cout << "Startup completed successfully" << endl; cout << "Startup completed successfully" << endl;
//debugging //debugging
// mapPager.GetRegion(0, 0);
} }
void ServerApplication::Loop() { void ServerApplication::Loop() {