Support multiple map layers, fix transparent tiles

This commit is contained in:
Matthias Schiffer 2014-09-24 03:20:25 +02:00
parent ba321783e7
commit 3c995acde8
5 changed files with 52 additions and 34 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

View file

@ -35,13 +35,22 @@ std::shared_ptr<Map> Map::load(__attribute__((unused)) const std::string &name)
std::shared_ptr<Map> map(new Map(16, 16));
map->tileset.push_back("dirt");
map->tileset.push_back("horizontal_bar");
for (int i = 0; i < 2; i++)
map->tiles.emplace_back(new uint32_t[16*16]);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
if (4 <= i && i < 12 && 4 <= j && j < 12)
map->setTileAt(i, j, 1);
map->setTileAt(0, i, j, 1);
else
map->setTileAt(i, j, 0);
map->setTileAt(0, i, j, 0);
if (4 <= i && i < 12 && j == 8)
map->setTileAt(1, i, j, 2);
else
map->setTileAt(1, i, j, 0);
}
}

View file

@ -44,14 +44,14 @@ private:
std::vector<std::string> tileset;
size_t width, height;
std::unique_ptr<uint32_t[]> tiles;
std::vector<std::unique_ptr<uint32_t[]>> tiles;
std::shared_ptr<Entity> playerEntity;
mutable std::deque<std::shared_ptr<Entity>> entities;
Map(size_t width0, size_t height0)
: width(width0), height(height0), tiles(new uint32_t[width*height]) {
: width(width0), height(height0) {
}
public:
@ -79,18 +79,22 @@ public:
return height;
}
void setTileAt(size_t x, size_t y, uint32_t value) {
if (x >= width || y >= height)
throw std::range_error("Map::setTileAt: bad coordinates");
tiles[y*width + x] = value;
size_t getLayerCount() const {
return tiles.size();
}
uint32_t getTileAt(ssize_t x, ssize_t y) const {
if (x < 0 || (size_t)x >= width || y < 0 || (size_t)y >= height)
void setTileAt(size_t layer, size_t x, size_t y, uint32_t value) {
if (layer >= tiles.size() || x >= width || y >= height)
throw std::range_error("Map::setTileAt: bad coordinates");
tiles[layer][y*width + x] = value;
}
uint32_t getTileAt(size_t layer, ssize_t x, ssize_t y) const {
if (layer >= tiles.size() || x < 0 || (size_t)x >= width || y < 0 || (size_t)y >= height)
return 0;
return tiles[y*width + x];
return tiles[layer][y*width + x];
}
static std::shared_ptr<Map> load(const std::string &name);

View file

@ -48,12 +48,11 @@ MapView::MapView(const std::shared_ptr<Window> &window0,
amask = 0xff000000;
#endif
SpriteCache *spriteCache = window->getSpriteCache();
const std::vector<std::string> &tileset = map->getTileset();
SDL_Surface *surface = SDL_CreateRGBSurface(0, getTileSize()*tileset.size(), getTileSize(), 32, rmask, gmask, bmask, amask);
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
SpriteCache *spriteCache = window->getSpriteCache();
for (size_t i = 0; i < tileset.size(); i++) {
SDL_Rect rect = {
@ -63,7 +62,11 @@ MapView::MapView(const std::shared_ptr<Window> &window0,
.h = 0,
};
SDL_BlitSurface(spriteCache->get("tile", tileset[i]), nullptr, surface, &rect);
SDL_Surface *sprite = spriteCache->get("tile", tileset[i]);
SDL_SetSurfaceBlendMode(sprite, SDL_BLENDMODE_NONE);
SDL_BlitSurface(sprite, nullptr, surface, &rect);
SDL_SetSurfaceBlendMode(sprite, SDL_BLENDMODE_BLEND);
}
tiles = SDL_CreateTextureFromSurface(window->getRenderer(), surface);
@ -98,27 +101,29 @@ void MapView::render(float centerX, float centerY, uint64_t time) {
int baseX = viewport.first/2 - int(centerX * tilePixels) - tilePixels/2, baseY = viewport.second/2 - int(centerY * tilePixels) - tilePixels/2;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
uint32_t tile = map->getTileAt(x, y);
if (!tile)
continue;
for (size_t layer = 0; layer < map->getLayerCount(); layer++) {
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
uint32_t tile = map->getTileAt(layer, x, y);
if (!tile)
continue;
SDL_Rect src = {
.x = int(getTileSize()*(tile-1)),
.y = 0,
.w = getTileSize(),
.h = getTileSize(),
};
SDL_Rect src = {
.x = int(getTileSize()*(tile-1)),
.y = 0,
.w = getTileSize(),
.h = getTileSize(),
};
SDL_Rect dst = {
.x = baseX + x*tilePixels,
.y = baseY + y*tilePixels,
.w = tilePixels,
.h = tilePixels,
};
SDL_Rect dst = {
.x = baseX + x*tilePixels,
.y = baseY + y*tilePixels,
.w = tilePixels,
.h = tilePixels,
};
SDL_RenderCopy(window->getRenderer(), tiles, &src, &dst);
SDL_RenderCopy(window->getRenderer(), tiles, &src, &dst);
}
}
}