James Heavey
/
EL17JH
FINAL VERSION
BreakoutEngine/BreakoutEngine.cpp
- Committer:
- jamesheavey
- Date:
- 2019-05-04
- Revision:
- 62:64559062e0ec
- Parent:
- 61:0a8b3ffedc40
- Child:
- 63:2de6fb2de428
File content as of revision 62:64559062e0ec:
#include "BreakoutEngine.h" #include <iostream> BreakoutEngine::BreakoutEngine() { } BreakoutEngine::~BreakoutEngine() { } void BreakoutEngine::init(int paddle_width,int paddle_height,int ball_size,int speed, int prev_score) { /* printf("init started /n"); listofBricks.clear(); listofLasers.clear(); */ // initialise the game parameters _paddle_width = paddle_width; _paddle_height = paddle_height; _ball_size = ball_size; _speed = speed; _number_left = 18; _index = 0; _cool_time = 0.0f; _prev_score = prev_score; _multiplier = 1; // y position on screen - WIDTH is defined in N5110.h _p1y = HEIGHT - GAP - 1; // puts paddles and ball in middle _p1.init(_p1y,_paddle_height,_paddle_width); _ball.init(_ball_size,_speed); _brick11.init(3,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); // need to figure out how to make a list of these _brick12.init(16,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); _brick13.init(29,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); _brick14.init(42,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); _brick15.init(55,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); _brick16.init(68,GAP_TOP+1,BRICK_HEIGHT,BRICK_WIDTH); _brick21.init(3,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); // need to figure out how to make a list of these _brick22.init(16,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); _brick23.init(29,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); _brick24.init(42,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); _brick25.init(55,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); _brick26.init(68,GAP_TOP+BRICK_HEIGHT+2,BRICK_HEIGHT,BRICK_WIDTH); _brick31.init(3,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); // need to figure out how to make a list of these _brick32.init(16,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); _brick33.init(29,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); _brick34.init(42,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); _brick35.init(55,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); _brick36.init(68,GAP_TOP+1+((BRICK_HEIGHT+1)*2),BRICK_HEIGHT,BRICK_WIDTH); listofBricks.push_back(_brick11); //maybe be able yo iterate through and this.draw(), maybe useful if i figure out how to delete objects aswell listofBricks.push_back(_brick12); listofBricks.push_back(_brick13); listofBricks.push_back(_brick14); listofBricks.push_back(_brick15); listofBricks.push_back(_brick16); listofBricks.push_back(_brick21); listofBricks.push_back(_brick22); listofBricks.push_back(_brick23); listofBricks.push_back(_brick24); listofBricks.push_back(_brick25); listofBricks.push_back(_brick26); listofBricks.push_back(_brick31); listofBricks.push_back(_brick32); listofBricks.push_back(_brick33); listofBricks.push_back(_brick34); listofBricks.push_back(_brick35); listofBricks.push_back(_brick36); _laser1.init(-10); _laser2.init(-10); _laser3.init(-10); listofLasers.push_back(_laser1); listofLasers.push_back(_laser2); listofLasers.push_back(_laser3); //printf("init ended /n"); } void BreakoutEngine::moveback_bricks() // rename to reset add in ball reset and use to increase the number of balls each time { reset_num_left(); _ball.init(_ball_size,_speed + _multiplier/2); // replace the 1 with a multiplier private variable that tracks the number of times continued from victory int pointer = 0; for (it_R = listofBricks.begin(); it_R != listofBricks.end(); ++it_R){ if (pointer <= 5) { it_R -> set_posx((pointer * 13) + 3); } else if (pointer <= 11) { it_R -> set_posx(((pointer-6) * 13) + 3); } else if (pointer <= 17) { it_R -> set_posx(((pointer-12) * 13) + 3); } it_R -> reset_lives(); pointer ++; } } void BreakoutEngine::read_input(Gamepad &pad, bool x) { _d = pad.get_direction(); _mag = pad.get_mag(); if (x == true) { _p1.set_tilt(); } else { _p1.set_joy(); } if (pad.check_event(Gamepad::B_PRESSED) && _cool_time <= 0) { // max of 3 lasers on screen at once Vector2D p_pos = _p1.get_pos(); it_L = listofLasers.begin(); switch(_index){ case 0: advance(it_L, 0); it_L -> set_posx(p_pos.x+7); it_L -> set_posy(p_pos.y); inc_index(); break; case 1: advance(it_L, 1); it_L -> set_posx(p_pos.x+7); it_L -> set_posy(p_pos.y); inc_index(); break; case 2: advance(it_L, 2); it_L -> set_posx(p_pos.x+7); it_L -> set_posy(p_pos.y); reset_index(); break; } _cool_time = 0.75f; } else { _cool_time -= 0.125; // 1/8 as fps is 8 } } void BreakoutEngine::inc_index() { _index ++; } void BreakoutEngine::reset_index() { _index = 0; } void BreakoutEngine::draw(N5110 &lcd) { // draw the elements in the LCD buffer // pitch lcd.drawRect(0,GAP_TOP - 2,WIDTH,HEIGHT - GAP_TOP + 2,FILL_TRANSPARENT); //score print_scores(lcd); // paddles _p1.draw(lcd); // ball _ball.draw(lcd); //print_scores(lcd); for (it_R = listofBricks.begin(); it_R != listofBricks.end(); ++it_R){ it_R->draw(lcd); } for (it_L = listofLasers.begin(); it_L != listofLasers.end(); ++it_L){ it_L->draw(lcd); } } void BreakoutEngine::update(Gamepad &pad) { check_goal(pad); // important to update paddles and ball before checking collisions so can // correct for it before updating the display _p1.update(_d,_mag); _ball.update(); for (it_L = listofLasers.begin(); it_L != listofLasers.end(); ++it_L){ it_L->update(); } lives_leds(pad); check_wall_collisions(pad); check_paddle_collisions(pad); check_brick_collisions(pad); check_laser_collisions(pad); } void BreakoutEngine::lives_leds(Gamepad &pad) { if (_p1.get_lives() == 0) { pad.leds_off(); } else if (_p1.get_lives() == 1) { //turn leftmost led on pad.leds_off(); pad.led(1,1); } else if (_p1.get_lives() == 2) { //turn leftmost led on pad.leds_off(); pad.led(1,1); pad.led(2,1); } else if (_p1.get_lives() == 3) { //turn leftmost led on pad.leds_off(); pad.led(1,1); pad.led(2,1); pad.led(3,1); } else if (_p1.get_lives() == 4) { pad.leds_on(); pad.led(5,0); pad.led(6,0); } else if (_p1.get_lives() == 5) { pad.leds_on(); pad.led(6,0); } else if (_p1.get_lives() == 6) { pad.leds_on(); } } int BreakoutEngine::get_lives() { return _p1.get_lives(); } void BreakoutEngine::check_wall_collisions(Gamepad &pad) { // read current ball attributes Vector2D ball_pos = _ball.get_pos(); Vector2D ball_velocity = _ball.get_velocity(); if (ball_pos.y <= GAP_TOP - 1) { // 1 due to 1 pixel boundary ball_pos.y = GAP_TOP - 1; // bounce off ceiling without going off screen ball_velocity.y = -ball_velocity.y; // audio feedback pad.tone(750.0,0.1); } else if (ball_pos.x <= 1) { // 1 due to 1 pixel boundary ball_pos.x = 1; // bounce off ceiling without going off screen ball_velocity.x = -ball_velocity.x; // audio feedback pad.tone(750.0,0.1); } // check if hit bottom wall else if (ball_pos.x + _ball_size >= (WIDTH-1) ) { // bottom pixel is 47 // hit bottom ball_pos.x = (WIDTH-1) - _ball_size; // stops ball going off screen ball_velocity.x = -ball_velocity.x; // audio feedback pad.tone(750.0,0.1); } // update ball parameters _ball.set_velocity(ball_velocity); _ball.set_pos(ball_pos); for (it_L = listofLasers.begin(); it_L != listofLasers.end(); ++it_L){ if ( (it_L -> get_y() <= GAP_TOP - 2) ) { // edit this so that if it hits the middle, reflect, else change angle depending on how far off centre (add angle to ball) // if it has, fix position and reflect x velocity it_L -> set_posx(-10); } } } void BreakoutEngine::check_paddle_collisions(Gamepad &pad) { // read current ball attributes Vector2D ball_pos = _ball.get_pos(); Vector2D ball_velocity = _ball.get_velocity(); // check p1 first Vector2D p1_pos = _p1.get_pos(); // see if ball has hit the paddle by checking for overlaps if ( (ball_pos.x >= p1_pos.x) && //left (ball_pos.x <= p1_pos.x + _paddle_width) && //right (ball_pos.y >= _p1y) && //bottom (ball_pos.y <= _p1y + _paddle_height) //top ) { // edit this so that if it hits the middle, reflect, else change angle depending on how far off centre (add angle to ball) // if it has, fix position and reflect x velocity pad.tone(1000.0,0.1); ball_pos.y = _p1y + _paddle_height - 1; ball_velocity.y = -ball_velocity.y; // if (ball_pos.x == p1_pos.x + PADDLE_WIDTH/2) { // check ballxpos in relation to paddle xpos. translate the distance from the centre to an angle between 30 and 60 degrees in that direction // ball_pos.y = _p1y + _paddle_height - 1; // ball_velocity.y = -ball_velocity.y; // } // else if (ball_pos.x <= p1_pos.x + PADDLE_WIDTH/2) { // float ang = 40*(((p1_pos.x + PADDLE_WIDTH/2)-ball_pos.x)/(PADDLE_WIDTH/2 - p1_pos.x)) + 30; //converts the distance from the centre to an angle between 30 and 60 // if (ball_velocity.x > 0) { // ball_velocity.x = -ball_velocity.x; // } // ball_pos.y = _p1y + _paddle_heigh - 1; // ball_velocity.y = -tan(ang); // } // else if (ball_pos.x >= p1_pos.x + PADDLE_WIDTH/2) { // float ang = 40*(((p1_pos.x + PADDLE_WIDTH/2)-ball_pos.x)/(PADDLE_WIDTH/2 - p1_pos.x)) + 30; //converts the distance from the centre to an angle between 30 and 60 // if (ball_velocity.x < 0) { // ball_velocity.x = -ball_velocity.x; // } // ball_pos.y = _p1y + _paddle_height - 1; // ball_velocity.y = -tan(ang); // } } // write new attributes _ball.set_velocity(ball_velocity); _ball.set_pos(ball_pos); } void BreakoutEngine::check_brick_collisions(Gamepad &pad) { // read current ball attributes Vector2D ball_pos = _ball.get_pos(); Vector2D ball_velocity = _ball.get_velocity(); for (it_R = listofBricks.begin(); it_R != listofBricks.end(); ++it_R){ if ( (ball_pos.x >= it_R -> get_x()) && //left (ball_pos.x <= it_R -> get_x() + BRICK_WIDTH) && //right (ball_pos.y >= it_R -> get_y()) && //bottom (ball_pos.y <= it_R -> get_y() + BRICK_HEIGHT) //top ) { // edit this so that if it hits the middle, reflect, else change angle depending on how far off centre (add angle to ball) // if it has, fix position and reflect x velocity if (ball_velocity.y < 0) { ball_pos.y = it_R -> get_y() + BRICK_HEIGHT; } else { ball_pos.y = it_R -> get_y(); } ball_velocity.y = -ball_velocity.y; // audio feedback pad.tone(1000.0,0.1); it_R -> hit(); it_R -> hit(); //delete _brick11; it_R -> set_posx(-100); one_less(); } } // write new attributes _ball.set_velocity(ball_velocity); _ball.set_pos(ball_pos); } void BreakoutEngine::check_laser_collisions(Gamepad &pad) { // read current ball attributes // check p1 first for (it_L = listofLasers.begin(); it_L != listofLasers.end(); ++it_L){ for (it_R = listofBricks.begin(); it_R != listofBricks.end(); ++it_R){ if ( (it_L -> get_x() >= it_R -> get_x()) && //left (it_L -> get_x() <= it_R -> get_x() + BRICK_WIDTH) && //right (it_L -> get_y() >= it_R -> get_y()) && //bottom (it_L -> get_y()<= it_R -> get_y() + BRICK_HEIGHT) //top ) { // edit this so that if it hits the middle, reflect, else change angle depending on how far off centre (add angle to ball) // if it has, fix position and reflect x velocity it_L -> set_posx(-10); // audio feedback pad.tone(1000.0,0.1); if(it_R->hit() == true) { it_R -> set_posx(-100); one_less(); } } } } } bool BreakoutEngine::check_goal(Gamepad &pad) { Vector2D ball_pos = _ball.get_pos(); // P1 has scored if (ball_pos.y > HEIGHT) { _p1.lose_life(); //lose_screen(); // go to loss screen then initialise again _ball.init(_ball_size,_speed+_multiplier/2); pad.tone(1500.0,0.5); return true; } else { return false; } } void BreakoutEngine::print_scores(N5110 &lcd) //maybe add to oneless { // get scores from paddles int p1_score = get_prev_score() + (18 - get_num_left())*100 * _multiplier; //maybe add a previous score so the score carries over through victory screens. add hi score fix so restart restarts from 321 // also, add a multiplier of 2 for every contiue on victory // print to LCD i char buffer1[14]; sprintf(buffer1,"%2d",p1_score); lcd.printString("SCORE: ",2 ,0); lcd.printString(buffer1,WIDTH/2 -2,0); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits } int BreakoutEngine::get_prev_score(){ return _prev_score; } int BreakoutEngine::get_num_left(){ return _number_left; } void BreakoutEngine::one_less() { _number_left -= 1; } void BreakoutEngine::reset_num_left() { _number_left = 18; } int BreakoutEngine::get_mult() { return _multiplier; } void BreakoutEngine::inc_mult() { _multiplier ++; } void BreakoutEngine::set_mult_zero() { _multiplier = 0; }