Allow changing Tile type after insertion.

This commit is contained in:
Felix Ableitner 2013-08-20 21:44:11 +02:00
parent 0fccc7e3af
commit 9db73a7b93
4 changed files with 57 additions and 27 deletions

View file

@ -23,15 +23,7 @@ Sprite::Sprite(const Vector2f& position, Category category,
mShape.setTextureRect(sf::IntRect(Vector2i(), Vector2i(size))); mShape.setTextureRect(sf::IntRect(Vector2i(), Vector2i(size)));
setPosition(position); setPosition(position);
setDirection(direction); setDirection(direction);
try { setTexture(texture);
mTexture = ResourceManager::i().acquire(Loader::i()
.fromFile<sf::Texture>(texture));
mShape.setTexture(&*mTexture, false);
}
catch (thor::ResourceLoadingException&) {
LOG_W("Failed to load texture " << texture << ", coloring red.");
mShape.setFillColor(sf::Color(255, 0, 0));
}
} }
/** /**
@ -150,3 +142,21 @@ void
Sprite::setPosition(const Vector2f& position) { Sprite::setPosition(const Vector2f& position) {
mShape.setPosition(position); mShape.setPosition(position);
} }
/**
* Sets a new texture. The old one is discarded through smart pointers if
* it isn't used any more.
*/
void
Sprite::setTexture(const std::string& texture) {
try {
mTexture = ResourceManager::i().acquire(Loader::i()
.fromFile<sf::Texture>(texture));
mShape.setTexture(&*mTexture, false);
}
catch (thor::ResourceLoadingException&) {
LOG_W("Failed to load texture " << texture << ", coloring red.");
mShape.setFillColor(sf::Color(255, 0, 0));
}
}

View file

@ -64,6 +64,7 @@ protected:
void setSpeed(Vector2f direction, float speed); void setSpeed(Vector2f direction, float speed);
void setDirection(const Vector2f& direction); void setDirection(const Vector2f& direction);
void setPosition(const Vector2f& position); void setPosition(const Vector2f& position);
void setTexture(const std::string& texture);
private: private:
friend class CollisionModel; friend class CollisionModel;

View file

@ -14,20 +14,42 @@
#include "../util/Yaml.h" #include "../util/Yaml.h"
#include "../World.h" #include "../World.h"
const Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75); const Vector2i Tile::TILE_SIZE = Vector2i(75, 75);
/** /**
* Constructs a tile. * Constructs a tile. Use this over setTile if a tile has not been generated
* for the position yet.
* *
* @param pType Type of the tile to create. * @param pType Type of the tile to create.
* @param pPosition Position of the tile in tile coordinates.
* @param world Box2D world object.
*/ */
Tile::Tile(Type type, int x, int y) : Tile::Tile(const Vector2i& position, Type type) :
Rectangle(Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.y), Rectangle(Vector2f(thor::cwiseProduct(position, TILE_SIZE)),
CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0, CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0,
Yaml(getConfig(type))), Yaml(getConfig(type))), mType(type) {
mType(type) { }
/**
* Places a tile of type at position, removing an old tile of different type
* if one exists.
*
* Highly inefficient as World::getNearbySprites has to be searched for every call.
*/
void
Tile::setTile(const Vector2i& position, Type type, World& world) {
Vector2f worldPosition(thor::cwiseProduct(position, TILE_SIZE));
auto candidates = world.getNearbySprites(worldPosition, 1.0f);
for (auto& c : candidates) {
std::shared_ptr<Tile> converted = std::dynamic_pointer_cast<Tile>(c);
// Direct comparison of floats as both are from the same generation
// on the same CPU.
if (converted.get() != nullptr &&
converted->getPosition() == worldPosition &&
converted->getType() != type) {
world.remove(converted);
break;
}
}
world.insert(std::shared_ptr<Sprite>(new Tile(position, type)));
} }
/** /**
@ -41,7 +63,6 @@ Tile::getConfig(Type type) {
case Type::WALL: case Type::WALL:
return "tile_wall.yaml"; return "tile_wall.yaml";
default: default:
assert(false);
return ""; return "";
} }
} }

View file

@ -10,6 +10,8 @@
#include "../abstract/Rectangle.h" #include "../abstract/Rectangle.h"
class World;
/** /**
* Holds information about a single tile. * Holds information about a single tile.
*/ */
@ -19,20 +21,16 @@ public:
WALL, WALL,
FLOOR FLOOR
}; };
public:
explicit Tile(Type type, int x, int y);
Type getType() const;
public:
static const Vector2i TILE_SIZE; //< Tile size in pixels. static const Vector2i TILE_SIZE; //< Tile size in pixels.
public: public:
explicit Tile(const Vector2i& position, Type type);
Type getType() const;
static void setTile(const Vector2i& position, Type type, World& world);
static std::string getConfig(Type type); static std::string getConfig(Type type);
static bool isSolid(Type type); static bool isSolid(Type type);
private: private:
Type mType; Type mType;
}; };