diff options
author | Philipp Sehmisch <crush@themanaworld.org> | 2009-01-06 14:33:20 +0100 |
---|---|---|
committer | Philipp Sehmisch <crush@themanaworld.org> | 2009-01-06 16:40:46 +0100 |
commit | 6b60673b0805fbab747924d1a0b6d9c66fc96f64 (patch) | |
tree | e40cc55a4d952bfb9bc89a41c3205c1d7bd90616 | |
parent | 090b4893a57a1b7e9c83f7db043843d35016fcff (diff) | |
download | mana-6b60673b0805fbab747924d1a0b6d9c66fc96f64.tar.gz mana-6b60673b0805fbab747924d1a0b6d9c66fc96f64.tar.bz2 mana-6b60673b0805fbab747924d1a0b6d9c66fc96f64.tar.xz mana-6b60673b0805fbab747924d1a0b6d9c66fc96f64.zip |
Added support for animated tiles.
-rw-r--r-- | src/map.cpp | 51 | ||||
-rw-r--r-- | src/map.h | 40 | ||||
-rw-r--r-- | src/resources/mapreader.cpp | 90 | ||||
-rw-r--r-- | src/utils/gettext.h | 44 |
4 files changed, 199 insertions, 26 deletions
diff --git a/src/map.cpp b/src/map.cpp index 6170adef..abe87dfd 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -62,6 +62,34 @@ struct Location MetaTile *tile; }; +TileAnimation::TileAnimation(Animation *ani): + mAnimation(ani), + mLastUpdate(tick_time), + mLastImage(NULL) +{ +} + +void TileAnimation::update() +{ + //update animation + mAnimation.update(tick_time - mLastUpdate); + mLastUpdate = tick_time; + + // exchange images + Image *img = mAnimation.getCurrentImage(); + if (img != mLastImage) + { + for (std::list<std::pair<MapLayer*, int> >::iterator i = mAffected.begin(); + i != mAffected.end(); + i++) + { + i->first->setTile(i->second, img); + } + mLastImage = img; + } + +} + MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer): mX(x), mY(y), mWidth(width), mHeight(height), @@ -79,7 +107,7 @@ MapLayer::~MapLayer() void MapLayer::setTile(int x, int y, Image *img) { - mTiles[x + y * mWidth] = img; + setTile(x + y * mWidth, img); } Image* MapLayer::getTile(int x, int y) const @@ -155,6 +183,7 @@ Map::~Map() delete_all(mLayers); delete_all(mTilesets); delete_all(mOverlays); + delete_all(mTileAnimations); } void Map::initializeOverlays() @@ -216,6 +245,15 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY) // Make sure sprites are sorted mSprites.sort(spriteCompare); + //update animated tiles + for (std::map<int, TileAnimation*>::iterator iAni = mTileAnimations.begin(); + iAni != mTileAnimations.end(); + iAni++) + { + iAni->second->update(); + } + + // draw the game world Layers::const_iterator layeri = mLayers.begin(); for (; layeri != mLayers.end(); ++layeri) { (*layeri)->draw(graphics, @@ -516,3 +554,14 @@ void Map::initializeParticleEffects(Particle* particleEngine) particleEngine->addEffect(i->file, i->x, i->y); } } + +TileAnimation* Map::getAnimationForGid(int gid) +{ + std::map<int, TileAnimation*>::iterator i = mTileAnimations.find(gid); + if (i == mTileAnimations.end()) + { + return NULL; + } else { + return i->second; + } +} @@ -28,6 +28,8 @@ #include "position.h" #include "properties.h" +#include "simpleanimation.h" + class AmbientOverlay; class Graphics; class Image; @@ -64,6 +66,23 @@ struct MetaTile }; /** + * Animation cycle of a tile image which changes the map accordingly. + */ +class TileAnimation +{ + public: + TileAnimation(Animation *ani); + void update(); + void addAffectedTile(MapLayer *layer, int index) + { mAffected.push_back(std::make_pair(layer, index)); } + private: + std::list<std::pair<MapLayer*, int> > mAffected; + SimpleAnimation mAnimation; + int mLastUpdate; + Image* mLastImage; +}; + +/** * A map layer. Stores a grid of tiles and their offset, and implements layer * rendering. */ @@ -88,6 +107,11 @@ class MapLayer void setTile(int x, int y, Image *img); /** + * Set tile image with x + y * width already known. + */ + void setTile(int index, Image *img) { mTiles[index] = img; } + + /** * Get tile image, with x and y in layer coordinates. */ Image *getTile(int x, int y) const; @@ -225,8 +249,18 @@ class Map : public Properties /** * Initializes all added particle effects */ - void - initializeParticleEffects(Particle* particleEngine); + void initializeParticleEffects(Particle* particleEngine); + + /** + * Adds a tile animation to the map + */ + void addAnimation(int gid, TileAnimation *animation) + { mTileAnimations[gid] = animation; } + + /** + * Gets the tile animation for a specific gid + */ + TileAnimation *getAnimationForGid(int gid); private: /** @@ -270,6 +304,8 @@ class Map : public Properties int y; }; std::list<ParticleEffectData> particleEffects; + + std::map<int, TileAnimation*> mTileAnimations; }; #endif diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 835e52b3..4e116889 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -304,7 +304,8 @@ void MapReader::readProperties(xmlNodePtr node, Properties *props) static void setTile(Map *map, MapLayer *layer, int x, int y, int gid) { const Tileset * const set = map->getTilesetWithGid(gid); - if (layer) { + if (layer) + { // Set regular tile on a layer Image * const img = set ? set->get(gid - set->getFirstGid()) : 0; layer->setTile(x, y, img); @@ -407,6 +408,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map) setTile(map, layer, x, y, gid); + TileAnimation* ani = map->getAnimationForGid(gid); + if (ani) + { + ani->addAffectedTile(layer, x + y * w); + } + x++; if (x == w) { x = 0; y++; @@ -452,10 +459,12 @@ Tileset *MapReader::readTileset(xmlNodePtr node, const std::string &path, Map *map) { + Tileset *set = NULL; + if (xmlHasProp(node, BAD_CAST "source")) { logger->log("Warning: External tilesets not supported yet."); - return NULL; + return set; } const int firstGid = XML::getProperty(node, "firstgid", 0); @@ -464,34 +473,69 @@ Tileset *MapReader::readTileset(xmlNodePtr node, for_each_xml_child_node(childNode, node) { - if (!xmlStrEqual(childNode->name, BAD_CAST "image")) - continue; + if (xmlStrEqual(childNode->name, BAD_CAST "image")) + { + const std::string source = XML::getProperty(childNode, "source", ""); - const std::string source = XML::getProperty(childNode, "source", ""); + if (!source.empty()) + { + std::string sourceStr = source; + sourceStr.erase(0, 3); // Remove "../" + + ResourceManager *resman = ResourceManager::getInstance(); + Image* tilebmp = resman->getImage(sourceStr); - if (!source.empty()) + if (tilebmp) + { + set = new Tileset(tilebmp, tw, th, firstGid); + tilebmp->decRef(); + } + else { + logger->log("Warning: Failed to load tileset (%s)", + source.c_str()); + } + } + } + else if (xmlStrEqual(childNode->name, BAD_CAST "tile")) { - std::string sourceStr = source; - sourceStr.erase(0, 3); // Remove "../" + for_each_xml_child_node(tileNode, childNode) + { + if (!xmlStrEqual(tileNode->name, BAD_CAST "properties")) continue; - ResourceManager *resman = ResourceManager::getInstance(); - Image* tilebmp = resman->getImage(sourceStr); + int tileGID = firstGid + XML::getProperty(childNode, "id", 0); - if (tilebmp) - { - Tileset *set = new Tileset(tilebmp, tw, th, firstGid); - tilebmp->decRef(); - return set; - } - else { - logger->log("Warning: Failed to load tileset (%s)", - source.c_str()); + // read tile properties to a map for simpler handling + std::map<std::string, int> tileProperties; + for_each_xml_child_node(propertyNode, tileNode) + { + if (!xmlStrEqual(propertyNode->name, BAD_CAST "property")) continue; + std::string name = XML::getProperty(propertyNode, "name", ""); + int value = XML::getProperty(propertyNode, "value", 0); + tileProperties[name] = value; + logger->log("Tile Prop of %d \"%s\" = \"%d\"", tileGID, name.c_str(), value); + } + + // create animation + if (!set) continue; + + Animation *ani = new Animation(); + for (int i = 0; ;i++) + { + std::map<std::string, int>::iterator iFrame, iDelay; + iFrame = tileProperties.find("animation-frame" + toString(i)); + iDelay = tileProperties.find("animation-delay" + toString(i)); + if (iFrame != tileProperties.end() && iDelay != tileProperties.end()) + { + ani->addFrame(set->get(iFrame->second), iDelay->second, 0, 0); + } else { + break; + } + } + map->addAnimation(tileGID, new TileAnimation(ani)); + logger->log("Animation length: %d", ani->getLength()); } } - - // Only one image element expected - break; } - return NULL; + return set; } diff --git a/src/utils/gettext.h b/src/utils/gettext.h new file mode 100644 index 00000000..0cd9114b --- /dev/null +++ b/src/utils/gettext.h @@ -0,0 +1,44 @@ +/* + * The Mana World + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _TMW_UTILS_GETTEXT_H +#define _TMW_UTILS_GETTEXT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if ENABLE_NLS + +#include <libintl.h> + +#define _(s) ((char const *)gettext(s)) +#define N_(s) ((char const *)s) + +#else + +#define gettext(s) ((char const *)s) +#define _(s) ((char const *)s) +#define N_(s) ((char const *)s) + +#endif + +#endif |