
Labyrinth of the Minotaur A simple roguelike/RPG using a nokia 5110 screen
Dependencies: N5110 PowerControl mbed
Diff: Game.cpp
- Revision:
- 26:0dd71fc0ede4
- Parent:
- 25:4d9841e579e2
- Child:
- 27:1ad2408ba702
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Game.cpp Fri May 08 11:47:26 2015 +0000 @@ -0,0 +1,1024 @@ +#include "Game.h" + +//Power Saving +int semihost_powerdown() +{ + uint32_t arg; + return __semihost(USR_POWERDOWN, &arg); +} + +//ISR +void ActPressed() +{ + ActFlag = 1; +} +void StartPressed() +{ + StartFlag = 1; +} +void DirPressed() +{ + DirFlag = 1; +} + + + +//High score system +void writeDataToFile() +{ + FILE *fp = fopen("/local/highscore.txt", "w"); // open 'highscore.txt' for writing + fprintf(fp,"%d\r\n",HScore1); // print score to file + fprintf(fp,"%d\r\n",HScore2); // print score to file + fprintf(fp,"%d\r\n",HScore3); // print score to file + fprintf(fp,"%d\r\n",HScore4); // print score to file + fclose(fp); // close file +} + +void readDataFromFile() +{ + FILE *fp = fopen("/local/highscore.txt", "r"); // open 'highscore.txt' for writing + fscanf(fp,"%d", &HScore1); // read score from file and save to int + fscanf(fp,"%d", &HScore2); // read score from file and save to int + fscanf(fp,"%d", &HScore3); // read score from file and save to int + fscanf(fp,"%d", &HScore4); // read score from file and save to int + fclose(fp); // close file +} + +void HighScoreCheck() +{ + readDataFromFile(); + + if(score >= HScore1) { + HScore4 = HScore3; + HScore3 = HScore2; + HScore2 = HScore1; + HScore1 = score; + } else if(score >= HScore2) { + HScore4 = HScore3; + HScore3 = HScore2; + HScore2 = score; + } else if(score >= HScore3) { + HScore4 = HScore3; + HScore3 = score; + } else if(score > HScore4) { + HScore4 = score; + } + + writeDataToFile(); +} + +//Game functions + +void DrawGraphic(int p, int x, int y) +{ + if(p == 0) { + for(int i = 0; i < 38; i++) { + for(int j = 0; j < 34; j++) { + + + if(HugeRat[i][j] == 1) { + + lcd.setPixel(y+i, x+j); + } + } + } + } +} + +void Intro() +{ + lcd.clear(); + lcd.printString("Labyrinth of", 12, 2); + lcd.printString("the Minotaur", 12, 3); + lcd.refresh(); + wait(1.0); +} + +void MainMenu() +{ + score = -100; + + level = 0; + + //Player Health + ph = 15; + + //Player weapon + pw = 0; //0 to 4 + + //Player armour + pa = 5; //5 to 9 + + int menu = 0; + + while (1) { + lcd.clear(); + if (menu == 0) { + lcd.printString("New Game <", 6, 1); + lcd.printString("High Scores", 6, 2); + lcd.printString("Options", 6, 3); + lcd.refresh(); + Sleep(); + } else if (menu == 1) { + lcd.printString("New Game", 6, 1); + lcd.printString("High Scores <", 6, 2); + lcd.printString("Options", 6, 3); + lcd.refresh(); + Sleep(); + } else { + lcd.printString("New Game", 6, 1); + lcd.printString("High Scores", 6, 2); + lcd.printString("Options <", 6, 3); + lcd.refresh(); + Sleep(); + } + + if (DirFlag) { + + DirFlag = 0; + + if(Up) { + if(menu > 0) { + menu--; + } + } else if(Down) { + if(menu < 3) { + menu++; + } + } + } + if (ActFlag) { + + ActFlag = 0; + + if (menu == 0) { + GameLoop(); + } else if (menu == 1) { + HighScoreScreen(); + } else { + Options(); + } + } + } +} + +void Options() +{ + + bool bright = 1; + + while(1) { + + lcd.setBrightness(bright); + lcd.clear(); + + if(bright == 1) { + lcd.printString("Backlight ON", 6, 2); + } else { + lcd.printString("Backlight OFF", 6, 2); + } + + lcd.refresh(); + if (DirFlag) { + + DirFlag = 0; + + bright = !bright; + } + if (ActFlag) { + ActFlag = 0; + } + if(StartFlag) { + + StartFlag = 0; + + MainMenu(); + + } + } +} + +void LevelScreen() +{ + char buffer[14]; + + int write = sprintf(buffer, "Level %d", level); // print formatted data to buffer + + lcd.clear(); + lcd.printString(buffer, 20, 2); + lcd.refresh(); + wait(1.0); +} + +void GameLoop() +{ + while (1) { + + //level++; + + level = 5; + + score = score + 100; + + World(); + + LevelScreen(); + + RevealMap(); //Uncomment for debugging to view map + + while (1) { + + ActFlag = 0; + StartFlag = 0; + DirFlag = 0; + + PlayerCamera(); + + if (map[px][py] == CHEST) { + Chest(); + } + + if (px == exx && py == exy) { + + if(level%5 == 0) { + BossFight = true; + Fight(); + } + + break; + + } + + Sleep(); + + + if (DirFlag) { + + DirFlag = 0; + + PlayerMove(); + + if (rand() % 40 == 0) { + if (ph < 15) { + ph++; + } + } + + if (rand() % 50 == 0) { + Fight(); + } + + } + if (StartFlag) { + + StartFlag = 0; + + StartMenu(); + } + if (ActFlag) { + + ActFlag = 0; + } + } + } +} + +void PlayerCamera() +{ + lcd.clear(); + + int tile; + + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 6; j++) { + + if (i == 6 && j == 2) { + lcd.printString("@", (6 * i) + 1, j); + } else { + int diffx = i - 6; + int diffy = j - 2; + + if (px + diffx < 84 && px + diffx > 0 && py + diffy < 48 && py + diffy > 0) { + tile = map[px + diffx][py + diffy]; + } else { + tile = WALL; + } + lcd.printChar(TileList[tile].Symbol, (6 * i) + 1, j); + + if (map[px + diffx][py + diffy] == FLOOR) { + map[px + diffx][py + diffy] = FLOOR_SEEN; + } + + } + } + } + lcd.refresh(); +} + +void PlayerMove() +{ + if (Up) { + int tile = map[px][py - 1]; + if (TileList[tile].Passable) { + py--; + } + } + if (Down) { + int tile = map[px][py + 1]; + if (TileList[tile].Passable) { + py++; + } + } + if (Right) { + int tile = map[px + 1][py]; + if (TileList[tile].Passable) { + px++; + } + } + if (Left) { + int tile = map[px - 1][py]; + if (TileList[tile].Passable) { + px--; + } + } +} + +void Fight() +{ + int m; + + lcd.clear(); + + if(BossFight) { + BossFight = false; + + m = 5; //Monster is a minotaur + + lcd.printString("BOSS!", 30, 2); + } else { + + int mr = level + 1; + + if (mr > 4) { + mr = 4; + lcd.printString("FIGHT!", 24, 2); + } + + m = rand() % mr; + } + + int mh = EnemyList[m].EHealth; + + for (int i = 0; i<5; i++) { + lcd.inverseMode(); + lcd.refresh(); + wait(0.2); + lcd.normalMode(); + lcd.refresh(); + wait(0.2); + } + + if(m==0) { + lcd.clear(); + DrawGraphic(m, 1, 1); + lcd.refresh(); + wait(2.0); + } + + bool menu = 1; + + while (1) { + ActFlag = 0; + StartFlag = 0; + DirFlag = 0; + + lcd.clear(); + + lcd.printString(EnemyList[m].EName, 0, 0); + char buffer1[14]; + int write = sprintf(buffer1, "%d/%d", mh, EnemyList[m].EHealth); // print formatted data to buffer + lcd.printString(buffer1, 54, 0); + + lcd.printString("You", 0, 2); + char buffer2[14]; + write = sprintf(buffer2, "%d/15", ph); // print formatted data to buffer + lcd.printString(buffer2, 54, 2); + + if (menu) { + lcd.printString("Fight <", 0, 4); + lcd.printString("Run", 0, 5); + } else { + lcd.printString("Fight", 0, 4); + lcd.printString("Run <", 0, 5); + } + lcd.refresh(); + Sleep(); + + if (DirFlag) { + DirFlag = 0; + menu = !menu; + } + if (ActFlag) { + ActFlag = 0; + if (menu) { //Fight + //Hit monster + if (rand() % 100 + 1 > EnemyList[m].EDodge) { //If monster doesn't dodge + + int damage = ItemList[pw].ItemValue - EnemyList[m].EArmour + rand() % 3 - rand() % 3; //Calculate damage + if (damage < 0) { + damage = 0; + } + mh = mh - damage; //Apply damage and calculate the monster's health + + char buffer3[14]; + write = sprintf(buffer3, "for %d damage", damage); // print formatted data to buffer + + lcd.clear(); + lcd.printString("You hit the", 0, 1); + lcd.printString(EnemyList[m].EName, 0, 2); + lcd.printString(buffer3, 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + + } else { //Monster dodges + lcd.clear(); + lcd.printString(EnemyList[m].EName, 0, 1); + lcd.printString("dodges your", 0, 2); + lcd.printString("attack", 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + } + + if (mh <= 0) { //Check if monster is dead + score = score + EnemyList[m].EPoints; + lcd.clear(); + lcd.printString("You win!", 18, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + break; + } + + MonsterAttack(m); + + + } else { //Run away + + score = score - 2; + + int b = rand() % 5; + + if (b == 0) { //Monster blocks the path + + lcd.clear(); + lcd.printString("You try to run", 0, 0); + lcd.printString("away but the", 0, 1); + lcd.printString("monster blocks", 0, 2); + lcd.printString("the path", 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + + MonsterAttack(m); + + } else { + + int s = rand() % 100 + 1; + + if (s > EnemyList[m].ESpd) { //If you outspeed monster + + lcd.clear(); + lcd.printString("You run away", 6, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + break; + + } else { + + lcd.clear(); + lcd.printString("You try to run", 0, 0); + lcd.printString("away but the", 0, 1); + lcd.printString("monster", 0, 2); + lcd.printString("catches up to", 0, 3); + lcd.printString("you", 0, 4); + lcd.refresh(); + wait(1.0); + Sleep(); + + MonsterAttack(m); + + } + + + } + } + } + } +} + +void MonsterAttack(int m) +{ + if (rand() % 100 + 1 < EnemyList[m].EHit) { //If monster hits and isn't dead + + int damage = EnemyList[m].EDamage - ItemList[pa].ItemValue + rand() % 3 - rand() % 3; //Calculate damage + if (damage < 0) { + damage = 0; + } + ph = ph - damage; //Apply damage and calculate the monster's health + + char buffer[14]; + int write = sprintf(buffer, "%d damage", damage); // print formatted data to buffer + + lcd.clear(); + lcd.printString(EnemyList[m].EName, 0, 1); + lcd.printString("hits you for", 0, 2); + lcd.printString(buffer, 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + + } else { //You dodge + lcd.clear(); + lcd.printString("You dodge the", 0, 1); + lcd.printString("monster's", 0, 2); + lcd.printString("attack", 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + } + if (ph <= 0) { //Check if player is dead + GameOver(); + } + +} + +void StartMenu() +{ + int menu = 0; + + char buffer[14]; + int write = sprintf(buffer, "Health %d/15", ph); // print formatted data to buffer + + + while (1) { + if (menu == 0) { + lcd.clear(); + lcd.printString(buffer, 0, 0); + lcd.printString("Map <", 0, 2); + lcd.printString("Map Legend", 0, 3); + lcd.printString("Inventory", 0, 4); + lcd.printString("Continue", 0, 5); + lcd.refresh(); + Sleep(); + } else if (menu == 1) { + lcd.clear(); + lcd.printString(buffer, 0, 0); + lcd.printString("Map", 0, 2); + lcd.printString("Map Legend <", 0, 3); + lcd.printString("Inventory", 0, 4); + lcd.printString("Continue", 0, 5); + lcd.refresh(); + Sleep(); + } else if (menu == 2) { + lcd.clear(); + lcd.printString(buffer, 0, 0); + lcd.printString("Map", 0, 2); + lcd.printString("Map Legend", 0, 3); + lcd.printString("Inventory <", 0, 4); + lcd.printString("Continue", 0, 5); + lcd.refresh(); + Sleep(); + } else if (menu == 3) { + lcd.clear(); + lcd.printString(buffer, 0, 0); + lcd.printString("Map", 0, 2); + lcd.printString("Map Legend", 0, 3); + lcd.printString("Inventory", 0, 4); + lcd.printString("Continue <", 0, 5); + lcd.refresh(); + Sleep(); + } + + if (DirFlag) { + DirFlag = 0; + if ((Down || Right) && menu < 3) { + menu++; + } else if ((Up || Left) && menu > 0) + menu--; + } + if (ActFlag) { + ActFlag = 0; + if (menu == 0) { + Map(); + } else if (menu == 1) { + MapLegend(); + } else if (menu == 2) { + Inventory(); + } else { + break; + } + } + if (StartFlag) { + StartFlag = 0; + } + } +} + +void Map() +{ + lcd.clear(); + DrawMap(); + while (!StartFlag) { + FlashPlayerLocation(); + } + StartFlag = 0; + ActFlag = 0; + DirFlag = 0; +} + +void DrawMap() +{ + //Draw map on screen + for (int i = 0; i<84; i++) { + for (int j = 0; j<48; j++) { + if (map[i][j] == FLOOR_SEEN || map[i][j] == CHEST_OPENED) { + lcd.clearPixel(i, j); + } else { + lcd.setPixel(i, j); + } + } + } + lcd.refresh(); +} + +void FlashPlayerLocation() +{ + lcd.setPixel(px, py); + lcd.refresh(); + wait(0.5); + lcd.clearPixel(px, py); + lcd.refresh(); + wait(0.5); +} + +void MapLegend() +{ + lcd.clear(); + lcd.printString("@ Player", 0, 0); + lcd.printString("# Wall", 0, 1); + lcd.printString(". Floor", 0, 2); + lcd.printString("= Chest", 0, 3); + lcd.printString("/ Open Chest", 0, 4); + + + while (1) { + Sleep(); + + if (ActFlag) { + ActFlag = 0; + } + if (DirFlag) { + DirFlag = 0; + break; + } + if (StartFlag) { + StartFlag = 0; + break; + } + } +} + +void Inventory() +{ + lcd.clear(); + lcd.printString("Armour:", 0, 0); + lcd.printString(ItemList[pa].ItemName, 0, 1); + char buffer1[14]; + int write = sprintf(buffer1, "+%d Armour", ItemList[pa].ItemValue); // print formatted data to buffer + lcd.printString(buffer1, 0, 2); + + lcd.printString("Weapon:", 0, 3); + lcd.printString(ItemList[pw].ItemName, 0, 4); + char buffer2[14]; + write = sprintf(buffer2, "+%d Damage", ItemList[pw].ItemValue); // print formatted data to buffer + lcd.printString(buffer2, 0, 5); + lcd.refresh(); + + while (1) { + Sleep(); + + if (ActFlag) { + ActFlag = 0; + } + if (DirFlag) { + DirFlag = 0; + break; + } + if (StartFlag) { + StartFlag = 0; + break; + } + } +} + +void Chest() +{ + score = score + 10; + + int c = rand() % 4; //0- Item, 1- Booby trap, 2- Map, Else- Potion + + if (c == 0) { + getItem(); + } else if (c == 1) { + BoobyTrap(); + } else if (c == 2) { + RevealMap(); + } else { + Potion(); + } + + map[px][py] = CHEST_OPENED; + +} + +void getItem() +{ + + int r = rand() % 10; + + DirFlag = 0; + + lcd.clear(); + lcd.printString("Do you want to", 0, 1); + lcd.printString("take the", 0, 2); + lcd.printString(ItemList[r].ItemName, 0, 3); + lcd.printString("-Yes (Action)", 0, 4); + lcd.printString("-No (Other)", 0, 5); + lcd.refresh(); + wait(1.0); + Sleep(); + + + if (ActFlag) { + + ActFlag = 0; + + if (r > 5) { + pa = r; + } else { + pw = r; + } + + lcd.clear(); + lcd.printString("You take the", 0, 1); + lcd.printString(ItemList[r].ItemName, 0, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + + } else { + + StartFlag = 0; + DirFlag = 0; + + lcd.clear(); + lcd.printString("You leave the", 0, 1); + lcd.printString(ItemList[r].ItemName, 0, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + } +} + +void BoobyTrap() +{ + + int damage = rand() % 5; + + if (damage != 0) { + + ph = ph - damage; + + char buffer[15]; + int write = sprintf(buffer, "You recive %d", damage); + + lcd.clear(); + lcd.printString("The chest is", 0, 0); + lcd.printString("booby trapped!", 0, 1); + lcd.printString(buffer, 0, 3); + lcd.printString("damage", 0, 4); + lcd.refresh(); + wait(1.0); + Sleep(); + + //Check if player is dead + if (ph < 0) { + GameOver(); + } + } else { + + lcd.clear(); + lcd.printString("The chest is", 0, 0); + lcd.printString("booby trapped", 0, 1); + lcd.printString("but the trap", 0, 2); + lcd.printString("fails", 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); + + } +} + +void RevealMap() +{ + + for (int i = 0; i < 84; i++) { + for (int j = 0; j < 48; j++) { + + if (map[i][j] == FLOOR) { + map[i][j] = FLOOR_SEEN; + } + } + } + + lcd.clear(); + lcd.printString("You find a map", 0, 0); + lcd.printString("of the current", 0, 1); + lcd.printString("level inside", 0, 2); + lcd.printString("the chest", 0, 3); + lcd.refresh(); + wait(1.0); + Sleep(); +} + +void Potion() +{ + + int p = rand() % 5; //0- Poison, 1- Teleport, Else- Full heal + + lcd.clear(); + lcd.printString("You find a", 0, 0); + lcd.printString("potion inside", 0, 1); + lcd.printString("the chest", 0, 2); + lcd.printString("Drink (Action)", 0, 4); + lcd.printString("Leave (Other)", 0, 5); + lcd.refresh(); + wait(1.0); + Sleep(); + + if (ActFlag) { //Potion drunk + ActFlag = 0; + + if (p == 0) { //Poison + + int damage = rand() % 4 + 1; + + ph = ph - damage; + + char buffer[15]; + int write = sprintf(buffer, "%d damage", damage); + + lcd.clear(); + lcd.printString("You drink the", 0, 0); + lcd.printString("potion and", 0, 1); + lcd.printString("suddenly feel", 0, 2); + lcd.printString("ill.", 0, 3); + lcd.printString("You take", 0, 4); + lcd.printString(buffer, 0, 5); + lcd.refresh(); + wait(1.0); + Sleep(); + + //Check if player is dead + if (ph < 0) { + GameOver(); + } + } else if (p == 1) { //Teleport + + lcd.clear(); + lcd.printString("You drink the", 0, 0); + lcd.printString("potion and", 0, 1); + lcd.printString("suddenly feel", 0, 2); + lcd.printString("your body", 0, 3); + lcd.printString("being", 0, 4); + lcd.printString("transported", 0, 5); + lcd.refresh(); + wait(1.0); + Sleep(); + + GameLoop(); + + } else { //Full heal + + ph = 15; + + lcd.clear(); + lcd.printString("You drink the", 0, 0); + lcd.printString("potion and", 0, 1); + lcd.printString("suddenly feel", 0, 2); + lcd.printString("all your", 0, 3); + lcd.printString("wounds heal", 0, 4); + lcd.refresh(); + wait(1.0); + Sleep(); + } + } else { //Leave the potion + DirFlag = 0; + StartFlag = 0; + lcd.clear(); + lcd.printString("You walk away", 0, 0); + lcd.printString("and leave the", 0, 1); + lcd.printString("potion", 0, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + } +} + +void GameOver() +{ + lcd.inverseMode(); + lcd.clear(); + lcd.printString("GAME OVER", 12, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + lcd.normalMode(); + ScoreScreen(); +} + +void ScoreScreen() +{ + char buffer[14]; + + int write = sprintf(buffer, "%d points", score); + + lcd.clear(); + lcd.printString("You scored", 6, 1); + lcd.printString(buffer, 6, 2); + lcd.refresh(); + wait(1.0); + Sleep(); + + HighScoreScreen(); +} + +void HighScoreScreen() +{ + + HighScoreCheck(); + + //readDataFromFile(); + + char buffer1[14]; + int write = sprintf(buffer1, "1. %d", HScore1); + + char buffer2[14]; + write = sprintf(buffer2, "2. %d", HScore2); + + char buffer3[14]; + write = sprintf(buffer3, "3. %d", HScore3); + + char buffer4[14]; + write = sprintf(buffer4, "4. %d", HScore4); + + lcd.clear(); + lcd.printString("High Scores", 6, 0); + lcd.printString(buffer1, 6, 2); + lcd.printString(buffer2, 6, 3); + lcd.printString(buffer3, 6, 4); + lcd.printString(buffer4, 6, 5); + lcd.refresh(); + wait(1.0); + Sleep(); + + MainMenu(); + +} + +int main() +{ + //Power Saving + PHY_PowerDown(); + int result = semihost_powerdown(); + + Up.rise(&DirPressed); + Down.rise(&DirPressed); + Right.rise(&DirPressed); + Left.rise(&DirPressed); + Start.rise(&StartPressed); + Act.rise(&ActPressed); + + //Generate random seed + srand(Noise * 1000000); + + //Initilize screen + lcd.init(); + + Intro(); + + MainMenu(); +} \ No newline at end of file