//copyright Tord Hjalt #include // sleep etc. #include //for cin, cout #include //for string #include //for vector #include //for random shuffle vectors #include //for files #include //for threads #include //for cout layout: setw(n) using namespace std; #define SCREEN_WIDTH 70 // window width #define SCREEN_HEIGHT 25 // window height #define VK_w 0x57 //WASD keys as VK-codes! Works with both w, W etc #define VK_a 0x41 #define VK_s 0x53 #define VK_d 0x44 #define VK_q 0x51 //q, Q void DrawWorld(CHAR_INFO screenBuffer[]); void DrawWon(string Str, int X, int Y, WORD color); bool CheckInput(); //checks user input void HandleInput(CHAR_INFO screenBuffer[]); //acts on user key void NextLevel(CHAR_INFO screenBuffer[], int a); int DaKeyCode = 0; int bKeyDown = 0; bool mUp = false; bool mRight = false; bool mLeft = false; COORD cHero = {2,23 }; //start position void play_music() { PlaySound("mixkit-comical-2.wav", NULL, SND_FILENAME|SND_LOOP|SND_ASYNC); } vectorvHighscores(25000); //fixed vector for highscores vectorvUsers; vectorAllUsersIn; vectoriPointsIn; vectoriPoints; vectorAllUsers; int Placer = 0; int Score = 0; int Empty = 0; string sTest; string sNamn; //Declare function for highscore list: void fHighscores(void); int Points = 0; int XPoints = 0; int main() { CHAR_INFO screenBuffer[SCREEN_WIDTH * SCREEN_HEIGHT] = {0}; int Time1 = 0; int Time2 = 0; int Elapsed = 0; int TrapTime1 = 0; int TrapTime2 = 0; int TrapElapsed = 0; int Trap2Time1 = 0; int Trap2Time2 = 0; int Trap2Elapsed = 0; int Trap3Time1 = 0; int Trap3Time2 = 0; int Trap3Elapsed = 0; int FlyXTime1 = 0; int FlyXTime2 = 0; int FlyXElapsed = 0; int TotalTime1 = 0; int TotalTime2 = 0; int TotalElapsed = 0; int iJump = 0; bool bTrap = false; bool bTrap2 = false; bool bTrap3 = false; bool bDeathWallOn = false; bool bSwitcher = false; bool bAnotherX = true; int FlyX = 0; int iFly = 0; //intro screen_ DrawWon("M M OO RRRR I A ", 10, 4, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("M M M M O O R R I A A", 10, 5, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("M M M O O R RR I AAAAA", 10, 6, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("M M O O R R I A A", 10, 7, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("M M OO R R I A A ", 10, 8, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon(" SYS ", 10, 9, FOREGROUND_RED | FOREGROUND_INTENSITY); DrawWon(" ", 10, 10, FOREGROUND_RED | FOREGROUND_INTENSITY); DrawWon("Tord Hjalt 2022.", 10, 11, FOREGROUND_RED | FOREGROUND_INTENSITY); DrawWon(" ", 10, 12, FOREGROUND_RED | FOREGROUND_INTENSITY); DrawWon("A: left, D: right, W: jump.", 10, 13, FOREGROUND_GREEN | FOREGROUND_INTENSITY); DrawWon("Jump down from heights. Go under red !: next level.", 10, 14, FOREGROUND_GREEN | FOREGROUND_INTENSITY); // cout << Level; //move cursor: DrawWon(" ", 1, 1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white Sleep(5000); //erase sign: for (int x = 1; x < SCREEN_WIDTH; x++) { for (int y = 1; y < SCREEN_HEIGHT; y++) { screenBuffer[x + y * SCREEN_WIDTH].Char.AsciiChar = '8'; screenBuffer[x + y * SCREEN_WIDTH].Attributes = 0; } } DrawWorld(screenBuffer); int Level = 1; // starts at level 1 fHighscores(); DrawWon("Enter your name.", 25, 15, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cin >> sNamn; Sleep(2000); DrawWon(" ", 5, 5, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white' DrawWon(" ", 1, 1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white //design floor plan, kevel 1: for (int i = 1; i < 70; i++) { screenBuffer[i + 24 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[i + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int j = 5; j < 10; j++) { screenBuffer[j + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[j + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int k = 25; k < 30; k++) { screenBuffer[k + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int m = 55; m < 60; m++) { screenBuffer[m + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 20 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 20 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int n = 50; n < 55; n++) { screenBuffer[n + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[n + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[n + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[n + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } //put magic boxes: screenBuffer[15 + 19 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[15 + 19 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; screenBuffer[40 + 20 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[40 + 20 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; //exit tunnel to next level: screenBuffer[67 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[67 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; //Place hero/player: screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //draw design and hero to screen: DrawWorld(screenBuffer); Sleep(1000); std::thread t(play_music);//background music DrawWon("Level:", 71, 2, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << Level; //start timers: Time1 = GetTickCount(); TrapTime1 = GetTickCount(); Trap2Time1 = GetTickCount(); Trap3Time1 = GetTickCount(); FlyXTime1 = GetTickCount(); TotalTime1 = GetTickCount(); //////////////////// G A M E L O O P ////////////////////////////// while(1) { if(CheckInput()) //if user pressed a key: HandleInput(screenBuffer); //om krockar med mur av # framför: if(((screenBuffer[(cHero.X + 1) + (cHero.Y) * SCREEN_WIDTH].Char.AsciiChar == '#') && (mRight)) || ((screenBuffer[(cHero.X - 1) + (cHero.Y) * SCREEN_WIDTH].Char.AsciiChar == '#') && (mLeft))) { Beep(700,50); int Krockad = cHero.X; if(mRight) cHero.X--; //flyttas tillbaka igen if(mLeft) cHero.X++; //flyttas tillbaka igen screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //sudda den som krockat: screenBuffer[Krockad + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[Krockad + cHero.Y * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); } //om krockar med box ovanför if (screenBuffer[ cHero.X + (cHero.Y - 1) * SCREEN_WIDTH].Char.AsciiChar == '.') { XPoints = XPoints + (Level * 1); //more points at higher levels DrawWon(" ", 71, 4, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white DrawWon("Points:", 71, 4, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << XPoints; Beep(800,50); int Skallad = cHero.Y; cHero.Y++; //flyttas tillbaka igen screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //sudda den som krockat: screenBuffer[cHero.X + Skallad * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[cHero.X + Skallad * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); } //hoppa upp: if(mUp) { COORD OldcHeroUx; Time2 = GetTickCount(); Elapsed = Time2 - Time1; if(Elapsed > 70) { Time1 = GetTickCount();//reset Elapsed = 0;//reset iJump++; if((cHero.Y > 1)&&(iJump < 5)) { OldcHeroUx = cHero; cHero.Y--; //move up 1 if((mRight)&&(cHero.X < 68))cHero.X++; //also right else if((mLeft)&&(cHero.X > 1))cHero.X--; //also left } else if(iJump > 4) { OldcHeroUx = cHero; if(cHero.Y < 23) cHero.Y++; //fall back down if( screenBuffer[ cHero.X + (cHero.Y +1) * SCREEN_WIDTH].Char.AsciiChar == '#') //hit floor { mUp = false; iJump = 0; //reset } else if( screenBuffer[ cHero.X + (cHero.Y +1) * SCREEN_WIDTH].Char.AsciiChar == '*') //danger things { t.detach(); //stops thread with background music PlaySound("mixkit-short-whistle-fall-406.wav", NULL, SND_FILENAME|NULL|SND_ASYNC); Sleep(2000); return(0); } } screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //erase old position: screenBuffer[OldcHeroUx.X + OldcHeroUx.Y * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[OldcHeroUx.X + OldcHeroUx.Y * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); } }//end if up //fall down from hight if steps out over edge: if(( screenBuffer[ cHero.X + (cHero.Y +1) * SCREEN_WIDTH].Char.AsciiChar != '#') //over the edge.. && (mUp == false)) //and not while jumping.. { t.detach(); //stops thread with background music PlaySound("mixkit-short-whistle-fall-406.wav", NULL, SND_FILENAME|NULL|SND_ASYNC); while(1) { COORD cHeroOldFall = cHero; Time2 = GetTickCount(); int Elapsed_F = Time2 - Time1; if((Elapsed_F > 70) && (cHero.Y < 25)) { Time1 = GetTickCount();//reset Elapsed_F = 0;//reset cHero.Y++; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //erase old position: screenBuffer[cHeroOldFall.X + cHeroOldFall.Y * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[cHeroOldFall.X + cHeroOldFall.Y * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); if(cHero.Y > 23) { PlaySound("mixkit-body-impact-falling-into-the-sand-2498.wav", NULL, SND_FILENAME|NULL|SND_ASYNC); system("color E2");//ljusgul Sleep(100); system("color 8");//mörkgrå Sleep(100); system("color E2");//ljusgul Sleep(100); system("color 8");//mörkgrå Sleep(100); Sleep(2000); return(0); } } }//fall while 1 } //end if fall //new floor plan according to Level if pass end marker to the right: if( screenBuffer[ cHero.X + (cHero.Y - 1) * SCREEN_WIDTH].Char.AsciiChar == '!') //passing level entrance { Level++; DrawWon("Level:", 71, 2, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << Level; cHero = {2,23}; //reset hero at start //erase old plan: for (int x = 1; x < SCREEN_WIDTH; x++) { for (int y = 1; y < SCREEN_HEIGHT; y++) { screenBuffer[x + y * SCREEN_WIDTH].Char.AsciiChar = '8'; screenBuffer[x + y * SCREEN_WIDTH].Attributes = 0; } } DrawWorld(screenBuffer); Beep(650,100); Beep(700,100); Beep(750,100); Beep(800,100); Beep(850,100); Beep(750,500); //new level sign: if(Level < 5) { DrawWon("NN NN EEEEEEE XX XX TTTTTTTT", 10, 4, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NNN NN EE XX XX TT", 10, 5, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NNNN NN EE XX XX TT", 10, 6, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NN NN NN EEEEE XXXX TT", 10, 7, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NN NN NN EEEEE XXXX TT", 10, 8, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NN NNNN EE XX XX TT", 10, 9, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NN NNN EE XX XX TT", 10, 10, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); DrawWon("NN NN EEEEEEE XX XX TT", 10, 11, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); } //move cursor: DrawWon(" ", 1, 1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white Sleep(3000); //erase sign: for (int x = 1; x < SCREEN_WIDTH; x++) { for (int y = 1; y < SCREEN_HEIGHT; y++) { screenBuffer[x + y * SCREEN_WIDTH].Char.AsciiChar = '8'; screenBuffer[x + y * SCREEN_WIDTH].Attributes = 0; } } DrawWorld(screenBuffer); NextLevel(screenBuffer, Level); if(Level > 5) { t.detach(); return(0); } } //end if passed level door //moving traps: switch(Level) { case 2: { TrapTime2 = GetTickCount(); TrapElapsed = TrapTime2 - TrapTime1; if((TrapElapsed > 400)&&(bTrap)) { TrapTime1 = GetTickCount();//reset TrapElapsed = 0;//reset for(int c = 19; c < 24; c++) //at bottom? { screenBuffer[53 + c * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[53 + c * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; } //erase top position: screenBuffer[53 + 18 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[53 + 18 * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); bTrap = false; } else if((TrapElapsed > 400)&&(bTrap == false)) { TrapTime1 = GetTickCount();//reset TrapElapsed = 0;//reset for(int d = 18; d < 23; d++) //at top? { screenBuffer[53 + d * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[53 + d * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; } //erase bottom position: screenBuffer[53 + 23 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[53 + 23 * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); bTrap = true; } }break; case 3: { //31-55: Trap2Time2 = GetTickCount(); Trap2Elapsed = Trap2Time2 - Trap2Time1; if((Trap2Elapsed > 1400)&&(bTrap2)) { Trap2Time1 = GetTickCount();//reset Trap2Elapsed = 0;//reset for(int c2 = 24; c2 < 35; c2++) //slicer at left { screenBuffer[c2 + 17 * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[c2 + 17 * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; } //erase right position: for(int c3 = 38; c3 < 42; c3++) { screenBuffer[c3 + 17 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[c3 + 17 * SCREEN_WIDTH].Attributes = 0; } DrawWorld(screenBuffer); bTrap2 = false; } else if((Trap2Elapsed > 1400)&&(bTrap2 == false)) { Trap2Time1 = GetTickCount();//reset Trap2Elapsed = 0;//reset for(int d2 = 38; d2 < 42; d2++) //slicer at right { screenBuffer[d2 + 17 * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[d2 + 17 * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; } //erase left position: for(int d3 = 24; d3 < 35; d3++) { screenBuffer[d3 + 17 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[d3 + 17 * SCREEN_WIDTH].Attributes = 0; } DrawWorld(screenBuffer); bTrap2 = true; } }break; case 4: { //flying blue Xs: FlyXTime2 = GetTickCount(); FlyXElapsed = FlyXTime2 - FlyXTime1; if(FlyXElapsed > 20) { FlyXTime1 = GetTickCount();//reset FlyXElapsed = 0;//reset if(FlyX > 0 ) FlyX--; else { FlyX = 69; //reset from far right bAnotherX = true; } //semirandom Y position: if(bAnotherX) { srand(GetTickCount()); //'seeding' the rand function with tick count iFly = ((rand() % 10) + 1) ; //(1-10) iFly = iFly + 8; //9-19 bAnotherX = false; } screenBuffer[FlyX + iFly * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[FlyX + iFly * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; screenBuffer[(FlyX+1) + iFly * SCREEN_WIDTH].Char.AsciiChar = ' '; //erase old position screenBuffer[(FlyX+1) + iFly * SCREEN_WIDTH].Attributes = 0; //erase last x to the left screenBuffer[1 + iFly * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[1 + iFly * SCREEN_WIDTH].Attributes = 0; screenBuffer[0 + iFly * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[0 + iFly * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); }//end timer } break; case 5: //the end { t.detach(); //stop music //add time bonus: TotalTime2 = GetTickCount(); TotalElapsed = TotalTime2 - TotalTime1; //typ 7000 Points = XPoints + 1000 - (TotalElapsed / 1000); if(XPoints < 2) Points = 1000 - (TotalElapsed / 1000); //testing: /* DrawWon(" ", 71, 4, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white DrawWon("XPoints:", 71, 4, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << XPoints; DrawWon(" ", 70, 7, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white DrawWon("Points:", 70, 7, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << Points; DrawWon(" ", 71, 9, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white DrawWon("TotE:", 71, 9, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);//=white cout << TotalElapsed; */ PlaySound("mixkit-greeting-music-box-tone-699.wav", NULL, SND_FILENAME|NULL|SND_ASYNC); fHighscores(); Sleep(7000); return(0); }break; default: { /* do nothing */ } break; }//end sw level traps if( screenBuffer[ cHero.X + (cHero.Y ) * SCREEN_WIDTH].Char.AsciiChar == 'X') //smashed by moving trap { t.detach(); //stops thread with background music Sleep(100); PlaySound("mixkit-bone-breaking-with-echo-2937.wav", NULL, SND_FILENAME|NULL|SND_ASYNC); system("color E2");//ljusgul Sleep(100); system("color 8");//mörkgrå Sleep(100); system("color E2");//ljusgul Sleep(100); system("color 8");//mörkgrå Sleep(100); Sleep(3000); return(0); } if( screenBuffer[ cHero.X + (cHero.Y - 1 ) * SCREEN_WIDTH].Char.AsciiChar == 'W') //pass under trigger { if(bSwitcher == false) {bDeathWallOn = true; bSwitcher = true; } //toggles on ... else if(bSwitcher) {bDeathWallOn = false; bSwitcher = false; // ...and off for(int p3 = 15; p3 < 24; p3++) //death wall disappears { screenBuffer[47 + p3 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[47 + p3 * SCREEN_WIDTH].Attributes = 0; screenBuffer[48 + p3 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[48 + p3 * SCREEN_WIDTH].Attributes = 0; } DrawWorld(screenBuffer); } } Trap3Time2 = GetTickCount(); Trap3Elapsed = Trap3Time2 - Trap3Time1; if((Trap3Elapsed > 100)&&(bTrap3) &&(bDeathWallOn)) { Trap3Time1 = GetTickCount();//reset Trap3Elapsed = 0;//reset for(int p = 15; p < 24; p++) //death wall appears { screenBuffer[47 + p * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[47 + p * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; screenBuffer[48 + p * SCREEN_WIDTH].Char.AsciiChar = 'X'; screenBuffer[48 + p * SCREEN_WIDTH].Attributes = BACKGROUND_GREEN | BACKGROUND_BLUE|BACKGROUND_INTENSITY; } DrawWorld(screenBuffer); bTrap3 = false; } else if((Trap3Elapsed > 100)&&(bTrap3 == false)&&(bDeathWallOn)) { Trap3Time1 = GetTickCount();//reset Trap3Elapsed = 0;//reset for(int p2 = 15; p2 < 24; p2++) //death wall disappears { screenBuffer[47 + p2 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[47 + p2 * SCREEN_WIDTH].Attributes = 0; screenBuffer[48 + p2 * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[48 + p2 * SCREEN_WIDTH].Attributes = 0; } DrawWorld(screenBuffer); bTrap3 = true; } Sleep(5); }//end while 1 return 0; } //////////////////////////////// DRAW WORLD ///////////////////////////////// ///// ///// This draws screenBuffer to the screen ///// //////////////////////////////// DRAW WORLD ///////////////////////////////// void DrawWorld(CHAR_INFO screenBuffer[]) { SMALL_RECT drawRect = {0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1}; COORD bufferSize = {SCREEN_WIDTH , SCREEN_HEIGHT}; COORD zeroZero = {0, 0}; HANDLE hOutput; hOutput = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsoleOutput(hOutput, screenBuffer, bufferSize, zeroZero, &drawRect); } //////////////////////// check input //////////////////////////////////////// //////////////////CHECK INPUT////////////////////////////////////////////// bool CheckInput() { DWORD events=0; HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD InputRecord; GetNumberOfConsoleInputEvents(hInput, &events); if(!events) return false; ReadConsoleInput(hInput, &InputRecord, 1, &events); bKeyDown = InputRecord.Event.KeyEvent.bKeyDown; DaKeyCode = InputRecord.Event.KeyEvent.wVirtualKeyCode; return true; } ////////////////////// Handle Input //////////////////////////////////// //************************************************************************// ////////////////////// Handle Input //////////////////////////////////// void HandleInput(CHAR_INFO screenBuffer[]) { if(bKeyDown > 0) { if((GetKeyState(VK_w) & 0x8000) != 0) //w : jump up + fwd { mUp = true; } else if((GetKeyState(VK_s) & 0x8000) != 0) //s : inactive? { Beep(800,400); } else if((GetKeyState(VK_d) & 0x8000) != 0) //d; move right { mRight = true; mLeft = false; COORD OldcHero = cHero; if(cHero.X < 69) cHero.X++; //move right //draw hero at new position: screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //erase old position: screenBuffer[OldcHero.X + OldcHero.Y * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[OldcHero.X + OldcHero.Y * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); } else if((GetKeyState(VK_a) & 0x8000) != 0) //a, move left { mLeft = true; mRight = false; COORD OldcHeroL = cHero; if(cHero.X > 1) cHero.X--; //move left //draw hero at new position: screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[cHero.X + cHero.Y * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; //erase old position: screenBuffer[OldcHeroL.X + OldcHeroL.Y * SCREEN_WIDTH].Char.AsciiChar = ' '; screenBuffer[OldcHeroL.X + OldcHeroL.Y * SCREEN_WIDTH].Attributes = 0; DrawWorld(screenBuffer); } } }//end handle input //////////////////////////////// DRAW Won ///////////////////////////////// //for displaying current points etc //////////////////////////////// DRAW Won ///////////////////////////////// void DrawWon(string Str, int X, int Y, WORD color) { HANDLE OutputH; COORD position = {X, Y}; OutputH = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(OutputH, color); SetConsoleCursorPosition(OutputH, position); cout << Str; //display text } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // N E X T L E V E L // N E X T L E V E L // N E X T L E V E L // N E X T L E V E L // N E X T L E V E L /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void NextLevel(CHAR_INFO screenBuffer[], int a) { switch(a) { case 2: { //design floor plan: for (int i = 1; i < 70; i++) { screenBuffer[i + 24 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[i + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } //hole:, now danger things instad for (int i2 = 12; i2 < 15; i2++) { screenBuffer[i2 + 24 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[i2 + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; } for (int j = 58; j < 65; j++) { screenBuffer[j + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[j + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int k = 15; k < 30; k++) { screenBuffer[k + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int m = 43; m < 48; m++) { screenBuffer[m + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } //put magic boxes: screenBuffer[46 + 17 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[46 + 17 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; //exit tunnel to next level: screenBuffer[67 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[67 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; //place hero: screenBuffer[2 + 23 * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[2 + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; DrawWorld(screenBuffer); }break; case 3: { //design floor plan: for (int i = 1; i < 70; i++) { screenBuffer[i + 24 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[i + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int k = 8; k < 30; k++) { screenBuffer[k + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int m = 15; m < 30; m++) { screenBuffer[m + 19 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 19 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 20 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 20 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 18 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 18 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } //death wall trigger: screenBuffer[40 + 22 * SCREEN_WIDTH].Char.AsciiChar = 'W'; screenBuffer[40 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; //put magic boxes: screenBuffer[56 + 19 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[56 + 19 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; screenBuffer[65 + 20 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[65 + 20 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; //exit tunnel to next level: screenBuffer[67 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[67 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; //place hero: screenBuffer[2 + 23 * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[2 + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; DrawWorld(screenBuffer); }break; case 4: { //design floor plan: for (int i = 1; i < 70; i++) { screenBuffer[i + 24 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[i + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int p = 18; p < 28; p++) { screenBuffer[p + 24 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[p + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; } for (int k = 5; k < 15; k++) { screenBuffer[k + 23 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 22 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 22 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[k + 21 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[k + 21 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } for (int m = 17; m < 30; m++) { screenBuffer[m + 19 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 19 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 20 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 20 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; screenBuffer[m + 18 * SCREEN_WIDTH].Char.AsciiChar = '#'; screenBuffer[m + 18 * SCREEN_WIDTH].Attributes = FOREGROUND_GREEN; } screenBuffer[28 + 18 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[28 + 18 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; //death wall trigger: screenBuffer[43 + 22 * SCREEN_WIDTH].Char.AsciiChar = 'W'; screenBuffer[43 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[39 + 22 * SCREEN_WIDTH].Char.AsciiChar = 'W'; screenBuffer[39 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[47 + 22 * SCREEN_WIDTH].Char.AsciiChar = 'W'; screenBuffer[47 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[42 + 24 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[42 + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; screenBuffer[43 + 24 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[43 + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; screenBuffer[44 + 24 * SCREEN_WIDTH].Char.AsciiChar = '*'; screenBuffer[44 + 24 * SCREEN_WIDTH].Attributes = FOREGROUND_RED; //put magic boxes: screenBuffer[58 + 19 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[58 + 19 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; screenBuffer[28 + 15 * SCREEN_WIDTH].Char.AsciiChar = '.'; screenBuffer[28 + 15 * SCREEN_WIDTH].Attributes = BACKGROUND_BLUE|BACKGROUND_INTENSITY; //exit tunnel to next level: screenBuffer[67 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[67 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; screenBuffer[68 + 22 * SCREEN_WIDTH].Char.AsciiChar = '!'; screenBuffer[68 + 22 * SCREEN_WIDTH].Attributes = BACKGROUND_RED|BACKGROUND_INTENSITY; //place hero: screenBuffer[2 + 23 * SCREEN_WIDTH].Char.AsciiChar = 'o'; screenBuffer[2 + 23 * SCREEN_WIDTH].Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; DrawWorld(screenBuffer); }break; case 5: { //do nothing here, ends in main }break; default: Beep(750,2000); break; }//end sw a } //funktion för highscorelistan: //////////////// FUNCTION HIGHSCORES ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// void fHighscores(void) { if (Points < 1) Points = 1; //annars vektorkrash //uppdatera highscorelista från gamla filer, printa sedan ny: //retreive stored names in order: ifstream finStrings("NameScores.txt"); if (!finStrings) { ofstream foutStrings("NameScores.txt"); foutStrings.close(); } while (finStrings >> sTest) AllUsersIn.push_back(sTest);//the list has already been sorted in order, but push_back reverses it!!! Now need to reverse it again: finStrings.close(); //same thing, but for stored scores; int Tempoint = 0; ifstream finInts("IntScores.txt"); if (!finInts) { ofstream foutInts("IntScores.txt"); foutInts.close(); } while (finInts >> Tempoint) iPointsIn.push_back(Tempoint);//already been sorted in order, push_back reverses finInts.close(); int est = 0; // re-assemble the past highscore list: for (int n = 0; n < AllUsersIn.size(); n++)// { //est = 200 - iPointsIn[n]; est = iPointsIn[n]; vHighscores[est] = AllUsersIn[n]; //put name at [points in] position, biggest first }//end for n //Load current name to pre-existing lists: if (Points > 25000) { Points = 25000; }//så inte går över max Points = (25000 - Points); //omdefinierat så hamnar högt upp på listan med hög poäng if (vHighscores[Points].empty())//om ledigt... vHighscores[Points] = sNamn; //sätt namnet där, vid sin poäng! //Tar bort delade platser, blir bugg när laddar in sparade filer igen då; olika vektorstorlakar. //Kompensera med poäng även baserad på steg; mer osannolikt att flera får samma poäng. //else //{//om redan finns nån med samma poäng, sätt på samma plats: //string sDelad = vHighscores[Points] + " OCH " + sNamn;//string = string + string funkar! //vHighscores[Points] = sDelad; //} //store the now udated names and points in files: ofstream foutStoreN("NameScores.txt"); for (int p = 0; p < vHighscores.size(); p++) { // string sOutAll = AllUsers[p]; if (vHighscores[p].empty()) Empty++; //do not print empty positions else { string sOutAll = vHighscores[p]; foutStoreN << sOutAll << endl; } } foutStoreN.close(); ofstream foutStoreI("IntScores.txt"); //for(int q = 0; q < iPoints.size(); q++) for (int q = 0; q < vHighscores.size(); q++) { if (vHighscores[q].empty()) Empty++; //do not print empty positions else { foutStoreI << q << endl; } }//end for q foutStoreI.close(); //output sHighscores vector to Highskor.txt file: ofstream fHigh("Highskor.txt"); //inte ::app, vill ha ny varje gång //use only those positions that are occupied with a name!: //the for loops also serve to reverse the order, printing last first...: fHigh << " HIGHSCORES:" << endl; for (int y = 0; y < vHighscores.size(); y++)// { if (vHighscores[y].empty()) Empty++;//do not print empty positions else { Placer++;//translate to first, second, third etc place! // and translate to a high score for the best: int Score = 25000 - y; // \t är tabulering, sätter ut ett stort mellanrum: if (Placer < 11)//only top 10 on Highscore list { fHigh << Placer << ":" << "\t" << vHighscores[y] << " (" << Score << " poeng)." << endl; } }//end else Placer }// end for y fHigh.close(); Placer = 0; //Visa highscorelista på skärmen också: //But only top 10 on Highscore list!: cout << endl; cout << "*********************************" << endl; cout << " HIGHSCORES:" << endl; for (int z = 0; z < vHighscores.size(); z++)// { if (vHighscores[z].empty()) Empty++;//do not print empty positions else { Placer++;//translate to first, second, third etc place! // and translate to a high score for the best: int screenScore = 25000 - z; if (Placer < 11)//only top 10 on Highscore list { cout << setw(3) << Placer << ":" << "\t" << vHighscores[z] << " (" << screenScore << " poeng)." << endl; } }//end else Placer }// end for z Placer = 0; cout << "*********************************" << endl; Sleep(3000); }//end funktion highscores