From af951b566ac668b9e251f37e374c4c4191eeb524 Mon Sep 17 00:00:00 2001 From: javidx9 Date: Sat, 19 Oct 2019 16:41:43 +0100 Subject: [PATCH] Added Isometric Demo --- Videos/OneLoneCoder_PGE_IsometricTiles.cpp | 214 +++++++++++++++++++++ Videos/isometric_demo.png | Bin 0 -> 6737 bytes 2 files changed, 214 insertions(+) create mode 100644 Videos/OneLoneCoder_PGE_IsometricTiles.cpp create mode 100644 Videos/isometric_demo.png diff --git a/Videos/OneLoneCoder_PGE_IsometricTiles.cpp b/Videos/OneLoneCoder_PGE_IsometricTiles.cpp new file mode 100644 index 0000000..4854ef3 --- /dev/null +++ b/Videos/OneLoneCoder_PGE_IsometricTiles.cpp @@ -0,0 +1,214 @@ +/* + Coding Quickie: Isometric Tiles + "Owww... My insides hurt :(" - javidx9 + + License (OLC-3) + ~~~~~~~~~~~~~~~ + + Copyright 2018-2019 OneLoneCoder.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions or derivations of source code must retain the above + copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions or derivative works in binary form must reproduce + the above copyright notice. This list of conditions and the following + disclaimer must be reproduced in the documentation and/or other + materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Relevant Video: https://youtu.be/ukkbNKTgf5U + + Links + ~~~~~ + YouTube: https://www.youtube.com/javidx9 + https://www.youtube.com/javidx9extra + Discord: https://discord.gg/WhwHUMV + Twitter: https://www.twitter.com/javidx9 + Twitch: https://www.twitch.tv/javidx9 + GitHub: https://www.github.com/onelonecoder + Patreon: https://www.patreon.com/javidx9 + Homepage: https://www.onelonecoder.com + + Author + ~~~~~~ + David Barr, aka javidx9, ŠOneLoneCoder 2019 +*/ + +#define OLC_PGE_APPLICATION +#include "olcPixelGameEngine.h" + +// Override base class with your custom functionality +class IsometricDemo : public olc::PixelGameEngine +{ +public: + IsometricDemo() + { + sAppName = "Coding Quickie: Isometric Tiles"; + } + +private: + // Number of tiles in world + olc::vi2d vWorldSize = { 14, 10 }; + + // Size of single tile graphic + olc::vi2d vTileSize = { 40, 20 }; + + // Where to place tile (0,0) on screen (in tile size steps) + olc::vi2d vOrigin = { 5, 1 }; + + // Sprite that holds all imagery + olc::Sprite *sprIsom = nullptr; + + // Pointer to create 2D world array + int *pWorld = nullptr; + +public: + bool OnUserCreate() override + { + // Load sprites used in demonstration + sprIsom = new olc::Sprite("isometric_demo.png"); + + // Create empty world + pWorld = new int[vWorldSize.x * vWorldSize.y]{ 0 }; + return true; + } + + bool OnUserUpdate(float fElapsedTime) override + { + Clear(olc::WHITE); + + // Get Mouse in world + olc::vi2d vMouse = { GetMouseX(), GetMouseY() }; + + // Work out active cell + olc::vi2d vCell = { vMouse.x / vTileSize.x, vMouse.y / vTileSize.y }; + + // Work out mouse offset into cell + olc::vi2d vOffset = { vMouse.x % vTileSize.x, vMouse.y % vTileSize.y }; + + // Sample into cell offset colour + olc::Pixel col = sprIsom->GetPixel(3 * vTileSize.x + vOffset.x, vOffset.y); + + // Work out selected cell by transforming screen cell + olc::vi2d vSelected = + { + (vCell.y - vOrigin.y) + (vCell.x - vOrigin.x), + (vCell.y - vOrigin.y) - (vCell.x - vOrigin.x) + }; + + // "Bodge" selected cell by sampling corners + if (col == olc::RED) vSelected += {-1, +0}; + if (col == olc::BLUE) vSelected += {+0, -1}; + if (col == olc::GREEN) vSelected += {+0, +1}; + if (col == olc::YELLOW) vSelected += {+1, +0}; + + // Handle mouse click to toggle if a tile is visible or not + if (GetMouse(0).bPressed) + { + // Guard array boundary + if (vSelected.x >= 0 && vSelected.x < vWorldSize.x && vSelected.y >= 0 && vSelected.y < vWorldSize.y) + ++pWorld[vSelected.y * vWorldSize.x + vSelected.x] %= 6; + } + + // Labmda function to convert "world" coordinate into screen space + auto ToScreen = [&](int x, int y) + { + return olc::vi2d + { + (vOrigin.x * vTileSize.x) + (x - y) * (vTileSize.x / 2), + (vOrigin.y * vTileSize.y) + (x + y) * (vTileSize.y / 2) + }; + }; + + // Draw World - has binary transparancy so enable masking + SetPixelMode(olc::Pixel::MASK); + + // (0,0) is at top, defined by vOrigin, so draw from top to bottom + // to ensure tiles closest to camera are drawn last + for (int y = 0; y < vWorldSize.y; y++) + { + for (int x = 0; x < vWorldSize.x; x++) + { + // Convert cell coordinate to world space + olc::vi2d vWorld = ToScreen(x, y); + + switch(pWorld[y*vWorldSize.x + x]) + { + case 0: + // Invisble Tile + DrawPartialSprite(vWorld.x, vWorld.y, sprIsom, 1 * vTileSize.x, 0, vTileSize.x, vTileSize.y); + break; + case 1: + // Visible Tile + DrawPartialSprite(vWorld.x, vWorld.y, sprIsom, 2 * vTileSize.x, 0, vTileSize.x, vTileSize.y); + break; + case 2: + // Tree + DrawPartialSprite(vWorld.x, vWorld.y - vTileSize.y, sprIsom, 0 * vTileSize.x, 1 * vTileSize.y, vTileSize.x, vTileSize.y * 2); + break; + case 3: + // Spooky Tree + DrawPartialSprite(vWorld.x, vWorld.y - vTileSize.y, sprIsom, 1 * vTileSize.x, 1 * vTileSize.y, vTileSize.x, vTileSize.y * 2); + break; + case 4: + // Beach + DrawPartialSprite(vWorld.x, vWorld.y - vTileSize.y, sprIsom, 2 * vTileSize.x, 1 * vTileSize.y, vTileSize.x, vTileSize.y * 2); + break; + case 5: + // Water + DrawPartialSprite(vWorld.x, vWorld.y - vTileSize.y, sprIsom, 3 * vTileSize.x, 1 * vTileSize.y, vTileSize.x, vTileSize.y * 2); + break; + } + } + } + + // Draw Selected Cell - Has varying alpha components + SetPixelMode(olc::Pixel::ALPHA); + + // Convert selected cell coordinate to world space + olc::vi2d vSelectedWorld = ToScreen(vSelected.x, vSelected.y); + + // Draw "highlight" tile + DrawPartialSprite(vSelectedWorld.x, vSelectedWorld.y, sprIsom, 0 * vTileSize.x, 0, vTileSize.x, vTileSize.y); + + // Go back to normal drawing with no expected transparency + SetPixelMode(olc::Pixel::NORMAL); + + // Draw Hovered Cell Boundary + //DrawRect(vCell.x * vTileSize.x, vCell.y * vTileSize.y, vTileSize.x, vTileSize.y, olc::RED); + + // Draw Debug Info + DrawString(4, 4, "Mouse : " + std::to_string(vMouse.x) + ", " + std::to_string(vMouse.y), olc::BLACK); + DrawString(4, 14, "Cell : " + std::to_string(vCell.x) + ", " + std::to_string(vCell.y), olc::BLACK); + DrawString(4, 24, "Selected: " + std::to_string(vSelected.x) + ", " + std::to_string(vSelected.y), olc::BLACK); + return true; + } +}; + + +int main() +{ + IsometricDemo demo; + if (demo.Construct(512, 480, 2, 2)) + demo.Start(); + return 0; +} \ No newline at end of file diff --git a/Videos/isometric_demo.png b/Videos/isometric_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..797ef4c505d983c17078825bf15b00ff83d52251 GIT binary patch literal 6737 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 literal 0 HcmV?d00001