diff --git a/FroggerSprites/bus.spr b/FroggerSprites/bus.spr new file mode 100644 index 0000000..29f534f Binary files /dev/null and b/FroggerSprites/bus.spr differ diff --git a/FroggerSprites/car1.spr b/FroggerSprites/car1.spr new file mode 100644 index 0000000..64a40e0 Binary files /dev/null and b/FroggerSprites/car1.spr differ diff --git a/FroggerSprites/car2.spr b/FroggerSprites/car2.spr new file mode 100644 index 0000000..5008614 Binary files /dev/null and b/FroggerSprites/car2.spr differ diff --git a/FroggerSprites/frog.spr b/FroggerSprites/frog.spr new file mode 100644 index 0000000..f412d04 Binary files /dev/null and b/FroggerSprites/frog.spr differ diff --git a/FroggerSprites/home.spr b/FroggerSprites/home.spr new file mode 100644 index 0000000..744ed20 Binary files /dev/null and b/FroggerSprites/home.spr differ diff --git a/FroggerSprites/log.spr b/FroggerSprites/log.spr new file mode 100644 index 0000000..9c81d4c Binary files /dev/null and b/FroggerSprites/log.spr differ diff --git a/FroggerSprites/pavement.spr b/FroggerSprites/pavement.spr new file mode 100644 index 0000000..2fa6302 Binary files /dev/null and b/FroggerSprites/pavement.spr differ diff --git a/FroggerSprites/wall.spr b/FroggerSprites/wall.spr new file mode 100644 index 0000000..7817eae Binary files /dev/null and b/FroggerSprites/wall.spr differ diff --git a/FroggerSprites/water.spr b/FroggerSprites/water.spr new file mode 100644 index 0000000..250f77c Binary files /dev/null and b/FroggerSprites/water.spr differ diff --git a/OneLoneCoder_Frogger.cpp b/OneLoneCoder_Frogger.cpp new file mode 100644 index 0000000..d65514b --- /dev/null +++ b/OneLoneCoder_Frogger.cpp @@ -0,0 +1,201 @@ +/* +OneLoneCoder.com - Code-It-Yourself! Frogger at the command prompt (quick and simple c++) +"Ribbet" - @Javidx9 + +Disclaimer +~~~~~~~~~~ +I don't care what you use this for. It's intended to be educational, and perhaps +to the oddly minded - a little bit of fun. Please hack this, change it and use it +in any way you see fit. BUT, you acknowledge that I am not responsible for anything +bad that happens as a result of your actions. However, if good stuff happens, I +would appreciate a shout out, or at least give the blog some publicity for me. +Cheers! + +Background +~~~~~~~~~~ +This is a bit of an unusual one. The games mechanics are very simple, but as soon +as you add graphics the code almost doubles in size! By standardising how the +lanes work and interact with the frog, the game pretty much controls itself, meaning +the game code is really really short. Everything else is eye candy. + +Controls +~~~~~~~~ +Arrow keys move frog. Cross the road, then the river, to get frog to safety. + +Author +~~~~~~ +Twitter: @javidx9 +Blog: www.onelonecoder.com + +Video: +~~~~~~ +https://youtu.be/QJnZ5QmpXOE + +Last Updated: 20/08/2017 +*/ + +#include +#include +using namespace std; + +#include "olcConsoleGameEngine.h" + + +class OneLoneCoder_Frogger : public olcConsoleGameEngine +{ +public: + OneLoneCoder_Frogger() + { + m_sAppName = L"Frogger"; + } + +private: + vector> vecLanes = + { + {0.0f, L"wwwhhwwwhhwwwhhwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"}, // 64 elements per lane + {-3.0f, L",,,jllk,,jllllk,,,,,,,jllk,,,,,jk,,,jlllk,,,,jllllk,,,,jlllk,,,,"}, + {3.0f, L",,,,jllk,,,,,jllk,,,,jllk,,,,,,,,,jllk,,,,,jk,,,,,,jllllk,,,,,,,"}, + {2.0f, L",,jlk,,,,,jlk,,,,,jk,,,,,jlk,,,jlk,,,,jk,,,,jllk,,,,jk,,,,,,jk,,"}, + {0.0f, L"pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"}, + {-3.0f, L"....asdf.......asdf....asdf..........asdf........asdf....asdf..."}, + { 3.0f, L".....ty..ty....ty....ty.....ty........ty..ty.ty......ty.......ty"}, + {-4.0f, L"..zx.....zx.........zx..zx........zx...zx...zx....zx...zx...zx.."}, + {2.0f, L"..ty.....ty.......ty.....ty......ty..ty.ty.......ty....ty......."}, + {0.0f, L"pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp"} + }; + + float fTimeSinceStart = 0.0f; + float fFrogX = 8.0f; + float fFrogY = 9.0f; + int nLaneWidth = 18; + int nCellSize = 8; + + bool *bufDanger = nullptr; + + olcSprite *spriteBus = nullptr; + olcSprite *spriteLog = nullptr; + olcSprite *spriteWater = nullptr; + olcSprite *spriteFrog = nullptr; + olcSprite *spritePavement = nullptr; + olcSprite *spriteCar1 = nullptr; + olcSprite *spriteCar2 = nullptr; + olcSprite *spriteWall = nullptr; + olcSprite *spriteHome = nullptr; + +protected: + // Called by olcConsoleGameEngine + virtual bool OnUserCreate() + { + bufDanger = new bool[ScreenWidth() * ScreenHeight()]; + memset(bufDanger, 0, ScreenWidth() * ScreenHeight() * sizeof(bool)); + + // You'll need these sprites! + + spriteBus = new olcSprite(L"FroggerSprites/bus.spr"); + spriteLog = new olcSprite(L"FroggerSprites/log.spr"); + spriteWater = new olcSprite(L"FroggerSprites/water.spr"); + spriteFrog = new olcSprite(L"FroggerSprites/frog.spr"); + spritePavement = new olcSprite(L"FroggerSprites/pavement.spr"); + spriteWall = new olcSprite(L"FroggerSprites/wall.spr"); + spriteHome = new olcSprite(L"FroggerSprites/home.spr"); + spriteCar1 = new olcSprite(L"FroggerSprites/car1.spr"); + spriteCar2 = new olcSprite(L"FroggerSprites/car2.spr"); + return true; + } + + // Called by olcConsoleGameEngine + virtual bool OnUserUpdate(float fElapsedTime) + { + fTimeSinceStart += fElapsedTime; + + // Handle Input + if (m_keys[VK_UP].bReleased) fFrogY -= 1.0f; + if (m_keys[VK_DOWN].bReleased) fFrogY += 1.0f; + if (m_keys[VK_LEFT].bReleased) fFrogX -= 1.0f; + if (m_keys[VK_RIGHT].bReleased) fFrogX += 1.0f; + + // Frog is moved by platforms + if (fFrogY <= 3) fFrogX -= fElapsedTime * vecLanes[(int)fFrogY].first; + + // Collision detection - check four corners of frog against danger buffer + bool tl = bufDanger[(int)(fFrogY*nCellSize + 1) * ScreenWidth() + (int)(fFrogX*nCellSize + 1)]; + bool tr = bufDanger[(int)(fFrogY*nCellSize + 1) * ScreenWidth() + (int)((fFrogX+1)*nCellSize - 1)]; + bool bl = bufDanger[(int)((fFrogY+1)*nCellSize - 1) * ScreenWidth() + (int)(fFrogX*nCellSize + 1)]; + bool br = bufDanger[(int)((fFrogY+1)*nCellSize - 1) * ScreenWidth() + (int)((fFrogX+1)*nCellSize - 1)]; + + if (tl || tr || bl || br) + { + // Frogs been hit :-( + fFrogX = 8.0f; + fFrogY = 9.0f; + } + + // Draw Lanes + int x=-1, y=0; + for (auto lane : vecLanes) + { + // Find lane offset start + int nStartPos = (int)(fTimeSinceStart * lane.first) % 64; + int nCellOffset = (int)((float)nCellSize* fTimeSinceStart * lane.first) % nCellSize; + if (nStartPos < 0) nStartPos = 64 - (abs(nStartPos) % 64); + + for (int i = 0; i < nLaneWidth; i++) + { + // Draw Graphics + wchar_t graphic = lane.second[(nStartPos + i) % 64]; + //Fill((x + i)*nCellSize - nCellOffset, y*nCellSize, (x + i + 1)*nCellSize - nCellOffset, (y + 1)*nCellSize, graphic); + + + + switch (graphic) // Graphics always make code verbose and less clear + { + case L'a': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteBus, 0, 0, 8, 8); break; // Bus 1 + case L's': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteBus, 8, 0, 8, 8); break; // Bus 2 + case L'd': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteBus, 16, 0, 8, 8); break; // Bus 3 + case L'f': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteBus, 24, 0, 8, 8); break; // Bus 4 + + case L'j': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteLog, 0, 0, 8, 8); break; // Log Start + case L'l': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteLog, 8, 0, 8, 8); break; // Log Middle + case L'k': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteLog, 16, 0, 8, 8); break; // Log End + + case L'z': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteCar1, 0, 0, 8, 8); break; // Car1 Back + case L'x': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteCar1, 8, 0, 8, 8); break; // Car1 Front + + case L't': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteCar2, 0, 0, 8, 8); break; // Car2 Back + case L'y': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteCar2, 8, 0, 8, 8); break; // Car2 Front + + case L'w': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteWall, 0, 0, 8, 8); break; // Wall + case L'h': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteHome, 0, 0, 8, 8); break; // Home + case L',': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spriteWater, 0, 0, 8, 8); break; // Water + case L'p': DrawPartialSprite((x + i)*nCellSize - nCellOffset, y*nCellSize, spritePavement, 0, 0, 8, 8); break; // Pavement + case L'.': Fill((x + i)*nCellSize - nCellOffset, y*nCellSize, (x + i + 1)*nCellSize - nCellOffset, (y + 1)*nCellSize, L' '); break; // Road + } + + // Fill Danger buffer + for (int j = (x + i)*nCellSize - nCellOffset; j < (x + i + 1)*nCellSize - nCellOffset; j++) + for (int k = y*nCellSize; k < (y + 1)*nCellSize; k++) + if (j >= 0 && j < ScreenWidth() && k >= 0 && k < ScreenHeight()) + bufDanger[k*ScreenWidth() + j] = + !(graphic == L'.' || + graphic == L'j' || graphic == L'k' || graphic == L'l' || + graphic == L'p' || + graphic == L'h'); + } + y++; + } + + // Draw Frog + DrawSprite(fFrogX*nCellSize, fFrogY*nCellSize, spriteFrog); + return true; + } +}; + + +int main() +{ + // Use olcConsoleGameEngine derived app + OneLoneCoder_Frogger game; + game.ConstructConsole(128, 80, 12, 12); + game.Start(); + return 0; +} \ No newline at end of file