Support multiple map layers, fix transparent tiles
This commit is contained in:
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 |
BIN
resources/sprite/tile/horizontal_bar.png
Normal file
BIN
resources/sprite/tile/horizontal_bar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 118 B |
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue