diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/level.cpp | 64 | ||||
-rw-r--r-- | src/level.h | 7 | ||||
-rw-r--r-- | src/main.cpp | 106 | ||||
-rw-r--r-- | src/train.h | 10 | ||||
-rw-r--r-- | src/util.cpp | 17 | ||||
-rw-r--r-- | src/util.h | 21 | ||||
-rw-r--r-- | src/window.cpp | 1 |
9 files changed, 125 insertions, 107 deletions
@@ -7,16 +7,15 @@ third-party/sdl2/sdl2-build/ third-party/sdl2/sdl2-src/ third-party/sdl2/sdl2/ -# Visual Studio +# IDE generated files and folders Debug/ Release/ .vs/ +.idea/ *.sln *.vcxproj *.vcxproj.filters *.vcxproj.user - - build/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e71ff2..d290495 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ SET(SOURCES level.cpp main.cpp train.cpp + util.cpp window.cpp ) diff --git a/src/level.cpp b/src/level.cpp index b42608b..1e71799 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -1,7 +1,8 @@ #include "level.h" +#include "util.h" Level::Level(int width, int height) - : m_width(width), m_height(height) + : m_width(width), m_height(height), m_tileSprites("../res/tiles.png") { m_tiles = new uint8_t[width * height]; memset(m_tiles, 0, width * height); @@ -22,6 +23,67 @@ void Level::set(int x, int y, uint8_t tile) m_tiles[x + y * m_width] = tile; } +void Level::draw(Bitmap& bitmap, int xo, int yo) +{ + for (int y = 0; y < 32; ++y) { + for (int x = 0; x < 32; ++x) { + auto tile = get(x, y); + + int xx = (x - y) * (TileSize / 2) - xo; + int yy = (x + y) * (TileSize / 4) - yo; + + int tx = (x + y) % 2; + int ty = 0; + + if (tile == NorthSouth) { + tx = 0; + ty = 2; + } else if (tile == EastWest) { + tx = 1; + ty = 2; + } else if (tile == SouthEast) { + tx = 0; + ty = 3; + } else if (tile == SouthWest) { + tx = 3; + ty = 3; + } else if (tile == NorthWest) { + tx = 1; + ty = 3; + } else if (tile == NorthEast) { + tx = 2; + ty = 3; + } + + bitmap.blit(m_tileSprites, xx, yy, tx * 24, ty * 24, TileSize, TileSize); + } + } +} + +void Level::toggleTile(int x, int y) +{ + static const auto updateDirection = [&](int xt, int yt) { + if (get(xt, yt) > 0) + set(xt, yt, ChooseDirection(*this, xt, yt)); + }; + + if (inBounds(x, y)) { + auto tile = get(x, y); + + if (tile > 0) + tile = 0; + else + tile = ChooseDirection(*this, x, y); + + m_tiles[x + y * m_width] = tile; + + updateDirection(x - 1, y); + updateDirection(x + 1, y); + updateDirection(x, y - 1); + updateDirection(x, y + 1); + } +} + RailDirection ChooseDirection(Level& level, int x, int y) { if (!level.inBounds(x, y)) return NorthSouth; diff --git a/src/level.h b/src/level.h index 344d35f..948dfcb 100644 --- a/src/level.h +++ b/src/level.h @@ -1,5 +1,6 @@ #pragma once +#include "bitmap.h" #include <cstdint> #include <cstring> @@ -10,9 +11,13 @@ public: uint8_t get(int x, int y); void set(int x, int y, uint8_t tile); - bool inBounds(int x, int y) { return x >= 0 && x < m_width && y >= 0 && y < m_height; } + bool inBounds(int x, int y) const { return x >= 0 && x < m_width && y >= 0 && y < m_height; } + + void draw(Bitmap& bitmap, int xo, int yo); + void toggleTile(int x, int y); private: + Bitmap m_tileSprites; int m_width, m_height; uint8_t* m_tiles; }; diff --git a/src/main.cpp b/src/main.cpp index 4ac5167..7b22928 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,73 +1,9 @@ -#define SDL_MAIN_HANDLED -#include <cmath> - #include "bitmap.h" #include "level.h" #include "train.h" +#include "util.h" #include "window.h" -struct Point2D { - float x, y; -}; - -Point2D screenToTile(Point2D source) -{ - Point2D result; - - constexpr int TILE_SIZE = 24; - - float mx = source.x; - float my = source.y; - float xx = (mx / TILE_SIZE + my / (TILE_SIZE / 2.f)); - float yy = (my / (TILE_SIZE / 2.f) - (mx / TILE_SIZE)); - - result.x = floor(xx - 1.5f); // Magic numbers - result.y = floor(yy - 0.5f); - - return result; -} - -void DrawLevel(Bitmap& bitmap, Bitmap& tiles, Level& level, int xo, int yo) -{ - bitmap.clear(0xff224466); - - for (int y = 0; y < 32; ++y) { - for (int x = 0; x < 32; ++x) { - constexpr int TILE_SIZE = 24; - - auto tile = level.get(x, y); - - int xx = (x - y) * (TILE_SIZE / 2) - xo; - int yy = (x + y) * (TILE_SIZE / 4) - yo; - - int tx = (x + y) % 2; - int ty = 0; - - if (tile == NorthSouth) { - tx = 0; - ty = 2; - } else if (tile == EastWest) { - tx = 1; - ty = 2; - } else if (tile == SouthEast) { - tx = 0; - ty = 3; - } else if (tile == SouthWest) { - tx = 3; - ty = 3; - } else if (tile == NorthWest) { - tx = 1; - ty = 3; - } else if (tile == NorthEast) { - tx = 2; - ty = 3; - } - - bitmap.blit(tiles, xx, yy, tx * 24, ty * 24, TILE_SIZE, TILE_SIZE); - } - } -} - int main(int argc, char** argv) { constexpr int Height = 240; @@ -76,9 +12,7 @@ int main(int argc, char** argv) Window window("Nonortho", Width, Height, Scale); - Bitmap tiles("../res/tiles.png"); Level level(32, 32); - Bitmap bitmap(Width, Height); Train car; @@ -88,38 +22,19 @@ int main(int argc, char** argv) window.onMouseDown([&](int button, int x, int y) { if (button == 1) { - static const auto update_direction = [&](int xt, int yt) { - if (level.get(xt, yt) > 0) - level.set(xt, yt, ChooseDirection(level, xt, yt)); - }; + int mx = x / Scale + xOffs; + int my = y / Scale + yOffs; - float mx = x / Scale + xOffs; - float my = y / Scale + yOffs; - Point2D tilePos = screenToTile({ mx, my }); - - if (level.inBounds(tilePos.x, tilePos.y)) { - auto tile = level.get(tilePos.x, tilePos.y); - - if (tile > 0) - tile = 0; - else - tile = ChooseDirection(level, tilePos.x, tilePos.y); - - level.set(tilePos.x, tilePos.y, tile); - - update_direction(tilePos.x - 1, tilePos.y); - update_direction(tilePos.x + 1, tilePos.y); - update_direction(tilePos.x, tilePos.y - 1); - update_direction(tilePos.x, tilePos.y + 1); - } + Point2D tilePos = ScreenToTile({ mx, my }); + level.toggleTile(tilePos.x, tilePos.y); } else if (button == 2 && !isDragging) { xDrag = x; yDrag = y; isDragging = true; } else { - float mx = x / Scale + xOffs; - float my = y / Scale + yOffs; - auto pos = screenToTile({ mx, my }); + int mx = x / Scale + xOffs; + int my = y / Scale + yOffs; + auto pos = ScreenToTile({ mx, my }); car.setPosition(pos.x, pos.y); } }); @@ -140,9 +55,12 @@ int main(int argc, char** argv) while (!window.shouldClose()) { window.update(); - DrawLevel(bitmap, tiles, level, xOffs, yOffs); + bitmap.clear(0xff224466); + + level.draw(bitmap, xOffs, yOffs); car.update(level); car.draw(bitmap, xOffs, yOffs); + window.draw(bitmap); } diff --git a/src/train.h b/src/train.h index 43892f9..6f5cd23 100644 --- a/src/train.h +++ b/src/train.h @@ -1,13 +1,7 @@ #pragma once #include "bitmap.h" - -enum CarDirection { - North, - East, - South, - West -}; +#include "util.h" class Level; @@ -30,6 +24,6 @@ private: float m_speed { 0.05f }; float m_progress { 0.f }; - CarDirection m_dir { North }; + Direction m_dir { North }; int m_nextX { 0 }, m_nextY { 0 }; }; diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..3eaf143 --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,17 @@ +#include "util.h" +#include <cmath> + +Point2D ScreenToTile(Point2D source) +{ + Point2D result {}; + + auto fx = (float)source.x; + auto fy = (float)source.y; + float xx = (fx / TileSize + fy / (TileSize / 2.f)); + float yy = (fy / (TileSize / 2.f) - (fx / TileSize)); + + result.x = (int)floorf(xx - 1.5f); // Magic numbers + result.y = (int)floorf(yy - 0.5f); + + return result; +}
\ No newline at end of file diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..80b7896 --- /dev/null +++ b/src/util.h @@ -0,0 +1,21 @@ +#pragma once + +#include <cmath> + +struct Point2D { + int x, y; +}; + +enum Direction { + North, + East, + South, + West +}; + +constexpr int TileSize = 24; + +/* + * Converts screen coordinates to a tile on the map + */ +Point2D ScreenToTile(Point2D);
\ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp index a907aba..16c8d24 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,5 +1,6 @@ #include "window.h" +#define SDL_MAIN_HANDLED #include <SDL2/SDL.h> #include <cstdio> |