Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ELEC2645_JoystickLCD_LPC1768_2021
Revision 9:6f060f495536, committed 2021-05-06
- Comitter:
- alex_20
- Date:
- Thu May 06 12:04:45 2021 +0000
- Parent:
- 8:1fc5e14b0db6
- Commit message:
- Race Collision for ELEC2645
Changed in this revision
--- a/lib/Ball.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Ball.cpp Thu May 06 12:04:45 2021 +0000 @@ -3,16 +3,15 @@ // constructure Ball::Ball() {} -void Ball::init() { - //initialize parameters - //say that trajectory is 0 +void Ball::init(int radius) { + if (radius > 4 | radius < 0){ + radius = 4; + } } -//std::vector<Vector2Df> Ball::get_path() { -// path points = utils.getCurve; -// return path_points; -// } - -void Ball::draw(N5110 &lcd, std::vector<Vector2Df> path_points, int radius, float iterator) { - lcd.drawCircle(static_cast<int>(path_points[iterator].x), static_cast<int>(path_points[iterator].y), radius, FILL_TRANSPARENT); +void Ball::draw(N5110 &lcd, std::vector<Vector2Df> path_points, int radius, int iterator) { + + if(iterator > 0) { + lcd.drawCircle(static_cast<int>(path_points[iterator].x), static_cast<int>(path_points[iterator].y), radius, FILL_TRANSPARENT); + } } \ No newline at end of file
--- a/lib/Ball.h Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Ball.h Thu May 06 12:04:45 2021 +0000 @@ -12,9 +12,9 @@ public: Ball(); - void init(); + void init(int radius); // std::vector<Vector2Df> get_path; - void draw(N5110 &lcd, std::vector<Vector2Df> path_points, int radius, float iterator); + void draw(N5110 &lcd, std::vector<Vector2Df> path_points, int radius, int iterator); }; #endif
--- a/lib/Car.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Car.cpp Thu May 06 12:04:45 2021 +0000 @@ -3,10 +3,14 @@ // constructure Car::Car() {} -void Car::init() { - //initialize parameters - int direction = STRAIGHT; +void Car::init(int direction, int magnitude, int start_pos) { + // initialize parameters + // direction = STRAIGHT; + // magnitude = 0; + // start_pos = 38 _direction = direction; + _magnitude = magnitude; + _start_pos = start_pos; } @@ -21,29 +25,27 @@ else { _direction = STRAIGHT; } - return _direction; } int Car::get_magnitude(float coord_x) { - int magnitude; if(coord_x > -0.2 && coord_x < 0.2) { - magnitude = 0; + _magnitude = 0; } - else if(coord_x > 0.8 && coord_x < -0.8) { - magnitude = 2; + else if(coord_x > 0.8 || coord_x < -0.8) { + _magnitude = 2; } else { - magnitude = 1; + _magnitude = 1; } - return magnitude; + return _magnitude; } -void Car::draw(N5110 &lcd, float start_pos, float start_angle) { - int x = static_cast<int>(start_pos); +void Car::draw(N5110 &lcd, int start_pos, float start_angle) { + int x = start_pos; int y = static_cast<int>(start_angle); const int rear_face[12][10] = { @@ -132,13 +134,13 @@ lcd.drawSprite(x + y - 2,36,6,4,(int *)wheel); // wheel 3 lcd.drawSprite(x - 2,40,6,4,(int *)wheel); // wheel 1 - lcd.drawLine(x,42,x + y,38,0,1); // line to connect corner 3 - lcd.drawLine(x + 9,42,x + y + 9,38,0,1); // line to connect corner 4 + lcd.drawLine(x,42,x + y,38,0,1); // line to connect corner left bottom + lcd.drawLine(x + 9,42,x + y + 9,38,0,1); // line to connect corner right bottom lcd.drawSprite(x + y + 8,36,6,4,(int *)wheel); // wheel 4 - lcd.drawLine(x,32,x + y,26,0,1); // line to connect corner 1 - lcd.drawLine(x + 9,32,x + y + 9,26,0,1); // line to connect corner 2 + lcd.drawLine(x,32,x + y,26,0,1); // line to connect corner left up + lcd.drawLine(x + 9,32,x + y + 9,26,0,1); // line to connect corner right up lcd.drawSprite(x,32,12,10,(int *)rear_face); lcd.drawSprite(x + 8,40,6,4,(int *)wheel); // wheel 2 @@ -147,19 +149,19 @@ case LEFT: lcd.drawSprite(x - y - 2,26,10,10,(int *)window); - //lcd.drawSprite(x - y,26,12,10,(int *)front_face); lcd.drawLine(x - y,26,x - y + 9,26,0,1); // front face lcd.drawLine(x - y,26,x - y,36,0,1); // front face lcd.drawSprite(x - y + 8,36,6,4,(int *)wheel); // wheel 4 lcd.drawSprite(x + 8,40,6,4,(int *)wheel); // wheel 2 - lcd.drawLine(x + 9,42,x - y + 9,38,0,1); // line to connect corner 4 + lcd.drawLine(x + 9,42,x - y + 9,38,0,1); // line to connect corner right bottom + lcd.drawLine(x,42,x - y,38,0,1); // line to connect corner left bottom lcd.drawSprite(x - 2 - y,36,6,4,(int *)wheel); // wheel 3 - lcd.drawLine(x,32,x - y,26,0,1); // line to connect corner 1 - lcd.drawLine(x + 9,32,x - y + 9,26,0,1); // line to connect corner 2 + lcd.drawLine(x,32,x - y,26,0,1); // line to connect corner right up + lcd.drawLine(x + 9,32,x - y + 9,26,0,1); // line to connect corner left up lcd.drawSprite(x,32,12,10,(int *)rear_face); lcd.drawSprite(x - 2,40,6,4,(int *)wheel); // wheel 1
--- a/lib/Car.h Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Car.h Thu May 06 12:04:45 2021 +0000 @@ -17,13 +17,15 @@ public: Car(); - void init(); + void init(int direction, int magnitude, int start_pos); int get_direction(float coord_x); int get_magnitude(float coord_x); - void draw(N5110 &lcd, float start_pos, float start_angle); + void draw(N5110 &lcd, int start_pos, float start_angle); private: int _direction; + int _magnitude; + int _start_pos; }; #endif \ No newline at end of file
--- a/lib/GameEngine.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/GameEngine.cpp Thu May 06 12:04:45 2021 +0000 @@ -1,89 +1,131 @@ -#include "PongEngine.h" - -PongEngine::PongEngine(){ _lives = 4; } +#include "GameEngine.h" -void PongEngine::init(int paddle_position, int paddle_height, int paddle_width, int ball_size, int speed){ - //printf("Pong Engine: Init\n"); - _ball.init(ball_size,speed); - _paddle.init(paddle_position, paddle_height, paddle_width); -} +// constructure +GameEngine::GameEngine() {} -int PongEngine::update(UserInput input) { - //printf("Pong Engine: Update\n"); - check_goal(); // checking for a goal is a priority - _ball.update(); - _paddle.update(input); - // important to update paddles and ball before checking collisions so can - // correct for it before updating the display - check_wall_collision(); - check_paddle_collision(); +void GameEngine::init(int road_direction, + int road_inclination, + int radius, + std::vector<Vector2Df> ball_path, + int car_direction, + int car_magnitude, + int car_start_pos, + float road_offset, + float car_turn, + float ball_it) +{ + _road_direction = road_direction; + _road_inclination = road_inclination; + _radius = radius; + _ball_path = ball_path; + _car_direction = car_direction; + _car_magnitude = car_magnitude; + _car_start_pos = car_start_pos; + _road_offset = road_offset; + _car_turn = car_turn; + _ball_it = ball_it; - return _lives; -} - -void PongEngine::draw(N5110 &lcd) { - _road.draw(lcd); + // initialize all the parameters from the game + _ball.init(_radius); + _road.init(_road_direction, _road_inclination); + _car.init(_car_direction, _car_magnitude, _car_start_pos); } -void PongEngine::check_wall_collision() { - //printf("Pong Engine: Check Wall Collision\n"); - // read current ball attributes - Position2D ball_pos = _ball.get_pos(); - Position2D ball_velocity = _ball.get_velocity(); - int size = _ball.get_size(); + +void GameEngine::update(float car_coord) { - // check if hit top wall - if (ball_pos.y <= 1) { // 1 due to 1 pixel boundary - ball_pos.y = 1; // bounce off ceiling without going off screen - ball_velocity.y = -ball_velocity.y; // flip velocity - } else if (ball_pos.y + size >= (HEIGHT-1) ) { - // hit bottom - ball_pos.y = (HEIGHT-1) - size; // stops ball going off screen - ball_velocity.y = -ball_velocity.y; // flip velcoity - } else if (ball_pos.x + size >= (WIDTH-1) ) { - // hit right wall - ball_pos.x = (WIDTH-1) - size; // stops ball going off screen - ball_velocity.x = -ball_velocity.x; // flip velcoity + // Get the user input to know where to draw the car + _car_direction = _car.get_direction(car_coord); + _car_magnitude = _car.get_magnitude(car_coord); + + if(_car_direction == 0) { // STRAIGHT + _car_turn = 0; + } + if(_car_direction == 2) { // LEFT + if(_car_magnitude == 1) { + _car_turn = 4.0; + } + if(_car_magnitude == 2) { + _car_turn = 6.0; + } + _car_start_pos -= 0.2 * _car_magnitude; + } + if(_car_direction == 1) { // RIGHT + if(_car_magnitude == 1) { + _car_turn = 4.0; + } + if(_car_magnitude == 2) { + _car_turn = 6.0; + } + _car_start_pos += 0.2 * _car_magnitude; + } + + // Define boundaries for car movement + if(_car_start_pos < 22.0) { + _car_start_pos = 22.0; + } + if(_car_start_pos > 55.0) { + _car_start_pos = 55.0; } - // update ball parameters - _ball.set_velocity(ball_velocity); - _ball.set_pos(ball_pos); + // Make sure that middle line on road is moving continuously + _road_offset += 0.01; + + + if(_ball_it < _ball_path.size()){ + _ball_it += 0.3; + // Get the ball generation function + _iterator = static_cast<int>(_ball_path.size() - _ball_it); + } + else { + _iterator = 0; + } } -void PongEngine::check_paddle_collision() { - //printf("Pong Engine: Check Paddle Collision\n"); - // read current ball and paddle attributes - Position2D ball_pos = _ball.get_pos(); - Position2D ball_velocity = _ball.get_velocity(); - Position2D paddle_pos = _paddle.get_pos(); // paddle +void GameEngine::reset_ball() { + _ball_it = 0; +} + - // see if ball has hit the paddle by checking for overlaps - if ( - (ball_pos.y >= paddle_pos.y) && //top - (ball_pos.y <= paddle_pos.y + _paddle.get_height() ) && //bottom - (ball_pos.x >= paddle_pos.x) && //left - (ball_pos.x <= paddle_pos.x + _paddle.get_width() ) //right - ) { - // if it has, fix position and reflect x velocity - ball_pos.x = paddle_pos.x + _paddle.get_width(); - ball_velocity.x = -ball_velocity.x; +void GameEngine::draw(N5110 &lcd, Utils &utils) { + _road.draw(lcd, utils, _road_direction, _road_offset); + _ball.draw(lcd, _ball_path, _radius, _iterator); + _car.draw(lcd, _car_start_pos, _car_turn); +} + + +int GameEngine::check_collision() { + if (static_cast<int>(_ball_path[_iterator].y) > 38 + && static_cast<int>(_ball_path[_iterator].y) < 46 + && static_cast<int>(_ball_path[_iterator].x) <= _car_start_pos + 12 + && static_cast<int>(_ball_path[_iterator].x) >= _car_start_pos - 2) + { + return 1; } - // write new attributes - _ball.set_velocity(ball_velocity); - _ball.set_pos(ball_pos); + + else { + return 0; + } +} + + +void GameEngine::generate_road(float tilt) { + + if (_road_direction < tilt - 0.05) { + _road_direction += 0.05; + } + + else if (_road_direction > tilt + 0.05) { + _road_direction -= 0.05; + } + + else { + _road_direction = tilt; + } } -void PongEngine::check_goal() { - //printf("Pong Engine: Check Goal\n"); - Position2D ball_pos = _ball.get_pos(); - int size = _ball.get_size(); - int speed = abs(_ball.get_velocity().x); // speed is magnitude of velocity - // check if ball position has gone off the left - if (ball_pos.x + size < 0) { - // reset the ball - _ball.init(size,speed); - _lives--; // lose a life - } +void GameEngine::generate_ball(int start){ + std::vector<Vector2Df> ball_path = _utils.getCurve(42 + start,48,42 + 5 * _road_direction + start, 30 - abs(_road_direction),42 + start,12); + _ball_path = ball_path; } \ No newline at end of file
--- a/lib/GameEngine.h Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/GameEngine.h Thu May 06 12:04:45 2021 +0000 @@ -7,21 +7,64 @@ #include "Utils.h" #include "Road.h" #include "Car.h" -#include "Vector.h" +#include "Vector.h" -class GameEngine { - public: - GameEngine(); // pass in the lcd object from the main file - void init(int paddle_position,int paddle_height,int paddle_width,int ball_size,int speed); - int update(UserInput input); - void sign(N5110 &lcd, Road &road); - void draw(N5110 &lcd); - private: - void check_collision(); - void generate_ball(); - void generate_road(); - Ball _ball; - Road _road; +class GameEngine +{ +public: + + GameEngine(); + + /** Initialize game + * @param road_direction - set up the road as STRAIGHT (0) + * @param road_inclination - set up the inclination of the road as 0 + * @param radius - set the ball radius as 4 + * @param ball_path - initial the ball start position + * @param car_direction - set up the car view as STRAIGHT (0) + * @param car_magnitude - set up the car tilt as 0 + * @param car_start_pos - set up the car position as 38 (right in the centre) + * @param road_offset - should increase continuously + * @param car_turn - the angle at which the car turns + * @param ball_it - the iterator that draws the ball + **/ + void init(int road_direction, + int road_inclination, + int radius, + std::vector<Vector2Df> ball_path, + int car_direction, + int car_magnitude, + int car_start_pos, + float road_offset, + float car_turn, + float ball_it); + + int check_collision(); + void update(float car_coord); + void sign(N5110 &lcd, Road &road); + void reset_ball(); + void draw(N5110 &lcd, Utils &utils); + void generate_road(float tilt); + void generate_ball(int start); + + +private: + + Ball _ball; + Road _road; + Car _car; + Utils _utils; + + float _road_offset; // Road + float _road_direction; // Road, i + int _road_inclination; // Road + float _ball_it; // Ball, it + int _radius; // Ball + std::vector<Vector2Df> _ball_path; // Ball + int _iterator; // Ball + int _car_direction; // Car + int _car_magnitude; // Car + float _car_start_pos; // Car + float _car_turn; // Car, y + }; - #endif \ No newline at end of file
--- a/lib/Road.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Road.cpp Thu May 06 12:04:45 2021 +0000 @@ -3,24 +3,23 @@ // constructure Road::Road() {} -void Road::init() { +void Road::init(float direction, float inclination) { //initialize parameters - int direction = 0; - int inclination = 0; - _direction = direction; _inclination = inclination; } -void Road::set_inclination(int inclination) { +void Road::set_inclination(float inclination) { _inclination = inclination; } void Road::draw(N5110 &lcd, Utils &utils, float direction, float offset) { + // direction is i in the main code + // use "+= or -= speed" to get the direction of the road lcd.drawLine (0,12,84,12,0,1); - std::vector<Vector2Df> curve_points_1 = utils.getCurve(12,48,20 + 5 * direction, 30 - abs(direction),28,12); - std::vector<Vector2Df> curve_points_2 = utils.getCurve(72,48,64 + 5 * direction, 30 - abs(direction),56,12); - std::vector<Vector2Df> curve_points_3 = utils.getCurve(42,48,42 + 5 * direction, 30 - abs(direction),42,12); + std::vector<Vector2Df> curve_points_1 = utils.getCurve(12,48,20 + 5 * direction, 30 - abs(direction),28,12); // LEFT + std::vector<Vector2Df> curve_points_2 = utils.getCurve(72,48,64 + 5 * direction, 30 - abs(direction),56,12); // RIGHT + std::vector<Vector2Df> curve_points_3 = utils.getCurve(42,48,42 + 5 * direction, 30 - abs(direction),42,12); // MIDDLE lcd.drawCurve(curve_points_1, 0, 1, TYPE_SOLID); lcd.drawCurve(curve_points_2, 0, 1, TYPE_SOLID);
--- a/lib/Road.h Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Road.h Thu May 06 12:04:45 2021 +0000 @@ -13,15 +13,15 @@ public: Road(); - void init(); - void set_inclination(int inclination); + void init(float direction, float inclination); + void set_inclination(float inclination); void draw(N5110 &lcd, Utils &utils, float direction, float offset); void draw_warn(N5110 &lcd, int warn_position); private: - int _inclination; - int _direction; + float _inclination; + float _direction; }; #endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/ShiftReg.cpp Thu May 06 12:04:45 2021 +0000 @@ -0,0 +1,26 @@ +#include "ShiftReg.h" + +ShiftReg::ShiftReg() +{ + clkout = new DigitalOut(p7); + dataout = new DigitalOut(p5); + latchout = new DigitalOut(p30); +} + +ShiftReg::~ShiftReg() +{ + delete clkout; + delete dataout; + delete latchout; +} + +void ShiftReg::write(int data) +{ + *latchout = 0; + for (int i = 7; i >= 0; i--) { + *clkout = 0; + *dataout = (data & (1 << i)) != 0; + *clkout = 1; + } + *latchout = 1; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/ShiftReg.h Thu May 06 12:04:45 2021 +0000 @@ -0,0 +1,23 @@ +#ifndef SHIFTREG_H +#define SHIFTREG_H + +#include <mbed.h> + +/** A simple serial driver for a shift register that uses only three digital out pins. +* Based on a fork of Ollie8/ShiftOut +*/ +class ShiftReg { + + public : + + ShiftReg(); + ~ShiftReg(); + void write(int data); + + private : + DigitalOut *clkout; + DigitalOut *dataout; + DigitalOut *latchout; +}; + +#endif \ No newline at end of file
--- a/lib/Utils.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/lib/Utils.cpp Thu May 06 12:04:45 2021 +0000 @@ -25,7 +25,7 @@ { // vertor that will store all points std::vector<Vector2Df> curve_points; - for(float i = 0 ; i <= 1 ; i += 0.2) + for(float i = 0 ; i <= 1 ; i += 0.05) { float xa, ya, xb, yb; xa = curveEquation(x0 , x1 , i);
--- a/main.cpp Sat Apr 24 21:31:19 2021 +0000 +++ b/main.cpp Thu May 06 12:04:45 2021 +0000 @@ -4,6 +4,7 @@ */ #include "mbed.h" +#include "ShiftReg.h" #include "Joystick.h" #include "N5110.h" #include "Road.h" @@ -11,13 +12,20 @@ #include "Utils.h" #include "Vector.h" #include "Ball.h" +#include "Vector.h" +#include "GameEngine.h" +#include <stdlib.h> +#include <time.h> // objects // BusOut leds(LED4,LED3,LED2,LED1); N5110 lcd(p14,p8,p9,p10,p11,p13,p21); -DigitalIn button_A(p29); +InterruptIn button_A(p29); +DigitalIn button_B(p28); DigitalIn button_C(p27); +DigitalIn button_D(p26); +ShiftReg seven_seg; // y x Joystick joystick(p20,p19); @@ -30,6 +38,13 @@ Utils utils; Car car; Ball ball; +GameEngine game; +Ticker ticker; + +// flag - must be volatile as changes within ISR +// g_ prefix makes it easier to distinguish it as global +volatile int g_timer_flag = 0; +volatile int g_buttonA_flag = 0; #define speed 0.01 #define road_speed 0.016 @@ -37,93 +52,158 @@ // functions void init_buttons(); +void init(); +void render(); +void menu(); +void instructions(); +void pause(); +void game_over(); +void draw_arrow(int x, int y); +void timer_isr(); +void buttonA_isr(); +void display_lives(int lives); int main() { - // initialisation - lcd.init(); - road.init(); - car.init(); - joystick.init(); - lcd.setContrast(0.5); - - float i = 0; - float offset = 0; - float start_pos = 38.0; - float y = 0.0; - float it = 0.0; - float perspective = 0.0; + button_A.rise(&buttonA_isr); + init_buttons(); + int state = 0; // set inital state + init(); + // welcome(); + int up_down = 17; + float number_1 = 0; + float number_2 = 0; + int lives = 4; + int old_collision = 0; + display_lives(0); + + // set-up the ticker so that the ISR it is called every 5 seconds + ticker.attach(&timer_isr,5); while(1) { lcd.clear(); - road.draw(lcd, utils, i, offset); - - if (button_A.read() == 1) { + Vector2D coord = joystick.get_mapped_coord(); + switch(state) { - road.draw_warn(lcd, 1); - i += speed; - } - - if (button_C.read() == 1) { - road.draw_warn(lcd, 2); - i -= speed; - } - offset += road_speed; - - Vector2D coord = joystick.get_mapped_coord(); - int direction = car.get_direction(coord.x); - int magnitude = car.get_magnitude(coord.x); - - if(direction == STRAIGHT) { - y = 0; + case 0: // Main Menu + { + menu(); + lives = 4; + display_lives(0); + if(coord.y >= 0.5) { + up_down = 17; + } + + if(coord.y <= -0.5) { + up_down = 25; + } + + draw_arrow(2,up_down); + + if(g_buttonA_flag) { + if(up_down == 17){ + state = 1; + g_buttonA_flag = 0; + } + if(up_down == 25) { + state = 2; + g_buttonA_flag = 0; + } + } + break; } - - if(direction == LEFT) { - if(magnitude == 1) { - y = 4.0; - } - if(magnitude == 2) { - y = 4.0; + + + case 1: // Actual Game + { + game.update(coord.x); + + // check if flag is set i.e. interrupt has occured + if (g_timer_flag) { + g_timer_flag = 0; // if it has, clear the flag + + // generate random road or ball + // initialize random seed: + srand (time(NULL)); + + number_1 = (rand() % 20 + 1) - 10; + number_2 = (static_cast <float> (rand()) / (static_cast <float> (RAND_MAX/10.0))) - 5.0; + game.reset_ball(); } - start_pos -= car_speed; - } - - if(direction == RIGHT) { - if(magnitude == 1) { - y = 4.0; + + game.generate_ball(number_1); + game.generate_road(number_2); + + // put the MCU to sleep until an interrupt wakes it up + sleep(); + render(); + display_lives(lives); + + int collision = game.check_collision(); + if(collision == 1 && old_collision == 0) { + lives--; + if (lives == 0) { + state = 4; + } + } + + old_collision = collision; + + if(g_buttonA_flag) { + state = 3; + g_buttonA_flag = 0; + } + break; + } + + + case 2: // Instructions + { + instructions(); + if(g_buttonA_flag) { + state = 0; + g_buttonA_flag = 0; } - if(magnitude == 2) { - y = 8.0; + break; + } + + + case 3: // Pause Menu + { + pause(); + if(coord.y >= 0.5) { + up_down = 17; } - start_pos += car_speed; - } - - // define boundaries for car movement - if(start_pos < 20.0) { - start_pos = 20.0; + if(coord.y <= -0.5) { + up_down = 25; + } + + draw_arrow(2,up_down); + if(g_buttonA_flag) { + if(up_down == 17){ + state = 1; + g_buttonA_flag = 0; + } + if(up_down == 25) { + state = 0; + g_buttonA_flag = 0; + } + } + break; + } + + case 4: // Game over + { + game_over(); + if(g_buttonA_flag) { + state = 0; + g_buttonA_flag = 0; + } + break; + } } - - if(start_pos > 55.0) { - start_pos = 55.0; - } - - car.draw(lcd,start_pos,y); - - std::vector<Vector2Df> path_points = utils.getCurve(12,60,25,30,28,12); - float iterator = path_points.size() - it; - - // take the current coordinates and draw circle on the line - ball.draw(lcd, path_points, 4, iterator); - it += 0.03; - perspective += road_speed; - - printf("%f\n", it); - - if (it > 10) { - it = 0; - } - - lcd.refresh(); + sleep(); + lcd.refresh(); } } @@ -132,5 +212,101 @@ // PCB has external pull-down resistors so turn the internal ones off // (default for DigitalIn) button_A.mode(PullNone); + button_B.mode(PullNone); button_C.mode(PullNone); + button_D.mode(PullNone); +} + + +void init() { + seven_seg.write(0x00); + lcd.init(); + joystick.init(); + lcd.setContrast(0.55); + + std::vector<Vector2Df> curve_point; + Vector2Df point = {-20.0,-50.0}; + curve_point.push_back(point); + + game.init(0.0, // road direction + 0.0, // road inclination + 4, // ball radius + curve_point, // points from ball path + 0, // car direction + 0, // car magnitude + 38.0, // car start position + 0.0, // offset + 0.0, // car_turn + 0.0); // ball_it +} + +void menu() { + lcd.printString("MAIN MENU",15,0); + lcd.printString("Start Game",10,2); + lcd.printString("Instructions",10,3); + lcd.printString("Press A",20,5); +} + +void instructions() { + lcd.printString("INSTRUCTIONS",6,0); + lcd.printString("Use joystick",6,1); + lcd.printString("to move",21,2); + lcd.printString("Press A to",13,4); + lcd.printString("pause or exit",4,5); + display_lives(0); +} + +void pause() { + lcd.printString("PAUSE",27,0); + lcd.printString("Back to game",10,2); + lcd.printString("Back to menu",10,3); +} + +void game_over() { + lcd.printString("GAME OVER",16,1); + lcd.printString("Don't collide!",1,2); + lcd.printString("Press A",20,5); +} + +void render() { + game.draw(lcd, utils); +} + +void draw_arrow(int x, int y) { + const int arrow[5][7] = { + { 0, 0, 0, 0, 1, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 0 }, + { 1, 1, 1, 1, 1, 1, 1 }, + { 1, 1, 1, 1, 1, 1, 0 }, + { 0, 0, 0, 0, 1, 0, 0 }, + }; + lcd.drawSprite(x,y,5,7,(int *)arrow); +} + +// time-triggered interrupt +void timer_isr() { + g_timer_flag = 1; // set flag in ISR +} + +// Button A event-triggered interrupt +void buttonA_isr() { + g_buttonA_flag = 1; // set flag in ISR +} + +void display_lives(int lives) { + if (lives == 4) { + lcd.printString("Lives: 4",0,0); + seven_seg.write(0x66); + } else if (lives == 3) { + lcd.printString("Lives: 3",0,0); + seven_seg.write(0x4F); + } else if (lives == 2) { + lcd.printString("Lives: 2",0,0); + seven_seg.write(0x5B); + } else if (lives == 1) { + lcd.printString("Lives: 1",0,0); + seven_seg.write(0x06); + } else { + seven_seg.write(0x3F); + } } \ No newline at end of file