summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcflip <cflip@cflip.net>2022-03-26 11:50:51 -0600
committercflip <cflip@cflip.net>2022-03-26 11:50:51 -0600
commit8e2fd5758b00036da965effbefdc76c1d373cd23 (patch)
tree3fe911af9e4ef648de856c3942b8fd6ba3cd91ff
parent42397536e79fdf68fb194de86bbeb3f1ed098eed (diff)
Implement sprite depth sorting
This algorithm draws the level in two passes; the ground and rail tiles are drawn first, then the train cars and walls. This method isn't perfect, but it'll do for now.
-rw-r--r--src/level.cpp64
-rw-r--r--src/train.cpp7
-rw-r--r--src/train.h1
3 files changed, 51 insertions, 21 deletions
diff --git a/src/level.cpp b/src/level.cpp
index d5893e6..dc02631 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -37,39 +37,61 @@ void Level::update()
}
}
+static Point2D GetSpriteForTile(uint8_t tile, int x, int y)
+{
+ Point2D result = { 0, 1 };
+ switch (TILE_TYPE(tile)) {
+ case TileGround:
+ result.x = (x + y) % 2;
+ result.y = 0;
+ break;
+ case TileWall:
+ result.x = 2;
+ result.y = 0;
+ break;
+ case TileTrack:
+ result.x = TILE_DATA(tile);
+ result.y = 2;
+ break;
+ }
+ return result;
+}
+
void Level::draw(Bitmap& bitmap, int xo, int yo)
{
for (int y = 0; y < m_height; ++y) {
for (int x = 0; x < m_width; ++x) {
auto tile = get(x, y);
+ if (TILE_TYPE(tile) == TileWall)
+ continue;
int xx = (x - y) * (TileSize / 2) - xo;
int yy = (x + y) * (TileSize / 4) - yo;
- int tx = 0;
- int ty = 1;
-
- switch (TILE_TYPE(tile)) {
- case TileGround:
- tx = (x + y) % 2;
- ty = 0;
- break;
- case TileWall:
- tx = 2;
- ty = 0;
- break;
- case TileTrack:
- tx = TILE_DATA(tile);
- ty = 2;
- break;
- }
-
- bitmap.blit(m_tileSprites, xx, yy, tx * TileSize, ty * TileSize, TileSize, TileSize);
+ Point2D textureIndex = GetSpriteForTile(tile, x, y);
+ bitmap.blit(m_tileSprites, xx, yy, textureIndex.x * TileSize, textureIndex.y * TileSize, TileSize, TileSize);
}
}
- for (auto& vehicle : m_vehicles) {
- vehicle.draw(bitmap, xo, yo);
+ for (int y = 0; y < m_height; ++y) {
+ for (int x = 0; x < m_width; ++x) {
+ auto vehiclesInTile = std::find_if(m_vehicles.begin(), m_vehicles.end(), [x, y](const auto& vehicle) {
+ return vehicle.getSpritePosition().x == x && vehicle.getSpritePosition().y == y;
+ });
+
+ while (vehiclesInTile != m_vehicles.end()) {
+ vehiclesInTile->draw(bitmap, xo, yo);
+ ++vehiclesInTile;
+ }
+
+ auto tile = get(x, y);
+ if (TILE_TYPE(tile) == TileWall) {
+ int xx = (x - y) * (TileSize / 2) - xo;
+ int yy = (x + y) * (TileSize / 4) - yo;
+ Point2D textureIndex = GetSpriteForTile(tile, x, y);
+ bitmap.blit(m_tileSprites, xx, yy, textureIndex.x * TileSize, textureIndex.y * TileSize, TileSize, TileSize);
+ }
+ }
}
}
diff --git a/src/train.cpp b/src/train.cpp
index cfbae97..080a357 100644
--- a/src/train.cpp
+++ b/src/train.cpp
@@ -57,6 +57,13 @@ void Train::setPosition(int tx, int ty)
findNextTile();
}
+Point2D Train::getSpritePosition() const
+{
+ int xi = ceil((float)x + (float)(m_nextX - x) * m_progress);
+ int yi = ceil((float)y + (float)(m_nextY - y) * m_progress);
+ return { xi, yi };
+}
+
void Train::addVehicle(Train* newTrain)
{
if (!m_prev) {
diff --git a/src/train.h b/src/train.h
index d47818e..c496db8 100644
--- a/src/train.h
+++ b/src/train.h
@@ -14,6 +14,7 @@ public:
void draw(Bitmap&, int, int);
void setPosition(int x, int y);
+ Point2D getSpritePosition() const;
void setSpeed(float speed) { m_speed = speed; };
// Add a vehicle to the end of this train
void addVehicle(Train*);