DuckHunt game using IMU sensor and uLCD display

Dependencies:   4DGL-uLCD-SE LSM9DS1_Library_cal SDFileSystem mbed wave_player

Fork of uLCD144G2_demo by jim hamblen

Committer:
jli26
Date:
Mon Oct 31 21:20:17 2016 +0000
Revision:
10:c19a945d9dca
Parent:
8:31e63caf37e2
Duck Hunt Game

Who changed what in which revision?

UserRevisionLine numberNew contents of line
4180_1 8:31e63caf37e2 1 // uLCD-144-G2 demo program for uLCD-4GL LCD driver library
4180_1 0:cfcf73272647 2 //
4180_1 0:cfcf73272647 3 #include "mbed.h"
4180_1 2:75727e89a717 4 #include "uLCD_4DGL.h"
jli26 10:c19a945d9dca 5 #include "LSM9DS1.h"
jli26 10:c19a945d9dca 6 #include <math.h>
jli26 10:c19a945d9dca 7 #include "PinDetect.h"
jli26 10:c19a945d9dca 8 #include "SDFileSystem.h"
jli26 10:c19a945d9dca 9 #include "wave_player.h"
4180_1 0:cfcf73272647 10
jli26 10:c19a945d9dca 11
jli26 10:c19a945d9dca 12
jli26 10:c19a945d9dca 13 #define PI 3.14159
jli26 10:c19a945d9dca 14 // Earth's magnetic field varies by location. Add or subtract
jli26 10:c19a945d9dca 15 // a declination to get a more accurate heading. Calculate
jli26 10:c19a945d9dca 16 // your's here:
jli26 10:c19a945d9dca 17 // http://www.ngdc.noaa.gov/geomag-web/#declination
jli26 10:c19a945d9dca 18 #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
4180_1 0:cfcf73272647 19
jli26 10:c19a945d9dca 20 uLCD_4DGL uLCD(p9,p10,p30); // serial tx, serial rx, reset pin;
jli26 10:c19a945d9dca 21 DigitalOut myled(LED1);
jli26 10:c19a945d9dca 22 Serial pc(USBTX, USBRX);
jli26 10:c19a945d9dca 23 Serial device(p28, p27);
jli26 10:c19a945d9dca 24
jli26 10:c19a945d9dca 25 PinDetect trigger(p21);
jli26 10:c19a945d9dca 26
jli26 10:c19a945d9dca 27 //speaker
jli26 10:c19a945d9dca 28 SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
jli26 10:c19a945d9dca 29 AnalogOut DACout(p18);
jli26 10:c19a945d9dca 30 wave_player waver(&DACout);
jli26 10:c19a945d9dca 31 //
jli26 10:c19a945d9dca 32
jli26 10:c19a945d9dca 33
jli26 10:c19a945d9dca 34
4180_1 7:7bd7397ab89f 35
jli26 10:c19a945d9dca 36 //duck
jli26 10:c19a945d9dca 37 int duckWidth = 20;
jli26 10:c19a945d9dca 38 int duckHeight = 20;
jli26 10:c19a945d9dca 39 int duckx = 64;
jli26 10:c19a945d9dca 40 int ducky = 40;
jli26 10:c19a945d9dca 41 int duckDY = 3;
jli26 10:c19a945d9dca 42 int duckDX = 3;
jli26 10:c19a945d9dca 43 int duckMaxSpeed = 10;
jli26 10:c19a945d9dca 44 int duckMinSpeed = 4;
jli26 10:c19a945d9dca 45 //
jli26 10:c19a945d9dca 46
jli26 10:c19a945d9dca 47 //aimer
jli26 10:c19a945d9dca 48 int aimerWidth = 20;
jli26 10:c19a945d9dca 49 int aimerHeight = 20;
jli26 10:c19a945d9dca 50 int aimerx = 64;
jli26 10:c19a945d9dca 51 int aimery = 64;
jli26 10:c19a945d9dca 52 //
jli26 10:c19a945d9dca 53
jli26 10:c19a945d9dca 54 //trigger
jli26 10:c19a945d9dca 55 bool hit = false;
jli26 10:c19a945d9dca 56
jli26 10:c19a945d9dca 57 //duckreset
jli26 10:c19a945d9dca 58 bool duckReset = false;
jli26 10:c19a945d9dca 59
jli26 10:c19a945d9dca 60 //scoreboard
jli26 10:c19a945d9dca 61 int scoreCount = 0;
jli26 10:c19a945d9dca 62 bool scoreChange = false;
jli26 10:c19a945d9dca 63
jli26 10:c19a945d9dca 64 // countinghits.wav
jli26 10:c19a945d9dca 65 // duck-hunt-intro.wav
jli26 10:c19a945d9dca 66
jli26 10:c19a945d9dca 67
jli26 10:c19a945d9dca 68 void trigger_hit_callback() {
jli26 10:c19a945d9dca 69 device.putc(pc.printf("aimerx: %d, aimery: %d \n\r",aimerx,aimery));
jli26 10:c19a945d9dca 70 device.putc(pc.printf("duckx: %d, ducky: %d \n\r",duckx,ducky));
jli26 10:c19a945d9dca 71 device.putc(pc.printf("duckx: %d, ducky: %d \n\r",duckx + duckWidth,ducky + duckHeight));
jli26 10:c19a945d9dca 72 hit = true;
jli26 10:c19a945d9dca 73 if (aimery >= duckx && aimery <= (duckx + duckWidth)){
jli26 10:c19a945d9dca 74 if (aimerx >= ducky && aimerx <= (ducky + duckHeight)){
jli26 10:c19a945d9dca 75 duckReset = true;
jli26 10:c19a945d9dca 76 scoreCount = scoreCount + 1;
jli26 10:c19a945d9dca 77 scoreChange = true;
jli26 10:c19a945d9dca 78 device.putc(pc.printf("HIT \n"));
4180_1 3:454d1f4c8fd7 79 }
4180_1 3:454d1f4c8fd7 80 }
jli26 10:c19a945d9dca 81 }
jli26 10:c19a945d9dca 82
jli26 10:c19a945d9dca 83 int calcDuckXPos()
jli26 10:c19a945d9dca 84 {
jli26 10:c19a945d9dca 85 int newX = duckx + duckDX;
jli26 10:c19a945d9dca 86 if (newX > 128 - duckWidth){
jli26 10:c19a945d9dca 87 duckDX = rand()%(duckMaxSpeed-duckMinSpeed + 1) + duckMinSpeed;
jli26 10:c19a945d9dca 88 duckDX = -duckDX;
jli26 10:c19a945d9dca 89 newX = duckx + duckDX;
jli26 10:c19a945d9dca 90 }
jli26 10:c19a945d9dca 91 if (newX < 0){
jli26 10:c19a945d9dca 92 duckDX = rand()%(duckMaxSpeed-duckMinSpeed + 1) + duckMinSpeed;
jli26 10:c19a945d9dca 93 newX = duckx + duckDX;
jli26 10:c19a945d9dca 94 }
jli26 10:c19a945d9dca 95 return newX;
jli26 10:c19a945d9dca 96 }
jli26 10:c19a945d9dca 97
jli26 10:c19a945d9dca 98
jli26 10:c19a945d9dca 99 int calcDuckYPos()
jli26 10:c19a945d9dca 100 {
jli26 10:c19a945d9dca 101
jli26 10:c19a945d9dca 102 int newY = ducky + duckDY;
jli26 10:c19a945d9dca 103 if (newY > 128 - duckHeight){
jli26 10:c19a945d9dca 104 duckDY = rand()%(duckMaxSpeed-duckMinSpeed + 1) + duckMinSpeed;
jli26 10:c19a945d9dca 105 duckDY = -duckDY;
jli26 10:c19a945d9dca 106 newY = ducky + duckDY;
4180_1 7:7bd7397ab89f 107 }
jli26 10:c19a945d9dca 108 if (newY < 25){
jli26 10:c19a945d9dca 109 duckDY = rand()%(duckMaxSpeed-duckMinSpeed + 1) + duckMinSpeed;
jli26 10:c19a945d9dca 110 newY = ducky + duckDY;
4180_1 5:a1ef40ff0f78 111 }
jli26 10:c19a945d9dca 112 return newY;
jli26 10:c19a945d9dca 113 }
jli26 10:c19a945d9dca 114
jli26 10:c19a945d9dca 115
jli26 10:c19a945d9dca 116 void drawDuck()
jli26 10:c19a945d9dca 117 {
jli26 10:c19a945d9dca 118 uLCD.display_image(duckx,ducky);
jli26 10:c19a945d9dca 119
jli26 10:c19a945d9dca 120 }
jli26 10:c19a945d9dca 121
jli26 10:c19a945d9dca 122 void eraseDuck()
jli26 10:c19a945d9dca 123 {
jli26 10:c19a945d9dca 124 uLCD.filled_rectangle(duckx, ducky, duckx + duckWidth, ducky + duckHeight, BLACK);
jli26 10:c19a945d9dca 125 }
jli26 10:c19a945d9dca 126
jli26 10:c19a945d9dca 127 void drawAimer()
jli26 10:c19a945d9dca 128 {
jli26 10:c19a945d9dca 129 uLCD.circle(aimery, aimerx, (aimerWidth/2) - 5, WHITE);
jli26 10:c19a945d9dca 130 uLCD.line(aimery - aimerHeight/2, aimerx, aimery + aimerHeight/2, aimerx, WHITE);
jli26 10:c19a945d9dca 131 uLCD.line(aimery, aimerx - aimerWidth/2, aimery,aimerx + aimerHeight/2, WHITE);
jli26 10:c19a945d9dca 132 }
jli26 10:c19a945d9dca 133
jli26 10:c19a945d9dca 134 void eraseAimer()
jli26 10:c19a945d9dca 135 {
jli26 10:c19a945d9dca 136 uLCD.circle(aimery, aimerx, (aimerWidth/2) - 5, BLACK);
jli26 10:c19a945d9dca 137 uLCD.line(aimery - aimerHeight/2, aimerx, aimery + aimerHeight/2, aimerx, BLACK);
jli26 10:c19a945d9dca 138 uLCD.line(aimery, aimerx - aimerWidth/2, aimery,aimerx + aimerHeight/2, BLACK);
4180_1 6:f752accd632c 139 }
4180_1 7:7bd7397ab89f 140
4180_1 7:7bd7397ab89f 141
4180_1 8:31e63caf37e2 142
jli26 10:c19a945d9dca 143 int main()
jli26 10:c19a945d9dca 144 {
jli26 10:c19a945d9dca 145 uLCD.media_init();
jli26 10:c19a945d9dca 146 uLCD.set_sector_address(0x0001, 0x2B71);
jli26 10:c19a945d9dca 147 //LSM9DS1 IMU(p9, p10, 0x6B, 0x1E);
jli26 10:c19a945d9dca 148
jli26 10:c19a945d9dca 149 LSM9DS1 IMU(p28, p27, 0xD6, 0x3C);
jli26 10:c19a945d9dca 150 IMU.begin();
jli26 10:c19a945d9dca 151
jli26 10:c19a945d9dca 152 if (!IMU.begin()) {
jli26 10:c19a945d9dca 153 pc.printf("Failed to communicate with LSM9DS1.\n");
jli26 10:c19a945d9dca 154 }
jli26 10:c19a945d9dca 155
jli26 10:c19a945d9dca 156 IMU.calibrate(1);
jli26 10:c19a945d9dca 157 // IMU.calibrateMag(0);
jli26 10:c19a945d9dca 158
jli26 10:c19a945d9dca 159
jli26 10:c19a945d9dca 160
jli26 10:c19a945d9dca 161
jli26 10:c19a945d9dca 162 //demo graphics commands
jli26 10:c19a945d9dca 163 uLCD.background_color(BLACK);
jli26 10:c19a945d9dca 164 uLCD.cls();
jli26 10:c19a945d9dca 165 trigger.mode(PullUp);
jli26 10:c19a945d9dca 166 wait(.001);
jli26 10:c19a945d9dca 167 trigger.attach_deasserted(&trigger_hit_callback);
jli26 10:c19a945d9dca 168 trigger.setSampleFrequency();
jli26 10:c19a945d9dca 169
jli26 10:c19a945d9dca 170 float mult = 160.0;
jli26 10:c19a945d9dca 171 float rawx = 0;
jli26 10:c19a945d9dca 172 float rawy = 0;
jli26 10:c19a945d9dca 173
jli26 10:c19a945d9dca 174
jli26 10:c19a945d9dca 175
jli26 10:c19a945d9dca 176 int duckResetCounter = 25;
jli26 10:c19a945d9dca 177
jli26 10:c19a945d9dca 178 uLCD.set_font(FONT_7X8);
jli26 10:c19a945d9dca 179 uLCD.text_width(1);
jli26 10:c19a945d9dca 180 uLCD.text_height(1);
jli26 10:c19a945d9dca 181 uLCD.locate(1,1);
jli26 10:c19a945d9dca 182 uLCD.printf("Score: %d",scoreCount);
jli26 10:c19a945d9dca 183
jli26 10:c19a945d9dca 184 while(1){
jli26 10:c19a945d9dca 185
jli26 10:c19a945d9dca 186 drawAimer();
jli26 10:c19a945d9dca 187 eraseAimer();
jli26 10:c19a945d9dca 188
jli26 10:c19a945d9dca 189 if (!duckReset){
jli26 10:c19a945d9dca 190 drawDuck();
jli26 10:c19a945d9dca 191 eraseDuck();
jli26 10:c19a945d9dca 192 } else {
jli26 10:c19a945d9dca 193 duckResetCounter = duckResetCounter - 1;
jli26 10:c19a945d9dca 194 if (duckResetCounter <= 0){
jli26 10:c19a945d9dca 195 duckResetCounter = 50;
jli26 10:c19a945d9dca 196 duckReset = false;
jli26 10:c19a945d9dca 197 }
jli26 10:c19a945d9dca 198 }
jli26 10:c19a945d9dca 199
jli26 10:c19a945d9dca 200
jli26 10:c19a945d9dca 201
jli26 10:c19a945d9dca 202 // if (fire){
jli26 10:c19a945d9dca 203 // fire = false;
jli26 10:c19a945d9dca 204 // if (aimerx >= duckx && aimerx <= (duckx + duckWidth)){
jli26 10:c19a945d9dca 205 // device.putc(pc.printf("X Good"));
jli26 10:c19a945d9dca 206 // if (aimery >= ducky && aimery <= (ducky + duckHeight)){
jli26 10:c19a945d9dca 207 // led = !led;
jli26 10:c19a945d9dca 208 // device.putc(pc.printf("HIT"));
jli26 10:c19a945d9dca 209 // }
jli26 10:c19a945d9dca 210 // }
jli26 10:c19a945d9dca 211 // }
jli26 10:c19a945d9dca 212
jli26 10:c19a945d9dca 213 while(!IMU.accelAvailable());
jli26 10:c19a945d9dca 214 IMU.readAccel();
jli26 10:c19a945d9dca 215 while(!IMU.gyroAvailable());
jli26 10:c19a945d9dca 216 IMU.readGyro();
jli26 10:c19a945d9dca 217
jli26 10:c19a945d9dca 218 rawx = IMU.calcAccel(IMU.ax);
jli26 10:c19a945d9dca 219 rawy = IMU.calcAccel(IMU.ay);
jli26 10:c19a945d9dca 220 // device.putc(pc.printf("ax: %f, ay: %f \n\r",rawx,rawy));
jli26 10:c19a945d9dca 221
jli26 10:c19a945d9dca 222
jli26 10:c19a945d9dca 223 aimerx = 64 + int(rawx * mult);
jli26 10:c19a945d9dca 224
jli26 10:c19a945d9dca 225 if (aimerx < 25){
jli26 10:c19a945d9dca 226 aimerx = 25;
jli26 10:c19a945d9dca 227 }
jli26 10:c19a945d9dca 228 aimery = 64 - int(rawy * mult);
jli26 10:c19a945d9dca 229
jli26 10:c19a945d9dca 230
jli26 10:c19a945d9dca 231 duckx = calcDuckXPos();
jli26 10:c19a945d9dca 232 ducky = calcDuckYPos();
jli26 10:c19a945d9dca 233
jli26 10:c19a945d9dca 234 if (hit){
jli26 10:c19a945d9dca 235 hit = false;
jli26 10:c19a945d9dca 236 FILE *wave_file=fopen("/sd/gunsound.wav","r");
jli26 10:c19a945d9dca 237 waver.play(wave_file);
jli26 10:c19a945d9dca 238 fclose(wave_file);
jli26 10:c19a945d9dca 239
jli26 10:c19a945d9dca 240 }
jli26 10:c19a945d9dca 241
jli26 10:c19a945d9dca 242 if (scoreChange){
jli26 10:c19a945d9dca 243 scoreChange = false;
jli26 10:c19a945d9dca 244 uLCD.set_font(FONT_7X8);
jli26 10:c19a945d9dca 245 uLCD.text_width(1);
jli26 10:c19a945d9dca 246 uLCD.text_height(1);
jli26 10:c19a945d9dca 247 uLCD.locate(1,1);
jli26 10:c19a945d9dca 248 uLCD.printf("Score: %d",scoreCount);
jli26 10:c19a945d9dca 249 }
jli26 10:c19a945d9dca 250
jli26 10:c19a945d9dca 251 }
jli26 10:c19a945d9dca 252
jli26 10:c19a945d9dca 253 }
jli26 10:c19a945d9dca 254
jli26 10:c19a945d9dca 255
jli26 10:c19a945d9dca 256