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: NokiaLCD SDFileSystem SIgame mbed-rtos mbed wave_player
Revision 0:fcfeec8463fa, committed 2013-03-07
- Comitter:
- zlee9
- Date:
- Thu Mar 07 02:59:24 2013 +0000
- Child:
- 1:02e3c9b77580
- Commit message:
- This is the final version of Space Invaders
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NokiaLCD.lib Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/zlee9/code/NokiaLCD/#65a915f69fa2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/SDFileSystem/#c8f66dc765d4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SIgame.lib Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/zlee9/code/SIgame/#4564efa43302
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Mar 07 02:59:24 2013 +0000
@@ -0,0 +1,445 @@
+/***************************************************************/
+/***************************************************************/
+/*** ***/
+/*** Space Invaders Simulator ***/
+/*** ***/
+/*** ECE 4180 Developer Team: Space Pirates ***/
+/*** Members: David Gaspard, Zhe Cheng Lee ***/
+/*** ***/
+/***************************************************************/
+/***************************************************************/
+
+
+/***************************************************************/
+/* */
+/* Libaries */
+/* */
+/***************************************************************/
+#include "mbed.h"
+#include "NokiaLCD.h"
+#include "SIgame.h"
+#include "rtos.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
+
+/***************************************************************/
+/* */
+/* Classes and Global Variables */
+/* */
+/***************************************************************/
+NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
+DigitalIn button(p20); // Pushbutton for firing laser
+AnalogIn horiz(p15); // From joystick for steering ship
+SDFileSystem sd(p11, p12, p13, p14, "sd"); //SD card
+AnalogOut DACout(p18);//Speaker out
+wave_player waver(&DACout);//Wave player
+
+int state;
+int doneski;//done playing start music?
+
+OBJECT wave[NUM_ALIEN_ROWS][NUM_ALIEN_COLS],
+ wave_old[NUM_ALIEN_ROWS][NUM_ALIEN_COLS];
+
+/***************************************************************/
+/* */
+/* Prototypes */
+/* */
+/***************************************************************/
+void start();
+int game();
+void lose();
+void win();
+void updateScreen(OBJECT ship, OBJECT ship_old, POINT ylaser, POINT ylaser_old,
+ POINT elaser[], POINT elaser_old[], int lives_rem);
+
+void playstart(void const *args);
+void startmusic(void const *args);
+
+
+/***************************************************************/
+/* */
+/* Main program */
+/* */
+/***************************************************************/
+int main()
+{
+ doneski=0;//Variable to declare that start screen music thread
+ //was terminated
+ Thread thread(playstart);//Satrt the sound effect thread
+ Thread startmu(startmusic);//start the trigger fire thread
+ state = START;//Begin the game
+ button.mode(PullUp);//Pull up the pushbutton
+
+ while (1) { // Game loop
+ switch (state) {
+ case START:
+ start(); // Start game
+ state = GAME;
+ break;
+
+ case GAME:
+ startmu.terminate();
+ doneski=1;
+ state = game(); // Actual game
+ break;
+
+ case LOSE:
+ lose(); // Losing screen
+ state = START;
+ break;
+
+ case WIN:
+ win(); // Winning screen
+ state = START;
+ break;
+ }
+ }
+}
+
+
+/***************************************************************/
+/* */
+/* Game-State Procedures */
+/* */
+/***************************************************************/
+void start()
+{
+ /******
+ * start
+ * Starts up game
+ ******/
+ lcd.cls();
+ lcd.locate(0,4);
+ lcd.printf("SPACE INVADERS");
+ lcd.locate(0,10);
+ lcd.printf("PRESS BUTTON TO CONTINUE");
+ WAIT4FULLPUSH(button);
+}
+
+
+int game()
+{
+ /******
+ * game
+ * Handles the main gameplay. Prepares for win state if player destroys all
+ * aliens and lose state if player loses all lives
+ ******/
+ POINT ylaser, ylaser_old, elaser[ELASER_CAP], elaser_old[ELASER_CAP];
+ OBJECT ship, ship_old, *sh_alien, *frontline[NUM_ALIEN_COLS];
+ int time, lives_rem, als_rem, i;
+ float hper;
+ bool reach, left, lcancel;
+
+ // Set display screen
+ lcd.cls();
+ lcd.background(BLACK);
+
+ // Initialize
+ lives_rem = NUM_LIVES_START;
+ als_rem = NUM_ALIENS_START;
+ reach = left = lcancel = false;
+ time = 0;
+ summonWave(); // Starting locations of all alien
+ memcpy(wave_old, wave, sizeof(wave)); // Make copy for aliens' old locations
+
+ // Keep track of aliens in front of respective columns
+ for (i = 0; i < NUM_ALIEN_COLS; i++)
+ frontline[i] = &wave[NUM_ALIEN_ROWS][i];
+
+ // Set up laser structures
+ elaser[0].collide = elaser[1].collide = elaser[2].collide =
+ elaser_old[0].collide = elaser_old[1].collide = elaser_old[2].collide
+ = ylaser.collide = ylaser_old.collide = true; // No lasers on screen yet
+ // Enemy lasers are white
+ elaser[0].color = elaser[1].color = elaser[2].color = WHITE;
+ ylaser.color = GREEN; // Player's laser is green
+
+ // Set up player's ship
+ ship = startShip();
+ memcpy(&ship_old, &ship, sizeof(ship)); // Save copy for ship's old locations
+
+ // Game goes on until player loses all lives, destroy all aliens, or allow
+ // any alien to reach screen border on player's side
+ while (!reach && lives_rem > 0 && als_rem > 0) {
+ /* Laser Movement */
+ /******************/
+ // Player's laser is on screen
+ if (!(ylaser.collide)) {
+ if (ylaser.y >= 0)
+ (ylaser.y)-= 3; // Laser travels up to aliens' side
+ else
+ ylaser.collide = true; // Laser vanishes at top of screen
+ }
+
+ // Enemy lasers is on screen
+ for (i = 0; i < ELASER_CAP; i++) {
+ if (elaser[i].y < SCREENHEIGHT) // Enemy lasers travel down to player's side
+ (elaser[i].y)++;
+ else // Enemy laser vanishes at bottom of screen
+ elaser[i].collide = true;
+ }
+
+ /* Controls */
+ /******************/
+ // Player firing laser
+ if (button && ylaser.collide) {
+ // Initialize laser's locations according to ship's
+ ylaser.y = ship.y - 1;
+ ylaser.x = ship.x + (ship.width >> 1);
+ // Can fire next laser after current hits top of screen or other objects
+ ylaser.collide = false;
+ }
+
+ // Player steering ship
+ hper = horiz; // Read joystick's horizontal position.
+ if (GOLEFT(hper) && ship.x > 0)
+ (ship.x)--; // Ship moves left/
+
+ if (GORIGHT(hper) && ship.x < SCREENWIDTH - 1)
+ (ship.x)++; // Ship moves right
+
+ /* Alien Activity */
+ /******************/
+ // Move wave of aliens. Update whether any alien reaches screen on
+ // player's side
+ reach = moveAlienWave(&left);
+
+ // Enemy aliens firing lasers. Aliens fire lasers only after certain
+ // time intervals or when one of their lasers canceled out with player's
+ if (time >= RELOAD_TIME || lcancel) {
+ // Choose random front alien to fire laser. Ignore any invalid ones
+ // (those in columns that were completely wiped out have been set to
+ // NULL)
+ while ((sh_alien = frontline[rand() / (RAND_MAX/i + 1)]) == NULL);
+
+ // Find enemy laser structure not in use for display
+ if (elaser[0].collide)
+ i = 0;
+ else if (elaser[1].collide)
+ i = 1;
+ else
+ i = 2;
+
+ // Initialize laser's location according to chosen alien's
+ elaser[i].y = sh_alien->y + 1;
+ elaser[i].x = sh_alien->x + (ALIEN_WIDTH >> 1);
+ elaser[i].collide = lcancel = false;
+ time = 0; // Reset time for next enemy laser fire
+ }
+
+ /* Collisions */
+ /*******************/
+ // Cancel out player's laser and enemy laser should they connect
+ lcancel = twoLasersCollide(&ylaser, elaser);
+
+ // Kill alien if player's laser hits one
+ destroyAlien(&als_rem, &ylaser, frontline);
+
+ // Check for any enemy laser touching ship
+ for (i = 0; i < ELASER_CAP; i++) {
+ if (!(elaser[i].collide) && elaser[i].y >= ship.y && elaser[i].y <=
+ ship.y + ship.height && elaser[i].x >= ship.x && elaser[i].x
+ <= ship.x + ship.width) {
+ // Plyaer loses life if hit by laser
+ lives_rem--;
+ ship.killed = elaser[i].collide = true;
+ }
+ }
+
+ updateScreen(ship, ship_old, ylaser, ylaser_old, elaser, elaser_old,
+ lives_rem); // Update gameplay screen
+ ship.killed = false;
+ time++; // Time passes
+
+ // Update old locations to current
+ memcpy(wave_old, wave, sizeof(wave));
+ memcpy(elaser_old, elaser, sizeof(elaser));
+ ylaser_old = ylaser;
+ ship_old = ship;
+ } // End of main gameplay loop
+
+
+ // Game's outcomes
+ if (als_rem) // Lost all lives or aliens reached your border
+ return LOSE;
+ else // Destroyed all aliens
+ return WIN;
+}
+
+
+void win()
+{
+ /******
+ * win
+ * Displays congratulation screen and prompt player to replay
+ ******/
+ // Congratulation screen
+ lcd.cls();
+ lcd.locate(0,3);
+ lcd.printf("WELL DONE\n\rEARTHLING");
+ lcd.locate(0,6);
+ lcd.printf("THIS TIME YOU WIN");
+ wait(2);
+
+ // Prompt player to play game again
+ lcd.cls();
+ lcd.locate(0,10);
+ lcd.printf("PRESS BUTTON TO PLAY AGAIN");
+ WAIT4FULLPUSH(button);
+}
+
+
+void lose()
+{
+ /******
+ * lose
+ * Displays game-over screen and prompts player to replay
+ ******/
+ // Game-over screen
+ lcd.cls();
+ lcd.locate(4,3);
+ lcd.printf("YOU SUCK");
+ wait(2);
+
+ // Prompt player to play game again
+ lcd.locate(0,10);
+ lcd.printf("PRESS BUTTON TO PLAY AGAIN");
+ WAIT4FULLPUSH(button);
+}
+
+
+/***************************************************************/
+/* */
+/* Game-Drawing Funntion */
+/* */
+/***************************************************************/
+void updateScreen(OBJECT ship, OBJECT ship_old, POINT ylaser, POINT ylaser_old,
+ POINT elaser[], POINT elaser_old[], int lives_rem)
+{
+ /******
+ * updateScreen
+ * Updates game display on Nokia LCD screen
+ ******/
+ int r, c;
+
+ // Old locations are drawn with black to erase previous images in display
+ // when redrawing images
+ wait(0.02);
+
+ // Redraw surviving aliens from their positions
+ for (c = 0; c < NUM_ALIEN_COLS; c++) {
+ for (r = 0; r < NUM_ALIEN_ROWS; r++) {
+ lcd.fill(wave_old[r][c].x, wave_old[r][c].y, wave_old[r][c].width,
+ wave_old[r][c].height, BLACK);
+ // Aliens as white rectangles
+ if (!(wave[r][c].killed)) // Don't draw destroyed aliens
+ lcd.fill(wave[r][c].x, wave[r][c].y, wave[r][c].width,
+ wave[r][c].height, wave[r][c].color);
+ }
+ }
+
+ // Redraw enemy lasers as single white pixels
+ for (c = 0; c < ELASER_CAP; c++) {
+ lcd.pixel(elaser_old[c].x, elaser_old[c].y, BLACK);
+ lcd.pixel(elaser_old[c].x+1, elaser_old[c].y, BLACK);
+ lcd.pixel(elaser_old[c].x, elaser_old[c].y+1, BLACK);
+ lcd.pixel(elaser_old[c].x+1, elaser_old[c].y+1, BLACK);
+ // Don't draw lasers that hit bottom screen border or other objects
+ if (!(elaser[c].collide)) {
+ lcd.pixel(elaser[c].x, elaser[c].y, elaser[c].color);
+ lcd.pixel(elaser[c].x+1, elaser[c].y, elaser[c].color);
+ lcd.pixel(elaser[c].x, elaser[c].y+1, elaser[c].color);
+ lcd.pixel(elaser[c].x+1, elaser[c].y+1, elaser[c].color);
+ }
+ }
+
+ // Redraw player's laser as single green pixel. Check that laser doesn't
+ // hit top screen border or other objects
+ lcd.pixel(ylaser_old.x, ylaser_old.y, BLACK);
+ lcd.pixel(ylaser_old.x+1, ylaser_old.y, BLACK);
+ lcd.pixel(ylaser_old.x, ylaser_old.y+1, BLACK);
+ lcd.pixel(ylaser_old.x+1, ylaser_old.y+1, BLACK);
+ if (!(ylaser.collide))
+ lcd.pixel(ylaser.x, ylaser.y, ylaser.color);
+ lcd.pixel(ylaser.x+1, ylaser.y, ylaser.color);
+ lcd.pixel(ylaser.x, ylaser.y+1, ylaser.color);
+ lcd.pixel(ylaser.x+1, ylaser.y+1, ylaser.color);
+
+ if (ship.killed) { // Ship is destroyed from being hit by laser
+ lcd.locate(0,15);
+ lcd.printf("LIVES: %d", lives_rem);
+ wait(2); // Game pauses for few seconds before player uses next life
+ lcd.cls(); // Clear lives message
+ }
+
+ // Redraw player's ship as green rectangle
+ lcd.fill(ship_old.x, ship_old.y, ship_old.width, ship_old.height, BLACK);
+ lcd.fill(ship.x, ship.y, ship.width, ship.height, ship.color);
+}
+
+
+/***************************************************************/
+/* */
+/* This function plays the lose/win screen music and generates */
+/* the firing sound effect */
+/* */
+/***************************************************************/
+void playstart(void const *args)//Th
+{ //Depending on the state of the game,
+ //queue either screen music or play sound effect upon fire
+ while(true) {
+ FILE *wave_file;
+ //At the start screen, do nothing
+ while(state==START) {
+ Thread::wait(50);
+ }
+
+ //wait 500ms after start screen music has been cutoff before
+ //continuing to avoid conflicts
+ while(!doneski) {
+ Thread::wait(500);
+ }
+
+ //While in the game, play firing sound when the player fires
+ while(state==GAME) {
+ if(button) {
+
+ wave_file=fopen("/sd/mample4.wav","r");
+
+
+ waver.play(wave_file);
+ fclose(wave_file);
+ }
+ }
+
+ //Play losing screen music
+ while(state==LOSE) {
+ wave_file=fopen("/sd/mample3.wav","r");
+ waver.play(wave_file);
+ fclose(wave_file);
+ }
+
+ //Play winning screen music
+ while(state==WIN) {
+ wave_file=fopen("/sd/mample3.wav","r");
+ waver.play(wave_file);
+ fclose(wave_file);
+ }
+ }
+}
+
+
+/***************************************************************/
+/* */
+/* startmusic() plays the start screen music */
+/* */
+/***************************************************************/
+void startmusic(void const *args)
+{
+
+ FILE *wave_file;
+ wave_file=fopen("/sd/mample2.wav","r");
+ waver.play(wave_file);
+ fclose(wave_file);
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#53e6cccd8782
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wave_player.lib Thu Mar 07 02:59:24 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/sravet/code/wave_player/#acc3e18e77ad