map class more flexible
This commit is contained in:
parent
8f2ad83756
commit
6a33473a1a
|
@ -34,14 +34,15 @@ Map g_map;
|
||||||
void Map::draw(const Rect& rect)
|
void Map::draw(const Rect& rect)
|
||||||
{
|
{
|
||||||
if(!m_framebuffer)
|
if(!m_framebuffer)
|
||||||
m_framebuffer = FrameBufferPtr(new FrameBuffer(MAP_VISIBLE_WIDTH * NUM_TILE_PIXELS, MAP_VISIBLE_HEIGHT * NUM_TILE_PIXELS));
|
setVisibleSize(Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT));
|
||||||
|
|
||||||
g_graphics.bindColor(Fw::white);
|
g_graphics.bindColor(Fw::white);
|
||||||
m_framebuffer->bind();
|
m_framebuffer->bind();
|
||||||
|
|
||||||
// draw offsets
|
// draw offsets
|
||||||
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
|
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
|
||||||
Point walkOffset = localPlayer->getWalkOffset();
|
if(localPlayer)
|
||||||
|
m_drawOffset = localPlayer->getWalkOffset();
|
||||||
|
|
||||||
//TODO: cache first/last visible floor
|
//TODO: cache first/last visible floor
|
||||||
// draw from bottom floors to top floors
|
// draw from bottom floors to top floors
|
||||||
|
@ -49,12 +50,12 @@ void Map::draw(const Rect& rect)
|
||||||
const int lastFloor = MAX_Z-1;
|
const int lastFloor = MAX_Z-1;
|
||||||
for(int iz = lastFloor; iz >= firstFloor; --iz) {
|
for(int iz = lastFloor; iz >= firstFloor; --iz) {
|
||||||
// draw tiles like linus pauling's rule order
|
// draw tiles like linus pauling's rule order
|
||||||
const int numDiagonals = MAP_SIZE_X + MAP_SIZE_Y - 1;
|
const int numDiagonals = m_size.width() + m_size.height() - 1;
|
||||||
for(int diagonal = 0; diagonal < numDiagonals; ++diagonal) {
|
for(int diagonal = 0; diagonal < numDiagonals; ++diagonal) {
|
||||||
// loop through / diagonal tiles
|
// loop through / diagonal tiles
|
||||||
for(int ix = std::min(diagonal, MAP_SIZE_X - 1), iy = std::max(diagonal - MAP_SIZE_X, 0); ix >= 0 && iy < MAP_SIZE_Y; --ix, ++iy) {
|
for(int ix = std::min(diagonal, m_size.width() - 1), iy = std::max(diagonal - m_size.width(), 0); ix >= 0 && iy < m_size.height(); --ix, ++iy) {
|
||||||
// position on current floor
|
// position on current floor
|
||||||
Position tilePos(m_centralPosition.x + (ix - PLAYER_OFFSET_X), m_centralPosition.y + (iy - PLAYER_OFFSET_Y), m_centralPosition.z);
|
Position tilePos(m_centralPosition.x + (ix - m_centralOffset.x), m_centralPosition.y + (iy - m_centralOffset.y), m_centralPosition.z);
|
||||||
// adjust tilePos to the wanted floor
|
// adjust tilePos to the wanted floor
|
||||||
tilePos.perspectiveUp(m_centralPosition.z - iz);
|
tilePos.perspectiveUp(m_centralPosition.z - iz);
|
||||||
//TODO: cache visible tiles, m_tiles[] has a high cost (50% fps decrease)
|
//TODO: cache visible tiles, m_tiles[] has a high cost (50% fps decrease)
|
||||||
|
@ -62,7 +63,7 @@ void Map::draw(const Rect& rect)
|
||||||
// skip tiles that are behind another tile
|
// skip tiles that are behind another tile
|
||||||
//if(isCompletlyCovered(tilePos, firstFloor))
|
//if(isCompletlyCovered(tilePos, firstFloor))
|
||||||
// continue;
|
// continue;
|
||||||
tile->draw(tilePos.to2D(m_centralPosition) - walkOffset);
|
tile->draw(positionTo2D(tilePos) - m_drawOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ void Map::draw(const Rect& rect)
|
||||||
// after drawing all tiles, draw shots
|
// after drawing all tiles, draw shots
|
||||||
for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
|
for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
|
||||||
Position missilePos = shot->getPosition();
|
Position missilePos = shot->getPosition();
|
||||||
shot->draw(missilePos.to2D(m_centralPosition) - walkOffset);
|
shot->draw(positionTo2D(missilePos) - m_drawOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +81,14 @@ void Map::draw(const Rect& rect)
|
||||||
m_framebuffer->draw(rect);
|
m_framebuffer->draw(rect);
|
||||||
|
|
||||||
// calculate stretch factor
|
// calculate stretch factor
|
||||||
float horizontalStretchFactor = rect.width() / (float)(MAP_VISIBLE_WIDTH * NUM_TILE_PIXELS);
|
float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS);
|
||||||
float verticalStretchFactor = rect.height() / (float)(MAP_VISIBLE_HEIGHT * NUM_TILE_PIXELS);
|
float verticalStretchFactor = rect.height() / (float)(m_visibleSize.height() * NUM_TILE_PIXELS);
|
||||||
|
|
||||||
// draw player names and health bars
|
// draw player names and health bars
|
||||||
//TODO: this must be cached with creature walks
|
//TODO: this must be cached with creature walks
|
||||||
for(int x = 0; x < MAP_VISIBLE_WIDTH; ++x) {
|
for(int x = 0; x < m_visibleSize.width(); ++x) {
|
||||||
for(int y = 0; y < MAP_VISIBLE_HEIGHT; ++y) {
|
for(int y = 0; y < m_visibleSize.height(); ++y) {
|
||||||
Position tilePos = Position(m_centralPosition.x + (x - PLAYER_OFFSET_X + 1), m_centralPosition.y + (y - PLAYER_OFFSET_Y + 1), m_centralPosition.z);
|
Position tilePos = Position(m_centralPosition.x + (x - m_centralOffset.x + 1), m_centralPosition.y + (y - m_centralOffset.y + 1), m_centralPosition.z);
|
||||||
if(const TilePtr& tile = m_tiles[tilePos]) {
|
if(const TilePtr& tile = m_tiles[tilePos]) {
|
||||||
auto creatures = tile->getCreatures();
|
auto creatures = tile->getCreatures();
|
||||||
|
|
||||||
|
@ -95,11 +96,11 @@ void Map::draw(const Rect& rect)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(const CreaturePtr& creature : creatures) {
|
for(const CreaturePtr& creature : creatures) {
|
||||||
Point p((7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(),
|
Point p((m_centralOffset.x - 1 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(),
|
||||||
(5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation());
|
(m_centralOffset.y - 1 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation());
|
||||||
|
|
||||||
if(creature != localPlayer) {
|
if(creature != localPlayer) {
|
||||||
p += creature->getWalkOffset() - walkOffset;
|
p += creature->getWalkOffset() - m_drawOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
|
creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
|
||||||
|
@ -278,3 +279,22 @@ void Map::setCentralPosition(const Position& centralPosition)
|
||||||
{
|
{
|
||||||
m_centralPosition = centralPosition;
|
m_centralPosition = centralPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Map::setVisibleSize(const Size& visibleSize)
|
||||||
|
{
|
||||||
|
m_visibleSize = visibleSize;
|
||||||
|
|
||||||
|
if(m_visibleSize.width() > MAX_WIDTH || m_visibleSize.height() > MAX_HEIGHT)
|
||||||
|
m_visibleSize = Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT);
|
||||||
|
|
||||||
|
m_centralOffset = Point(std::ceil(m_visibleSize.width() / 2.0), std::ceil(m_visibleSize.height() / 2.0));
|
||||||
|
m_size = m_visibleSize + Size(3, 3);
|
||||||
|
|
||||||
|
m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
|
||||||
|
}
|
||||||
|
|
||||||
|
Point Map::positionTo2D(const Position& position)
|
||||||
|
{
|
||||||
|
return Point((m_centralOffset.x - 1 + (position.x - m_centralPosition.x) - (m_centralPosition.z - position.z)) * NUM_TILE_PIXELS,
|
||||||
|
(m_centralOffset.y - 1 + (position.y - m_centralPosition.y) - (m_centralPosition.z - position.z)) * NUM_TILE_PIXELS);
|
||||||
|
}
|
||||||
|
|
|
@ -30,13 +30,11 @@ class Map
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
PLAYER_OFFSET_X = 8,
|
|
||||||
PLAYER_OFFSET_Y = 6,
|
|
||||||
MAP_VISIBLE_WIDTH = 15,
|
MAP_VISIBLE_WIDTH = 15,
|
||||||
MAP_VISIBLE_HEIGHT = 11,
|
MAP_VISIBLE_HEIGHT = 11,
|
||||||
MAP_SIZE_X = MAP_VISIBLE_WIDTH + 3,
|
|
||||||
MAP_SIZE_Y = MAP_VISIBLE_HEIGHT + 3,
|
|
||||||
MAP_SIZE_Z = 8,
|
MAP_SIZE_Z = 8,
|
||||||
|
MAX_WIDTH = 24,
|
||||||
|
MAX_HEIGHT = 24,
|
||||||
MAX_Z = 15,
|
MAX_Z = 15,
|
||||||
NUM_TILE_PIXELS = 32
|
NUM_TILE_PIXELS = 32
|
||||||
};
|
};
|
||||||
|
@ -66,6 +64,11 @@ public:
|
||||||
CreaturePtr getCreatureById(uint32 id);
|
CreaturePtr getCreatureById(uint32 id);
|
||||||
void removeCreatureById(uint32 id);
|
void removeCreatureById(uint32 id);
|
||||||
|
|
||||||
|
void setVisibleSize(const Size& visibleSize);
|
||||||
|
Point getCentralOffset() { return m_centralOffset; }
|
||||||
|
|
||||||
|
Point positionTo2D(const Position& position);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
||||||
std::map<uint32, CreaturePtr> m_creatures;
|
std::map<uint32, CreaturePtr> m_creatures;
|
||||||
|
@ -73,6 +76,8 @@ private:
|
||||||
|
|
||||||
Light m_light;
|
Light m_light;
|
||||||
Position m_centralPosition;
|
Position m_centralPosition;
|
||||||
|
Size m_size, m_visibleSize;
|
||||||
|
Point m_centralOffset, m_drawOffset;
|
||||||
|
|
||||||
FrameBufferPtr m_framebuffer;
|
FrameBufferPtr m_framebuffer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,7 +62,7 @@ bool UIMap::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||||
PointF relativeMousePos = PointF(relativeStretchMousePos.x, relativeStretchMousePos.y) / stretchFactor;
|
PointF relativeMousePos = PointF(relativeStretchMousePos.x, relativeStretchMousePos.y) / stretchFactor;
|
||||||
|
|
||||||
PointF tilePosF = relativeMousePos / Map::NUM_TILE_PIXELS;
|
PointF tilePosF = relativeMousePos / Map::NUM_TILE_PIXELS;
|
||||||
Position tilePos = Position(1 + (int)tilePosF.x - Map::PLAYER_OFFSET_X, 1 + (int)tilePosF.y - Map::PLAYER_OFFSET_Y, 0) + g_map.getCentralPosition();
|
Position tilePos = Position(1 + (int)tilePosF.x - g_map.getCentralOffset().x, 1 + (int)tilePosF.y - g_map.getCentralOffset().y, 0) + g_map.getCentralPosition();
|
||||||
|
|
||||||
TilePtr tile = g_map.getTile(tilePos);
|
TilePtr tile = g_map.getTile(tilePos);
|
||||||
if(tile)
|
if(tile)
|
||||||
|
|
|
@ -71,11 +71,6 @@ public:
|
||||||
return std::abs(x-pos.x) <= xdif && std::abs(y-pos.y) <= ydif && std::abs(pos.z-z) <= zdif;
|
return std::abs(x-pos.x) <= xdif && std::abs(y-pos.y) <= ydif && std::abs(pos.z-z) <= zdif;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point to2D(const Position& centerPos) const {
|
|
||||||
return Point((7 + (x - centerPos.x) - (centerPos.z - z)) * 32,
|
|
||||||
(5 + (y - centerPos.y) - (centerPos.z - z)) * 32);
|
|
||||||
};
|
|
||||||
|
|
||||||
void up(int n = 1) { z-=n; }
|
void up(int n = 1) { z-=n; }
|
||||||
void down(int n = 1) { z+=n; }
|
void down(int n = 1) { z+=n; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue