“Race Collision” is a one player game in which a truck has to avoid “particles” that appear on the road. By the use of the joystick, the player can guide themselves through the menu system to start the game. The truck is the main element of the game and it can be moved from side to side with the joystick. The road curves randomly from time to time and the player has to be careful to keep the truck within the road boundaries. Particles appear on the screen at random positions and 4 collisions lead to the end of the game.

Dependencies:   ELEC2645_JoystickLCD_LPC1768_2021

Committer:
eencae
Date:
Fri Dec 11 12:25:25 2020 +0000
Revision:
0:be41a15e7a86
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:be41a15e7a86 1 #include "Joystick.h"
eencae 0:be41a15e7a86 2
eencae 0:be41a15e7a86 3 Joystick::Joystick(PinName vertPin,PinName horizPin)
eencae 0:be41a15e7a86 4 {
eencae 0:be41a15e7a86 5 vert = new AnalogIn(vertPin);
eencae 0:be41a15e7a86 6 horiz = new AnalogIn(horizPin);
eencae 0:be41a15e7a86 7 }
eencae 0:be41a15e7a86 8
eencae 0:be41a15e7a86 9 void Joystick::init()
eencae 0:be41a15e7a86 10 {
eencae 0:be41a15e7a86 11 // read centred values of joystick
eencae 0:be41a15e7a86 12 _x0 = horiz->read();
eencae 0:be41a15e7a86 13 _y0 = vert->read();
eencae 0:be41a15e7a86 14
eencae 0:be41a15e7a86 15 // this assumes that the joystick is centred when the init function is called
eencae 0:be41a15e7a86 16 // if perfectly centred, the pots should read 0.5, but this may
eencae 0:be41a15e7a86 17 // not be the case and x0 and y0 will be used to calibrate readings
eencae 0:be41a15e7a86 18 }
eencae 0:be41a15e7a86 19
eencae 0:be41a15e7a86 20 Direction Joystick::get_direction()
eencae 0:be41a15e7a86 21 {
eencae 0:be41a15e7a86 22 float angle = get_angle(); // 0 to 360, -1 for centred
eencae 0:be41a15e7a86 23
eencae 0:be41a15e7a86 24 Direction d;
eencae 0:be41a15e7a86 25 // partition 360 into segments and check which segment the angle is in
eencae 0:be41a15e7a86 26 if (angle < 0.0f) {
eencae 0:be41a15e7a86 27 d = CENTRE; // check for -1.0 angle
eencae 0:be41a15e7a86 28 } else if (angle < 22.5f) { // then keep going in 45 degree increments
eencae 0:be41a15e7a86 29 d = N;
eencae 0:be41a15e7a86 30 } else if (angle < 67.5f) {
eencae 0:be41a15e7a86 31 d = NE;
eencae 0:be41a15e7a86 32 } else if (angle < 112.5f) {
eencae 0:be41a15e7a86 33 d = E;
eencae 0:be41a15e7a86 34 } else if (angle < 157.5f) {
eencae 0:be41a15e7a86 35 d = SE;
eencae 0:be41a15e7a86 36 } else if (angle < 202.5f) {
eencae 0:be41a15e7a86 37 d = S;
eencae 0:be41a15e7a86 38 } else if (angle < 247.5f) {
eencae 0:be41a15e7a86 39 d = SW;
eencae 0:be41a15e7a86 40 } else if (angle < 292.5f) {
eencae 0:be41a15e7a86 41 d = W;
eencae 0:be41a15e7a86 42 } else if (angle < 337.5f) {
eencae 0:be41a15e7a86 43 d = NW;
eencae 0:be41a15e7a86 44 } else {
eencae 0:be41a15e7a86 45 d = N;
eencae 0:be41a15e7a86 46 }
eencae 0:be41a15e7a86 47
eencae 0:be41a15e7a86 48 return d;
eencae 0:be41a15e7a86 49 }
eencae 0:be41a15e7a86 50
eencae 0:be41a15e7a86 51 // this method gets the magnitude of the joystick movement
eencae 0:be41a15e7a86 52 float Joystick::get_mag()
eencae 0:be41a15e7a86 53 {
eencae 0:be41a15e7a86 54 Polar p = get_polar();
eencae 0:be41a15e7a86 55 return p.mag;
eencae 0:be41a15e7a86 56 }
eencae 0:be41a15e7a86 57
eencae 0:be41a15e7a86 58 // this method gets the angle of joystick movement (0 to 360, 0 North)
eencae 0:be41a15e7a86 59 float Joystick::get_angle()
eencae 0:be41a15e7a86 60 {
eencae 0:be41a15e7a86 61 Polar p = get_polar();
eencae 0:be41a15e7a86 62 return p.angle;
eencae 0:be41a15e7a86 63 }
eencae 0:be41a15e7a86 64
eencae 0:be41a15e7a86 65 // get raw joystick coordinate in range -1 to 1
eencae 0:be41a15e7a86 66 // Direction (x,y)
eencae 0:be41a15e7a86 67 // North (0,1)
eencae 0:be41a15e7a86 68 // East (1,0)
eencae 0:be41a15e7a86 69 // South (0,-1)
eencae 0:be41a15e7a86 70 // West (-1,0)
eencae 0:be41a15e7a86 71 Vector2D Joystick::get_coord()
eencae 0:be41a15e7a86 72 {
eencae 0:be41a15e7a86 73 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
eencae 0:be41a15e7a86 74 // substracted to get values in the range -1.0 to 1.0
eencae 0:be41a15e7a86 75 float x = 2.0f*( horiz->read() - _x0 );
eencae 0:be41a15e7a86 76 float y = 2.0f*( vert->read() - _y0 );
eencae 0:be41a15e7a86 77
eencae 0:be41a15e7a86 78 // Note: the values are negated so positive is up and right.
eencae 0:be41a15e7a86 79 Vector2D coord = {-x,y};
eencae 0:be41a15e7a86 80 return coord;
eencae 0:be41a15e7a86 81 }
eencae 0:be41a15e7a86 82
eencae 0:be41a15e7a86 83 // This maps the raw x,y coord onto a circular grid.
eencae 0:be41a15e7a86 84 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
eencae 0:be41a15e7a86 85 Vector2D Joystick::get_mapped_coord()
eencae 0:be41a15e7a86 86 {
eencae 0:be41a15e7a86 87 Vector2D coord = get_coord();
eencae 0:be41a15e7a86 88
eencae 0:be41a15e7a86 89 // do the transformation
eencae 0:be41a15e7a86 90 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
eencae 0:be41a15e7a86 91 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
eencae 0:be41a15e7a86 92
eencae 0:be41a15e7a86 93 Vector2D mapped_coord = {x,y};
eencae 0:be41a15e7a86 94 return mapped_coord;
eencae 0:be41a15e7a86 95 }
eencae 0:be41a15e7a86 96
eencae 0:be41a15e7a86 97 // this function converts the mapped coordinates into polar form
eencae 0:be41a15e7a86 98 Polar Joystick::get_polar()
eencae 0:be41a15e7a86 99 {
eencae 0:be41a15e7a86 100 // get the mapped coordinate
eencae 0:be41a15e7a86 101 Vector2D coord = get_mapped_coord();
eencae 0:be41a15e7a86 102
eencae 0:be41a15e7a86 103 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
eencae 0:be41a15e7a86 104 // We want 0 degrees to correspond to North and increase clockwise to 359
eencae 0:be41a15e7a86 105 // like a compass heading, so we need to swap the axis and invert y
eencae 0:be41a15e7a86 106 float x = coord.y;
eencae 0:be41a15e7a86 107 float y = coord.x;
eencae 0:be41a15e7a86 108
eencae 0:be41a15e7a86 109 float mag = sqrt(x*x+y*y); // pythagoras
eencae 0:be41a15e7a86 110 float angle = RAD2DEG*atan2(y,x);
eencae 0:be41a15e7a86 111 // angle will be in range -180 to 180, so add 360 to negative angles to
eencae 0:be41a15e7a86 112 // move to 0 to 360 range
eencae 0:be41a15e7a86 113 if (angle < 0.0f) {
eencae 0:be41a15e7a86 114 angle+=360.0f;
eencae 0:be41a15e7a86 115 }
eencae 0:be41a15e7a86 116
eencae 0:be41a15e7a86 117 // the noise on the ADC causes the values of x and y to fluctuate slightly
eencae 0:be41a15e7a86 118 // around the centred values. This causes the random angle values to get
eencae 0:be41a15e7a86 119 // calculated when the joystick is centred and untouched. This is also when
eencae 0:be41a15e7a86 120 // the magnitude is very small, so we can check for a small magnitude and then
eencae 0:be41a15e7a86 121 // set the angle to -1. This will inform us when the angle is invalid and the
eencae 0:be41a15e7a86 122 // joystick is centred
eencae 0:be41a15e7a86 123
eencae 0:be41a15e7a86 124 if (mag < TOL) {
eencae 0:be41a15e7a86 125 mag = 0.0f;
eencae 0:be41a15e7a86 126 angle = -1.0f;
eencae 0:be41a15e7a86 127 }
eencae 0:be41a15e7a86 128
eencae 0:be41a15e7a86 129 Polar p = {mag,angle};
eencae 0:be41a15e7a86 130 return p;
eencae 0:be41a15e7a86 131 }