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