diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2008-04-08 18:43:44 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2008-04-08 18:43:44 +0000 |
commit | 720f716ba8d98a85266b8e81a534737c6fcdcf5f (patch) | |
tree | 192c702c463db0661f42fa34addf8f957e19e169 /src/map.cpp | |
parent | f25d5640eba5b1a0bbbc050a858aa4cdbdffdc7f (diff) | |
download | mana-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.gz mana-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.bz2 mana-720f716ba8d98a85266b8e81a534737c6fcdcf5f.tar.xz mana-720f716ba8d98a85266b8e81a534737c6fcdcf5f.zip |
Implemented support for an arbitrary number of map layers. The only layer
requirement for map layers are now that the fringe layer is called "Fringe" and
that the collision layer is called "Collision".
Diffstat (limited to 'src/map.cpp')
-rw-r--r-- | src/map.cpp | 208 |
1 files changed, 108 insertions, 100 deletions
diff --git a/src/map.cpp b/src/map.cpp index c7d1d3b8..28d07022 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -28,6 +28,7 @@ #include <cassert> #include "beingmanager.h" +#include "configuration.h" #include "game.h" #include "graphics.h" #include "particle.h" @@ -41,6 +42,8 @@ #include "utils/dtor.h" #include "utils/tostring.h" +extern volatile int tick_time; + /** * A location on a tile map. Used for pathfinding, open list. */ @@ -63,6 +66,80 @@ struct Location MetaTile *tile; }; +MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer): + mX(x), mY(y), + mWidth(width), mHeight(height), + mIsFringeLayer(isFringeLayer) +{ + const int size = mWidth * mHeight; + mTiles = new Image*[size]; + std::fill_n(mTiles, size, (Image*) 0); +} + +MapLayer::~MapLayer() +{ + delete[] mTiles; +} + +void MapLayer::setTile(int x, int y, Image *img) +{ + mTiles[x + y * mWidth] = img; +} + +Image* MapLayer::getTile(int x, int y) const +{ + return mTiles[x + y * mWidth]; +} + +void MapLayer::draw(Graphics *graphics, + int startX, int startY, + int endX, int endY, + int scrollX, int scrollY, + const Sprites &sprites) const +{ + startX -= mX; + startY -= mY; + endX -= mX; + endY -= mY; + + if (startX < 0) startX = 0; + if (startY < 0) startY = 0; + if (endX > mWidth) endX = mWidth; + if (endY > mHeight) endY = mHeight; + + Sprites::const_iterator si = sprites.begin(); + + for (int y = startY; y < endY; y++) + { + // If drawing the fringe layer, make sure all sprites above this row of + // tiles have been drawn + if (mIsFringeLayer) { + while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } + + for (int x = startX; x < endX; x++) + { + Image *img = getTile(x, y); + if (img) { + const int px = (x + mX) * 32 - scrollX; + const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight(); + graphics->drawImage(img, px, py); + } + } + } + + // Draw any remaining sprites + if (mIsFringeLayer) { + while (si != sprites.end()) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } +} + Map::Map(int width, int height, int tileWidth, int tileHeight): mWidth(width), mHeight(height), mTileWidth(tileWidth), mTileHeight(tileHeight), @@ -70,31 +147,26 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): mOnClosedList(1), mOnOpenList(2), mLastScrollX(0.0f), mLastScrollY(0.0f) { - int size = mWidth * mHeight; + const int size = mWidth * mHeight; mMetaTiles = new MetaTile[size]; - for (int i=0; i < NB_BLOCKTYPES; i++) + for (int i = 0; i < NB_BLOCKTYPES; i++) { mOccupation[i] = new int[size]; memset(mOccupation[i], 0, size * sizeof(int)); } - mTiles = new Image*[size * 3]; - std::fill_n(mTiles, size * 3, (Image*)0); } Map::~Map() { - // clean up map data + // delete metadata, layers, tilesets and overlays delete[] mMetaTiles; - delete[] mTiles; for (int i=0; i < NB_BLOCKTYPES; i++) { delete[] mOccupation[i]; } - // clean up tilesets + for_each(mLayers.begin(), mLayers.end(), make_dtor(mLayers)); for_each(mTilesets.begin(), mTilesets.end(), make_dtor(mTilesets)); - mTilesets.clear(); - // clean up overlays for_each(mOverlays.begin(), mOverlays.end(), make_dtor(mOverlays)); } @@ -109,9 +181,9 @@ void Map::initializeOverlays() const std::string name = "overlay" + toString(i); Image *img = resman->getImage(getProperty(name + "image")); - float speedX = getFloatProperty(name + "scrollX"); - float speedY = getFloatProperty(name + "scrollY"); - float parallax = getFloatProperty(name + "parallax"); + const float speedX = getFloatProperty(name + "scrollX"); + const float speedY = getFloatProperty(name + "scrollY"); + const float parallax = getFloatProperty(name + "parallax"); if (img) { @@ -124,6 +196,11 @@ void Map::initializeOverlays() } } +void Map::addLayer(MapLayer *layer) +{ + mLayers.push_back(layer); +} + void Map::addTileset(Tileset *tileset) { mTilesets.push_back(tileset); @@ -137,63 +214,31 @@ bool spriteCompare(const Sprite *a, const Sprite *b) return a->getPixelY() < b->getPixelY(); } -void Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) +void Map::draw(Graphics *graphics, int scrollX, int scrollY) { int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1; - // If drawing the fringe layer, make sure sprites are sorted - SpriteIterator si; - if (layer == 1) - { - mSprites.sort(spriteCompare); - si = mSprites.begin(); - endPixelY += mMaxTileHeight - mTileHeight; - } + // TODO: Do this per-layer + endPixelY += mMaxTileHeight - mTileHeight; int startX = scrollX / mTileWidth; int startY = scrollY / mTileHeight; int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth; int endY = endPixelY / mTileHeight; - if (startX < 0) startX = 0; - if (startY < 0) startY = 0; - if (endX > mWidth) endX = mWidth; - if (endY > mHeight) endY = mHeight; + // Make sure sprites are sorted + mSprites.sort(spriteCompare); - for (int y = startY; y < endY; y++) - { - // If drawing the fringe layer, make sure all sprites above this row of - // tiles have been drawn - if (layer == 1) - { - while (si != mSprites.end() && (*si)->getPixelY() <= y * 32 - 32) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } - - for (int x = startX; x < endX; x++) - { - Image *img = getTile(x, y, layer); - if (img) { - graphics->drawImage(img, - x * mTileWidth - scrollX, - y * mTileHeight - scrollY + - mTileHeight - img->getHeight()); - } - } + Layers::const_iterator layeri = mLayers.begin(); + for (; layeri != mLayers.end(); ++layeri) { + (*layeri)->draw(graphics, + startX, startY, endX, endY, + scrollX, scrollY, + mSprites); } - // Draw any remaining sprites - if (layer == 1) - { - while (si != mSprites.end()) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } + drawOverlay(graphics, scrollX, scrollY, + (int) config.getValue("OverlayDetail", 2)); } void Map::drawCollision(Graphics *graphics, int scrollX, int scrollY) @@ -289,26 +334,10 @@ void Map::drawOverlay(Graphics *graphics, }; } -void Map::setTileWithGid(int x, int y, int layer, int gid) -{ - if (layer == 3) - { - Tileset *set = getTilesetWithGid(gid); - if (set && (gid - set->getFirstGid() != 0)) - { - blockTile(x, y, BLOCKTYPE_WALL); - } - } - else if (layer < 3) - { - setTile(x, y, layer, getTileWithGid(gid)); - } -} - class ContainsGidFunctor { public: - bool operator() (Tileset* set) + bool operator() (const Tileset* set) const { return (set->getFirstGid() <= gid && gid - set->getFirstGid() < (int)set->size()); @@ -326,17 +355,6 @@ Tileset* Map::getTilesetWithGid(int gid) const return (i == mTilesets.end()) ? NULL : *i; } -Image* Map::getTileWithGid(int gid) const -{ - Tileset *set = getTilesetWithGid(gid); - - if (set) { - return set->get(gid - set->getFirstGid()); - } - - return NULL; -} - void Map::blockTile(int x, int y, BlockType type) { if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight) @@ -412,16 +430,6 @@ bool Map::contains(int x, int y) const return x >= 0 && y >= 0 && x < mWidth && y < mHeight; } -void Map::setTile(int x, int y, int layer, Image *img) -{ - mTiles[x + y * mWidth + layer * (mWidth * mHeight)] = img; -} - -Image* Map::getTile(int x, int y, int layer) const -{ - return mTiles[x + y * mWidth + layer * (mWidth * mHeight)]; -} - MetaTile* Map::getMetaTile(int x, int y) const { return &mMetaTiles[x + y * mWidth]; @@ -484,8 +492,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w for (int dx = -1; dx <= 1; dx++) { // Calculate location of tile to check - int x = curr.x + dx; - int y = curr.y + dy; + const int x = curr.x + dx; + const int y = curr.y + dy; // Skip if if we're checking the same tile we're leaving from, // or if the new location falls outside of the map boundaries @@ -559,7 +567,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Update Gcost and Fcost of new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; if (x != destX || y != destY) { // Add this tile to the open list @@ -576,7 +584,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Found a shorter route. // Update Gcost and Fcost of the new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; // Set the current tile as the parent of the new tile newTile->parentX = curr.x; @@ -617,7 +625,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w return path; } -void Map::addParticleEffect (std::string effectFile, int x, int y) +void Map::addParticleEffect(const std::string &effectFile, int x, int y) { ParticleEffectData newEffect; newEffect.file = effectFile; |