From 964353d5eab9b49ffb88958d520ab5b56f7c268b Mon Sep 17 00:00:00 2001 From: Reimar Date: Sun, 21 Dec 2014 16:34:23 +0100 Subject: made code better and hardcore more hardcore --- JnR.cpp | 530 ++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 329 insertions(+), 201 deletions(-) diff --git a/JnR.cpp b/JnR.cpp index a70909e..f30f8c9 100644 --- a/JnR.cpp +++ b/JnR.cpp @@ -167,9 +167,24 @@ void drawPixel(SDL_Surface *screen,int x, int y, Uint8 R, Uint8 G, Uint8 B) SDL_FillRect(screen,&r,color); } -SDL_Surface* preBall; +void drawLine(SDL_Surface* screen,double x0,double y0,double x1, double y1, Uint8 R, Uint8 G, Uint8 B) +{ + double x = x0; + double y = y0; + double dir_x = x1 - x0; + double dir_y = y1 - y0; + double norm = dir_x*dir_x + dir_y*dir_y; + dir_x /= sqrt(2*norm); + dir_y /= sqrt(2*norm); + while((x1-x)*dir_x + (y1-y)*dir_y > 0) + { + drawPixel(screen, x, y, R,G,B); + x += dir_x; + y += dir_y; + } +} -void drawCircle(SDL_Surface* screen, double x, double y, double angle, double radius, Uint8 R, Uint8 G, Uint8 B) +void drawCircle(SDL_Surface* screen, SDL_Surface* preBall, double x, double y, double angle, double radius, Uint8 R, Uint8 G, Uint8 B) { int tempseed = rand(); srand(87); @@ -301,7 +316,7 @@ public: }; -vector makeDeathAnimation(double x, double y, double r, double vxb, double vyb, int mode) +vector makeDeathAnimation(double x, double y, double r, double vxb, double vyb) { vector result; for(int i = 0; i < 2000; ++i) @@ -315,37 +330,25 @@ vector makeDeathAnimation(double x, double y, double r, double vxb, do Particle temp = Particle(tx, ty, 1, playerR, playerG, playerB); double vb = (rand()%5000)/30.0; double vp = ((rand()%10000)/10000.0)*2*M_PI; - if(!mode) - { - temp.vx = cos(vp)*vb+vxb; - temp.vy = sin(vp)*vb+vyb; - } - else - { - temp.vx = cos(vp)*vb+vxb*(rand()%1000)/1000.0; - temp.vy = sin(vp)*vb+vyb*(rand()%1000)/1000.0; - } + + temp.vx = cos(vp)*vb+vxb*(rand()%1000)/1000.0; + temp.vy = sin(vp)*vb+vyb*(rand()%1000)/1000.0; + temp.life = (rand()%100)/50.0; result.push_back(temp); } return result; } -double x_pos = 0; -double x_vel = 0; -double phi = 0; -double vphi = 0; double ground_level = 20; -double y_vel = 0; double ball_rad = 8; double y_pos = ground_level + ball_rad; double g = 300.0; double c_r = 0.004; -double highscore = 1000; -double position_multiplier = 3; double win_bonus = 5000; -bool hardcore = false; +string name; +//loads the "settings" (color sceme) void loadConstants() { ifstream ins; @@ -366,23 +369,20 @@ void loadConstants() ins.close(); } -int main() + +//a console io menu with limited possibility to set difficulty and hardcore mode +void pregame_menu(string& name, int& difficulty, double& position_multiplier, bool& hardcore) { - loadConstants(); - - string name; cout << "This is a simple jump and run" << endl; cout << "Please enter your name:"; cin >> name; cout << "Please enter difficulty (0-100):"; - int difficulty; cin >> difficulty; cout << "Do you want to play in hardcore mode(0/1)?"; cin >> hardcore; if(hardcore) { - highscore *= 1.5; - cout << "You are insane. +50% score!" << endl; + cout << "You are insane. +100% score!" << endl; } else cout << "Very sane decision..." << endl; @@ -393,14 +393,18 @@ int main() difficulty = max(-50,difficulty); if(difficulty > 100) difficulty = 100; - bool wantEnd = false; cout << "difficulty = " << difficulty << endl; +} + +//initializes the imported libs and opens a window +int init_libs(SDL_Surface **screen) +{ if(SDL_Init(SDL_INIT_VIDEO) == -1) { cout << "Error: Could not initialize SDL" << endl; return 1; } - screen = SDL_SetVideoMode(xres,yres,32,SDL_SWSURFACE); + *screen = SDL_SetVideoMode(xres,yres,32,SDL_SWSURFACE); if(!screen) { cout << "could not initialize screen" << endl; @@ -413,201 +417,313 @@ int main() return 1; } SDL_WM_SetCaption("Ballroller - v0.3", NULL); - while(!wantEnd) + return 0; +} + + +class GameHandle +{ + //will always contain the CURRENT highscore + double highscore; + //level number + int difficulty; + bool hardcore; + double x_pos; + double y_pos; + double x_vel; + double y_vel; + double vphi; + double phi; + double position_multiplier; + vector obstacles; + vector particles; + SDL_Surface* preBall; + SDL_Surface* screen; + bool game_Quit; + bool quickquit; + Label* scoreLabel; + Label* message; + //-1,0,1 respectively depending on the status of ther arrow keys + int down; + int right; + double g_x; + double g_y; + + void game_reset() { //SEED srandn(2334508 + difficulty); srand(2334508 + difficulty); - + highscore = 1000; - position_multiplier = 3; x_pos = 0; y_pos = 0; y_vel = 0; x_vel = 0; + vphi = 0; + phi = 0; + position_multiplier = 3; + //higher levels give more score position_multiplier += difficulty/40.0; - preBall = loadBMP("blank.bmp"); - - bool Game_Quit = false; - int down = 0; - int right = 0; - vector obstacles; + //hardcore gives 100% score bonus + if(hardcore) + highscore *= 2; + game_Quit = false; + quickquit = false; + + //creating the level + obstacles = vector(); obstacles.push_back(Obstacle(-50,ground_level,10,200)); - vector particles; - bool quickquit = false; - for(int i = 0; i < 10*60*5; ++i) - { - Particle p = Particle(rand()%11000 - 300,ground_level + rand()%((int)(yres-ground_level)),3,255,255,255); - p.life = 1000; - p.vy = -5-rand()%30/9.0; - particles.push_back(p); - } - //Longest Jump: 608 - //Highest Jump: 150 + //Longest Jump: 608 Highest Jump: 150 (TODO: filter obstacles based on that) int opos = 200; while(opos < 10000) { - int blub = 4+randn()%(192+difficulty/4-4); - obstacles.push_back(Obstacle(opos,ground_level,blub,(196 + difficulty/4)/2-blub/2)); - opos += randn()%(900-4*difficulty); + int blub = 4+randn()%(162+difficulty/2-4); + obstacles.push_back(Obstacle(opos,ground_level,blub,(176 + difficulty/2)/2-blub/2)); + opos += randn()%(890-9*difficulty/2); } + //in hardcore mode, there are boxes going from right to left if(hardcore) - for(int i = 1; i < 110; ++i) + for(int i = 1; i < 110; ++i) { Obstacle tempo = Obstacle(i*300,ground_level, 10, 10); tempo.vx = -60; obstacles.push_back(tempo); } - vector deathanimation; - bool lost = false; - long long steps = 0; + } +public: + ~GameHandle() + { + SDL_FreeSurface(preBall); + atexit(SDL_Quit); + delete scoreLabel; + } + + GameHandle(int Ndifficulty, bool Nhardcore, SDL_Surface* Nscreen) + { + difficulty = Ndifficulty; + hardcore = Nhardcore; + highscore = 1000; + screen = Nscreen; + preBall = loadBMP("blank.bmp"); + for(int i = 0; i < 10*60*5; ++i) + { + Particle p = Particle(rand()%11000 - 300,ground_level + rand()%((int)(yres-ground_level)),3,255,255,255); + p.life = 1000; + p.vy = -5-rand()%30/9.0; + particles.push_back(p); + } + SDL_Rect lpos; lpos.x = 300; lpos.y = 10; lpos.w = 300; lpos.h = 20; - Label scoreLabel = Label("Score: " + lltostr((long long)((1+0.5*hardcore)*(highscore + x_pos*position_multiplier))), lpos); - double maxjumpx = 0; - double maxjumpy = 0; - double lastjumppos = 0; + scoreLabel = new Label("Score: " + lltostr(highscore), lpos); + } - while(!Game_Quit) - { - steps++; - Uint32 start = SDL_GetTicks(); - if(!lost) - highscore--; - blacken(screen); - SDL_Event event; - while(SDL_PollEvent(&event)) - { - if(event.type == SDL_QUIT) - { - Game_Quit = true; - quickquit = true; - wantEnd = true; - break; - } - } - Uint8 *keyState = SDL_GetKeyState(NULL); + void update_scoreLabel() + { + scoreLabel->setCaption("Score: " + lltostr(highscore)); + } - down = -keyState[SDLK_UP]+keyState[SDLK_DOWN]; + void paint(bool win, bool showmessage) + { + blacken(screen); + for(int i = 0; i < (int) particles.size(); ++i) + particles[i].draw(screen,x_pos-xres/4,0); + for(int i = 0; i < (int) obstacles.size(); ++i) + obstacles[i].draw(screen,x_pos-xres/4,0); + if(win) + drawCircle(screen, preBall, xres/4, fabs(yres-y_pos), phi, ball_rad, playerR, playerG, playerB); + for(int i = 0; i < xres; ++i) + drawPixel(screen,i,yres-ground_level,255,255,255); + scoreLabel->draw(screen); + if(showmessage) + message->draw(screen); - vector nparticles; - for(int i = 0; i < (int) particles.size(); ++i) - { - if(particles[i].step(1/60.0) && particles[i].y > ground_level) - { - particles[i].draw(screen,x_pos-xres/4,0); - nparticles.push_back(particles[i]); - } - } + if(hardcore) + drawLine(screen,500,20,500 + g_x/3,20 - g_y/3,255,255,255); + SDL_Flip(screen); + } + + void step(int steps, bool inGame, double t) + { + if(inGame) + { + //spawning a new obstacle for hardcoremode if(!(steps%300) && hardcore) { - Obstacle tempo = Obstacle(110*100,ground_level, 10, 10); + Obstacle tempo = Obstacle(110*300,ground_level, 10, 10); tempo.vx = -60; obstacles.push_back(tempo); } for(int i = 0; i < (int) obstacles.size(); ++i) - { obstacles[i].step(1/60.0); - obstacles[i].draw(screen,x_pos-xres/4,0); - if(!lost) - if(obstacles[i].check_death(x_pos,y_pos,ball_rad)) + + x_pos = x_pos + x_vel/60.0; + y_pos = y_pos + y_vel/60.0; + //updating highscore + highscore -= 1.0; + highscore += x_vel/60.0*position_multiplier*(1+hardcore); + phi = phi + vphi/60.0; + if(hardcore) + { + double vart = (sin(t))/7; + g_x = g*sin(vart); + g_y = - g*cos(vart); + cout << g_x << endl; + if(y_pos > ground_level+ball_rad) { - cout << "Collision: You lost the game" << endl; - cout << "Better luck next time!" << endl; - highscore = (int)((1+0.5*hardcore)*(highscore + x_pos*position_multiplier)); - scoreLabel.setCaption("Score: " + lltostr(highscore)); - cout << "Your highscore: " << highscore << endl; - lost = true; - deathanimation = makeDeathAnimation(x_pos,y_pos,ball_rad,x_vel, y_vel,1); + y_vel = y_vel*(1.0-c_r) + g_y/60; + x_vel = x_vel*(1.0-c_r) + right*80/60.0 + g_x/60; + } + if(y_pos <= ground_level+ball_rad) + { + x_vel = x_vel*(1.0-c_r) + right*140./60.0 + g_x/60; + y_pos = ground_level+ball_rad; + y_vel = fabs(y_vel); + if(down == -1) + y_vel += 900; + y_vel *= 0.25; + /*double Dvphi = (x_vel/ball_rad+vphi)/2; + x_vel -= Dvphi*2;*/ + vphi += x_vel/ball_rad; } } - particles = nparticles; - for(int i = 0; i < 1; ++i) + else { - Particle p = Particle(-300 + rand()%11001,yres,3,255,255,255); - p.vy = -5-rand()%30/9.0; - p.life = 1000; - particles.push_back(p); + if(y_pos > ground_level+ball_rad) + { + y_vel = y_vel*(1.0-c_r) - g/60.0; + x_vel = x_vel*(1.0-c_r) + right*80/60.0; + } + if(y_pos <= ground_level+ball_rad) + { + x_vel = x_vel*(1.0-c_r) + right*140./60.0; + y_pos = ground_level+ball_rad; + y_vel = fabs(y_vel); + if(down == -1) + y_vel += 900; + y_vel *= 0.25; + vphi = -x_vel/ball_rad; + } } - if(!lost) + } + + //deleting old particles + vector nparticles; + for(int i = 0; i < (int) particles.size(); ++i) + { + if(particles[i].step(1/60.0) && particles[i].y > ground_level) { - x_pos = x_pos + x_vel/60.0; - y_pos = y_pos + y_vel/60.0; - phi = phi + vphi/60.0; - drawCircle(screen, xres/4, fabs(yres-y_pos), phi, ball_rad, playerR, playerG, playerB); - scoreLabel.setCaption("Score: " + lltostr((long long)((1+0.5*hardcore)*(highscore + x_pos*position_multiplier)))); + nparticles.push_back(particles[i]); } + } - right = -keyState[SDLK_LEFT]+keyState[SDLK_RIGHT]; - if(!right) + particles = nparticles; + for(int i = 0; i < 1; ++i) + { + Particle p = Particle(-300 + rand()%11001,yres,3,255,255,255); + p.vy = -5-rand()%30/9.0; + p.life = 1000; + particles.push_back(p); + } + } + + void handle_Events(bool &game_Quit, int &down, int& right) + { + SDL_Event event; + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_QUIT) { - right = -keyState[SDLK_LEFT]+keyState[SDLK_RIGHT]; + game_Quit = true; + break; } + } + Uint8 *keyState = SDL_GetKeyState(NULL); + + down = -keyState[SDLK_UP]+keyState[SDLK_DOWN]; + right = -keyState[SDLK_LEFT]+keyState[SDLK_RIGHT]; + } + + void animate_death() + { + vector deathanimation = makeDeathAnimation(x_pos,y_pos,ball_rad,x_vel, y_vel); + for(int i = 0; i < (int) deathanimation.size(); ++i) + particles.push_back(deathanimation[i]); + } + + void play() + { + //closes gamewindow + bool quit_Game = false; + while(!quit_Game) + { + //won or lost the game + bool game_Over = false; + //resets the game variables to startpoint + game_reset(); - if(y_pos > ground_level+ball_rad) - { - y_vel = y_vel*(1.0-c_r) - g/60.0; - x_vel = x_vel*(1.0-c_r) + right*80/60.0; - maxjumpy = max(maxjumpy,y_pos); - } - if(y_pos <= ground_level+ball_rad) - { - maxjumpx = max(maxjumpx,x_pos-lastjumppos); - lastjumppos = x_pos; - x_vel = x_vel*(1.0-c_r) + right*140./60.0; - y_pos = ground_level+ball_rad; - y_vel = fabs(y_vel); - if(down == -1) - y_vel += 900; - y_vel *= 0.25; - vphi = -x_vel/ball_rad; - } - if(!lost) - if(highscore+x_pos*position_multiplier <= 0) - { - cout << "TIMEOUT: You lost the game." << endl; - cout << "Better luck next time!" << endl; - quickquit = true; - Game_Quit = true; - deathanimation = makeDeathAnimation(x_pos,y_pos,ball_rad,x_vel, y_vel,0); - } - if(x_pos >= 10000) - { - cout << "You win the game!" << endl; - highscore = (int)((1+0.5*hardcore)*(highscore + x_pos*position_multiplier + win_bonus)); - cout << "Your highscore: " << highscore << endl; - scoreLabel.setCaption("Score: " + lltostr(highscore)); - Game_Quit = true; - } - for(int i = 0; i < xres; ++i) - drawPixel(screen,i,yres-ground_level,255,255,255); - bool animation_term = true; - for(int i = 0; i < (int) deathanimation.size(); ++i) + bool win = false; + double time = 0; + int steps = 0; + + while(!game_Over) { - if(deathanimation[i].step(1/60.0)) + Uint32 start = SDL_GetTicks(); + handle_Events(game_Quit,down, right); + if(game_Quit) { - animation_term = false; - deathanimation[i].draw(screen,x_pos-xres/4,0); + game_Over = true; + break; } + + step(steps, true,time); + + for(int i = 0; i < (int) obstacles.size(); ++i) + { + if(obstacles[i].check_death(x_pos,y_pos,ball_rad)) + { + cout << "Collision: You lost the game" << endl; + cout << "Better luck next time!" << endl; + update_scoreLabel(); + cout << "Your highscore: " << highscore << endl; + game_Over = true; + animate_death(); + } + } + if(game_Over) + break; + update_scoreLabel(); + steps++; + time += 1/60.0; + + if(highscore <= 0) + { + cout << "TIMEOUT: You lost the game." << endl; + cout << "Better luck next time!" << endl; + game_Over = true; + animate_death(); + break; + } + if(x_pos >= 10000) + { + cout << "You win the game!" << endl; + cout << "Your highscore: " << highscore << endl; + update_scoreLabel(); + game_Over = true; + win = true; + break; + } + paint(true,false); + Uint32 time = SDL_GetTicks()-start; + if(1000/60.0 - time > 0) + SDL_Delay(1000/60.0 - time); } - if(animation_term && lost) - Game_Quit = true; - scoreLabel.draw(screen); - SDL_Flip(screen); - Uint32 time = SDL_GetTicks()-start; - if(1000/60.0 - time > 0) - SDL_Delay(1000/60.0 - time); - } - cout << "Longest Jump: " << maxjumpx << endl; - cout << "Highest Jump: " << maxjumpy << endl; - - /*The Game has ended*/ - if(!quickquit) - { + /*finished a game, end-Game screen*/ ifstream ins; ins.open("highscore.dat"); vector > highlist; @@ -641,8 +757,7 @@ int main() { for(int i = 0; i < 10; ++i) { - ofs << highlist[i+1].first << " " << highlist[i+1].second << endl; - } + ofs << highlist[i+1].first << " " << highlist[i+1].second << endl; } } else { @@ -651,8 +766,7 @@ int main() ofs << highlist[i].first << " " << highlist[i].second << endl; } } - - ofs.close(); + ofs.close(); } cout << "\n**HIGHSCORE**\n"; for(int i = min(10,(int) highlist.size()-1); i > 0; --i) @@ -662,36 +776,50 @@ int main() if(highlist.size() < 11) cout << highlist[0].second << ": " << highlist[0].first << '\n'; cout << endl; - } - SDL_Rect mpos; - mpos.x = 25; - mpos.y = 180; - mpos.w = 300; - mpos.h = 32; - Label message = Label("GAME OVER - Press space to restart", mpos); - message.draw(screen); - SDL_Flip(screen); - while(true) - { - SDL_Event event; - SDL_PollEvent(&event); - Uint8 *keyState = SDL_GetKeyState(NULL); - if(event.type == SDL_QUIT || keyState[SDLK_ESCAPE]) + SDL_Rect mpos; + mpos.x = 25; + mpos.y = 180; + mpos.w = 300; + mpos.h = 32; + if(win) + message = new Label("YOU WIN! - Press space to restart",mpos); + else + message = new Label("GAME OVER - Press space to restart", mpos); + while(quit_Game == false) { - Game_Quit = true; - quickquit = true; - wantEnd = true; - break; + SDL_Event event; + SDL_PollEvent(&event); + Uint8 *keyState = SDL_GetKeyState(NULL); + if(event.type == SDL_QUIT || keyState[SDLK_ESCAPE]) + { + quit_Game = true; + break; + } + if(keyState[SDLK_SPACE] || keyState[SDLK_RETURN]) + break; + step(steps,false,time); + paint(win,true); + SDL_Delay(1000/60.0); } - if(keyState[SDLK_SPACE]) - break; - + delete message; } } - SDL_FreeSurface(preBall); +}; + +int main() +{ + loadConstants(); + bool hardcore = false; + int difficulty = 0; + double position_multiplier = 1; + pregame_menu(name,difficulty, position_multiplier, hardcore); + if(init_libs(&screen)) + return 1; + GameHandle game = GameHandle(difficulty, hardcore,screen); + game.play(); - atexit(SDL_Quit); return 0; } + -- cgit v1.2.3