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: mbed wave_player 4DGL-uLCD-SE MMA8452
Revision 0:09aa1ecd6c39, committed 2020-06-24
- Comitter:
- lwills
- Date:
- Wed Jun 24 21:09:03 2020 +0000
- Child:
- 1:5724f2947554
- Commit message:
- Missile Command shell
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#2cb1845d7681
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA8452.lib Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/ece2035ta/code/MMA8452/#53030e47347a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/city_landscape.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,104 @@
+//=================================================================
+// The file is for module "city landscape"
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+
+#include "city_landscape_private.h"
+
+CITY city_record[MAX_NUM_CITY];
+int building_height[NUM_BUILDING];
+
+// See the comments in city_landscape_public.h
+void city_landscape_init(int num_city) {
+ int i;
+ int city_distance = (SIZE_X-CITY_TO_SCREEN_MARGIN*2)/num_city;
+
+ // All interface for user should have error checking
+ ASSERT_P(num_city<=MAX_NUM_CITY,ERROR_CITY_NUMBER);
+
+ //initialize the record of cities
+ for(i=0;i<MAX_NUM_CITY;i++){
+ if(i<num_city){
+ // See the definition of CITY structure in city_landscape.h
+ city_record[i].y = REVERSE_Y(LANDSCAPE_HEIGHT)-1;
+ city_record[i].x = i*city_distance + CITY_TO_SCREEN_MARGIN;
+ city_record[i].width = CITY_WIDTH; // the width is fix number
+ city_record[i].height = MAX_BUILDING_HEIGHT; // the height is fix number
+ city_record[i].status = EXIST;
+ }
+ else{
+ city_record[i].status = DEMOLISHED;
+ }
+ }
+
+ //initialize the height of the buildings
+ for(i=0;i<NUM_BUILDING;i++){
+ building_height[i] = (rand() % MAX_BUILDING_HEIGHT*2/3)+MAX_BUILDING_HEIGHT/3;
+ }
+
+ //draw city landscape on the screen
+ draw_cities();
+ draw_landscape();
+
+}
+
+CITY city_get_info(int index){
+ // All interface for user should have error checking
+ ASSERT_P(index<MAX_NUM_CITY,ERROR_CITY_INDEX_GET_INFO);
+
+ return city_record[index];
+}
+
+void city_demolish(int index){
+ int j;
+ int city_x, city_y, building_x, building_y;
+ int height;
+
+ // error checking. the index must smaller than its max.
+ ASSERT_P(index<MAX_NUM_CITY,ERROR_CITY_INDEX_DEMOLISH);
+
+ // remove the record
+ city_record[index].status = DEMOLISHED;
+
+ // use the background color to cover the city
+ city_x = city_record[index].x;
+ city_y = city_record[index].y;
+ for(j=0;j<NUM_BUILDING;j++){
+ building_x = city_x+j*BUILDING_WIDTH;
+ building_y = city_y;
+ height = building_y-building_height[j]+1;
+ uLCD.filled_rectangle(building_x, building_y, building_x+BUILDING_WIDTH-1, height, BACKGROUND_COLOR);
+ }
+}
+
+void draw_cities(void){
+ int i,j;
+ int city_x, city_y, building_x, building_y;
+ int height;
+
+ for(i=0;i<MAX_NUM_CITY;i++){
+
+ // draw each city
+ if(city_record[i].status==EXIST){
+ city_x = city_record[i].x;
+ city_y = city_record[i].y;
+
+ // draw each building
+ for(j=0;j<NUM_BUILDING;j++){
+ building_x = city_x+j*BUILDING_WIDTH;
+ building_y = city_y;
+ height = building_y-building_height[j]+1;
+ uLCD.filled_rectangle(building_x, building_y, building_x+BUILDING_WIDTH-1, height, BUILDING_COLOR);
+ }
+ }
+ }
+}
+
+void draw_landscape(void){
+ uLCD.filled_rectangle(0, SIZE_Y-1, SIZE_X-1, REVERSE_Y(LANDSCAPE_HEIGHT), LANDSCAPE_COLOR);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/city_landscape_private.h Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,45 @@ +//================================================================= +// The header file is for module "city landscape" +// +// Copyright 2020 Georgia Tech. All rights reserved. +// The materials provided by the instructor in this course are for +// the use of the students currently enrolled in the course. +// Copyrighted course materials may not be further disseminated. +// This file must not be made publicly available anywhere. +//================================================================= +#ifndef CITY_LANDSCAPE_PRIVATE_H +#define CITY_LANDSCAPE_PRIVATE_H + +#include "mbed.h" +#include "globals.h" +#include "city_landscape_public.h" + +//==== [private type] ==== +// N/A + + +//==== [private function] ==== +// N/A + + +//==== [private macros] ==== +// The bottom of the screen => y=127 +// Gut the landscape grow up from the bottom of the screen. It is awkward. +// Thus, we use a macro to reverse the coordinate for convenience. +#define REVERSE_Y(x) (SIZE_Y-(x)) + +//==== [private settings] ==== +// You could modify these settings, but try to keep them be used only inside city_landscape.cpp +// Here are the settings to define the looking of your city landscape +#define CITY_TO_SCREEN_MARGIN 25 // pixel on the screen +#define CITY_WIDTH 10 // pixel on the screen +#define BUILDING_WIDTH 2 // pixel on the screen +#define NUM_BUILDING (CITY_WIDTH/BUILDING_WIDTH) +#define BUILDING_COLOR 0x00FF00 +#define LANDSCAPE_COLOR 0xCCAA00 + + + + + +#endif //CITY_LANDSCAPE_PRIVATE_H \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/city_landscape_public.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,58 @@
+// =================================================================
+// The header file is for module "city landscape"
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+/** @file city_landscape_public.h */
+#ifndef CITY_LANDSCAPE_PUBLIC_H
+#define CITY_LANDSCAPE_PUBLIC_H
+
+/// The enum define the status of a city
+typedef enum {
+ EXIST=1, ///< The city will be shown on screen
+ DEMOLISHED=0 ///< The city won't be shown on screen
+} CITY_STATUS;
+
+/// The structure to store the information of a city
+typedef struct {
+ int x; ///< Bottom-left corner of the city. x coordinate on the screen.
+ int y; ///< Bottom-left corner of the city. y coordinate on the screen.
+ int width; ///< The width of the city. The shape of the city is a rectangle.
+ int height; ///< The height of the city
+ CITY_STATUS status; ///< See enum CITY_STATUS
+} CITY;
+
+#define MAX_NUM_CITY 6
+
+/** Call city_landscape_init() only once at the begining of your code
+ @param num_city number of cities to be drawn. It must be less/equal to MAX_NUM_CITY.
+*/
+void city_landscape_init(int num_city);
+
+/** Get the information of city
+ @param index The index in city_record. It must be smaller than MAX_NUM_CITY.
+ @return The structure of city information
+*/
+CITY city_get_info(int index);
+
+/** Remove the city from record and screen
+ @param index The index in city_record. It must be smaller than MAX_NUM_CITY.
+*/
+void city_demolish(int index);
+
+/** Draw all exist cities onto the screen
+ @brief You might not need to use this function, but you could still use it if you want.
+*/
+void draw_cities(void);
+
+/** Draw the landscape
+ @brief You might not need to use this function, but you could still use it if you want.
+*/
+void draw_landscape(void);
+
+
+#endif //CITY_LANDSCAPE_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doubly_linked_list.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,113 @@
+//=================================================================
+// Implementation for DLL module.
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//=================================================================
+#include <stdlib.h>
+#include <stdio.h>
+#include "doubly_linked_list.h"
+#include "globals.h"
+
+LLNode* create_llnode(void* data) {
+ // complete this function (see doubly_linked_list.h for documentation)
+ LLNode* newNode;
+ return newNode;
+}
+
+DLinkedList* create_dlinkedlist(void) {
+ DLinkedList* newList = (DLinkedList*)malloc(sizeof(DLinkedList));
+ newList->head = NULL;
+ newList->tail = NULL;
+ newList->size = 0;
+ return newList;
+}
+
+void insertHead(DLinkedList* dLinkedList, void* data){
+ LLNode* newNode = create_llnode(data);
+ // complete this function
+}
+
+void deleteNode(DLinkedList* dLinkedList, LLNode* Node){
+ // complete this function
+}
+
+void destroyList(DLinkedList* dLinkedList){
+ LLNode* Node = dLinkedList->head;
+ LLNode* Next;
+ while(Node){
+ free(Node->data);
+ Next = Node->next;
+ free(Node);
+ Node = Next;
+ }
+ free(dLinkedList);
+}
+
+int getSize(DLinkedList* dLinkedList){
+ return dLinkedList->size;
+}
+
+// Check for common errors and ASSERT_P to raise the error code.
+void testDLL(void){
+ int n = 4;
+ LLItem* m[n];
+ DLinkedList* myList = create_dlinkedlist();
+ while (n--)
+ m[n] = (LLItem*) malloc(sizeof(LLItem));
+ for(n = 0; n<3; n++){
+ insertHead(myList, m[n]);
+ if ((myList->head->data != m[n]) || (getSize(myList) != n+1))
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(myList->head->data == m[n], ERROR_DLL_INSERT_HEAD);
+ ASSERT_P(getSize(myList) == n+1, ERROR_DLL_INSERT_HEAD);
+ }
+ // [2 1 0]
+ LLNode* current = myList->head;
+ for (n = 2; n>=0; n--){
+ if (current->data != m[n])
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(current->data == m[n], ERROR_DLL_INSERT_HEAD);
+ current = current->next;
+ }
+ pc.printf("OK DLL 3 x insertHead: [2 1 0]\n");
+ uLCD.printf("OK DLL 3 inserts:\n [2 1 0]\n");
+ deleteNode(myList, myList->head->next); // delete middle node
+ if (getSize(myList) != 2)
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(getSize(myList) == 2, ERROR_DLL_DELETE);
+ // [2 0]
+ current = myList->head;
+ for (n = 2; n>=0; n=n-2){
+ if (current->data != m[n])
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(current->data == m[n], ERROR_DLL_DELETE);
+ current = current->next;
+ }
+ pc.printf("OK DLL deleteNode middle: [2 0]\n");
+ uLCD.printf("OK DLL del mid:\n [2 0]\n");
+ insertHead(myList, m[3]); // 3 2 0
+ if (getSize(myList) != 3)
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(getSize(myList) == 3, ERROR_DLL_INSERT_HEAD);
+ pc.printf("OK DLL insertHead: [3 2 0]\n");
+ uLCD.printf("OK DLL 1 ins:\n [3 2 0]\n");
+ deleteNode(myList, myList->head); // delete head
+ if (getSize(myList) != 2)
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(getSize(myList) == 2, ERROR_DLL_DELETE);
+ current = myList->head;
+ // [2 0]
+ for (n = 2; n>=0; n=n-2){
+ if (current->data != m[n])
+ uLCD.printf("Complete and debug DLL to get rid of this error\n");
+ ASSERT_P(current->data == m[n], ERROR_DLL_DELETE);
+ current = current->next;
+ }
+ pc.printf("OK DLL deleteNode head: [2 0]\n");
+ uLCD.printf("OK DLL del head:\n [2 0]\n");
+ destroyList(myList);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doubly_linked_list.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,101 @@
+//=================================================================
+// Header file for DLL module.
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//=================================================================
+
+#ifndef DOUBLELINKEDLIST_H
+#define DOUBLELINKEDLIST_H
+
+// A linked list node structure.
+typedef struct llnode_t {
+ void* data;
+ struct llnode_t* prev;
+ struct llnode_t* next;
+}LLNode;
+
+/// The structure to store the information of a doubly linked list
+typedef struct dlinkedlist_t {
+ struct llnode_t* head;
+ struct llnode_t* tail;
+ int size;
+} DLinkedList;
+
+// Used for testing.
+struct LLItem {};
+void testDLL(void);
+
+/**
+ * create_llnode
+ *
+ * Creates a node by allocating memory for it on the heap,
+ * and initializing its previous and next pointers to NULL and its data pointer to the input
+ * data pointer
+ *
+ * @param data A void pointer to data the user is adding to the doublely linked list.
+ * @return A pointer to the linked list node
+ */
+LLNode* create_llnode(void* data);
+
+/**
+ * create_dlinkedlist
+ *
+ * Creates a doubly linked list by allocating memory for it on the heap. Initialize the size to zero,
+ * as well as head and tail pointers to NULL
+ *
+ * @return A pointer to an empty dlinkedlist
+ */
+DLinkedList* create_dlinkedlist(void);
+
+
+/**
+ * InsertHead
+ *
+ * Create a new LLNode with the given data and insert it at the head of the doubly linked list.
+ * Be sure to update the list's size, head (and tail if necessary).
+ *
+ * @param dLinkedList A pointer to the doubly linked list
+ * @param data A void pointer to data the user is adding to the doubly linked list.
+ *
+ */
+void insertHead(DLinkedList* dLinkedList, void* data);
+
+/**
+ * deleteNode
+ *
+ * Delete the node pointed to by Node (splice it out). Update list head/tail if necessary.
+ * Update the list's size. Free the Node's data and Node.
+ * Assume Node is not NULL.
+ *
+ * @param dLinkedList A pointer to the doubly linked list
+ * @param Node A pointer to a linked list node.
+ */
+void deleteNode(DLinkedList* dLinkedList, LLNode* Node);
+
+
+/**
+ * destroyList
+ *
+ * Destroy the doubly linked list. Everything in the linked list including list structure,
+ * nodes and data are all freed from the heap
+ *
+ * @param dLinkedList A pointer to the doubly linked list
+ *
+ */
+void destroyList(DLinkedList* dLinkedList);
+
+/**
+ * getSize
+ *
+ * Return the size of the doubly linked list
+ *
+ * @param dLinkedList A pointer to the doubly linked list
+ * @return the size
+ */
+int getSize(DLinkedList* dLinkedList);
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/globals.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,55 @@
+//=================================================================
+// The header file for general settings for the project
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//=================================================================
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+#include "mbed.h"
+#include "wave_player.h"
+#include "uLCD_4DGL.h"
+#include "MMA8452.h"
+
+// === [global object] ===
+extern uLCD_4DGL uLCD;
+extern Serial pc; // USB Console output
+extern wave_player waver;
+extern PwmOut speaker;
+
+// === [global settings] ===
+#define BACKGROUND_COLOR 0x000000 //black
+#define LANDSCAPE_HEIGHT 4 // number of pixel on the screen
+#define MAX_BUILDING_HEIGHT 10 // number of pixel on the screen
+
+
+// === [define the macro of error handle function] ===
+// when the condition (c) is not true, assert the program and show error code
+#define ASSERT_P(c,e) do { \
+ if(!(c)){ \
+ uLCD.printf("\nERROR:%d\n",e); \
+ pc.printf("\nERROR:%d\n",e); \
+ while(1); \
+ } \
+} while (0)
+
+// === [error code] ===
+#define ERROR_NONE 0 // All good in the hood
+#define ERROR_MISSILE_INDEX_GET_INFO -1 // make sure your code gives the valid index for missile_get_info()
+#define ERROR_MISSILE_INDEX_UPDATE_STATUS -2 // make sure your code gives the valid index for missile_update_status()
+#define ERROR_MISSILE_SPEED -3 // missile speed has to be between 1 and 8
+#define ERROR_MISSILE_INTERVAL -4 // missile interval has to be between 1 and 100
+// other missile error code ...
+#define ERROR_CITY_NUMBER -11 // num_city in city_landscape_init() is larger than MAX_NUM_CITY
+#define ERROR_CITY_INDEX_GET_INFO -12 // make sure your code gives the valid index for city_get_info()
+#define ERROR_CITY_INDEX_DEMOLISH -13 // make sure your code gives the valid index for city_demolish()
+// DLL
+#define ERROR_DLL_INSERT_HEAD -14 // inserting into doubly linked list at head failed
+#define ERROR_DLL_DELETE -15 // deleting node from doubly linked list failed
+// other anti-missile error code ...
+
+#endif //GLOBAL_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hardware.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,47 @@
+// This header has all the (extern) declarations of the globals.
+// "extern" means "this is instantiated somewhere, but here's what the name
+// means.
+#include "globals.h"
+
+#include "hardware.h"
+
+// We need to actually instantiate all of the globals (i.e. declare them once
+// without the extern keyword). That's what this file does!
+
+// Hardware initialization: Instantiate all the things!
+uLCD_4DGL uLCD(p9,p10,p11); // LCD Screen (tx, rx, reset)
+//SDFileSystem sd(p5, p6, p7, p8, "sd"); // SD Card(mosi, miso, sck, cs)
+Serial pc(USBTX,USBRX); // USB Console (tx, rx)
+MMA8452 acc(p28, p27, 100000); // Accelerometer (sda, sdc, rate)
+DigitalIn button1(p21); // Pushbuttons (pin)
+DigitalIn button2(p22);
+DigitalIn button3(p23);
+AnalogOut DACout(p18); // Speaker (pin)
+PwmOut speaker(p25);
+wave_player waver(&DACout);
+
+
+// Some hardware also needs to have functions called before it will set up
+// properly. Do that here.
+int hardware_init()
+{
+ //Initialize pushbuttons
+ button1.mode(PullUp);
+ button2.mode(PullUp);
+ button3.mode(PullUp);
+
+ return ERROR_NONE;
+}
+
+GameInputs read_inputs()
+{
+ GameInputs in;
+ in.b1 = !button1; // Inverted, because low voltage means "pressed"
+ in.b2 = !button2;
+ in.b3 = !button3;
+ // Read Accelerometer and record ax, ay, az in the GameInputs structure.
+ // Complete this function (hint: lookup mbed Hardware > Components > find the accelerometer you are using)
+
+ // pc.printf("Inputs: %d %d %d %f %f %f\r\n", inputs.b1, inputs.b2, inputs.b3, inputs.ax, inputs.ay, inputs.az);
+ return in;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hardware.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,26 @@
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+/**
+ * Structure that represents all the inputs to the game.
+ * If additional hardware is added, new elements should be added to this struct.
+ */
+struct GameInputs {
+ int b1, b2, b3; // Button presses
+ double ax, ay, az; // Accelerometer readings
+};
+
+/**
+ * Initialize all the hardware.
+ */
+int hardware_init();
+
+/**
+ * Read all the user inputs.
+ * This is all input hardware interaction should happen.
+ * Returns a GameInputs struct that has all the inputs recorded.
+ * This GameInputs is used elsewhere to compute the game update.
+ */
+GameInputs read_inputs();
+
+#endif // HARDWARE_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,159 @@
+//=================================================================
+// The main program file.
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+
+// External libs
+#include <stdlib.h>
+
+// Project includes
+#include "globals.h"
+#include "hardware.h"
+#include "city_landscape_public.h"
+#include "missile_public.h"
+#include "player_public.h"
+
+#define CITY_HIT_MARGIN 1
+#define CITY_UPPER_BOUND (SIZE_Y-(LANDSCAPE_HEIGHT+MAX_BUILDING_HEIGHT))
+
+int num_city_g = 4;
+// function prototypes
+void set_random_seed(Timer);
+int city_landscape_update(void);
+int was_player_hit(void);
+void missile_contact(void);
+
+int main()
+{
+ GameInputs inputs;
+ // First things first: initialize hardware
+ ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
+ pc.printf("Program Starting");
+
+ // Game state variables
+ int num_remain_city; // number of cities currently on the landscape
+ int player_alive; // 1 if alive, 0 if hit
+
+ testDLL();
+ // Timer to measure game update speed (secondarily used to generate random seed)
+ Timer t;
+ int dt; // delta time
+ set_random_seed(t); // Already implemented.
+
+ //Initialization functions (already implemented)
+ city_landscape_init(num_city_g);
+ missile_init();
+ player_init();
+ pc.printf("Initialization complete\n");
+
+ while(1)
+ {
+ t.start();
+ // Generate new missiles and draw all active missiles at current
+ // positions. (Already implemented.)
+ missile_generator();
+
+ // Draw all active anti-missiles (aka player missiles) at current
+ // positions. (Already implemented.)
+ player_missile_draw();
+
+ // Detect missile collisions with city/land and update status.
+ // You need to implement this (see specification below).
+ num_remain_city = city_landscape_update();
+
+ // Detect missile collision with player aircraft.
+ // You need to implement this (see specification below).
+ player_alive = was_player_hit(); //returns 0 if player is hit; else 1
+
+ // Detect missile collisions with player anti-missiles.
+ // You need to implement this (see specification below).
+ missile_contact();
+
+ // You must complete the implementation of this function in hardware.cpp:
+ inputs = read_inputs();
+
+ // You must write the code to dispatch to the correct action (e.g.,
+ // player_moveLeft/Right, player_fire, etc.) based on the inputs read.
+ // You must also implement player_moveLeft/moveRight/fire (see player
+ // module).
+
+
+ // You must write code to detect and implement game over.
+ if (player_alive) break; // replace this line
+
+ // Compute update time to control timing of the game loop.
+ // (Already implemented... you're welcome.)
+ t.stop();
+ dt = t.read_ms();
+ if (dt < 100) wait_ms(100 - dt);
+ }
+ pc.printf("out of main loop\n");
+
+ // You must write code to free up any dynamically allocated objects such
+ // as lists of missiles (hint: destroyList can be used for doubly linked
+ // lists).
+
+ return 0;
+}
+
+/** Detect whether any missile has hit a city and if so, call
+ city_demolish (hint: city_get_info may be useful).
+ Also, if any missile has hit a city or the landscape,
+ mark the missile's status as MISSILE_EXPLODED
+ which will cue the missile's deletion and erasure from the screen
+ on the next missile_generator call.
+ @return Number of remaining cities.
+*/
+int city_landscape_update(void){
+ // Complete this function.
+ return num_city_g;
+}
+
+/** Detect whether any missile has hit the player aircraft and if so, call
+ player_destroy (hint: player_get_info may be useful) and mark the
+ missile's status as MISSILE_EXPLODED which will cue the missile's deletion
+ and erasure from the screen on the next missile_generator call.
+ @return 1 if the player aircraft was hit and 0 otherwise.
+*/
+int was_player_hit(){
+ return 0;
+}
+
+/** Detect whether any missile has hit any player missile and if so,
+ mark the status of both the missile and the player missile as
+ MISSILE_EXPLODED which will cue the missile's deletion and erasure
+ from the screen on the next missile_generator call.
+*/
+void missile_contact(void) {
+}
+
+/* We need a random number generator (e.g., in missile_create to generate
+ random positions for the missiles to start, making the game different
+ every time). C provides a pseudo random number generator (in stdlib) but
+ it requires that we give it a different seed for each new game. A common
+ way to do this is to sample a clock and use the time as the seed. However
+ if we do this by starting a simple Timer t when the mbed starts running the
+ program and then sample it (t.read_ms), we will always get exactly the same
+ time sample -- t.read_ms will always occur at the same time in the program's
+ execution. We introduce variability in when we sample the time by waiting
+ for the user to push any button before we call t.read_ms.
+*/
+void set_random_seed(Timer t) {
+ GameInputs inputs;
+ t.start();
+ uLCD.printf("Push any button to start.\n");
+ while(1){
+ inputs = read_inputs();
+ if (inputs.b1 || inputs.b2 || inputs.b3) break;
+ }
+ uLCD.cls();
+ t.stop();
+ int seed = t.read_ms();
+ srand(seed);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/missile.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,128 @@
+//=================================================================
+// Implementation of missile module.
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+
+#include "missile_private.h"
+#include "doubly_linked_list.h"
+
+int missile_tick=0;
+
+//Create a DLL for missiles
+DLinkedList* missileDLL = NULL;
+
+void missile_init(void)
+{
+ missileDLL = create_dlinkedlist();
+}
+
+// See the comments in missile_public.h
+void missile_generator(void){
+ missile_tick++;
+ // only fire the missile at certain ticks
+ if((missile_tick % MISSILE_INTERVAL)==0 || missile_tick==0){
+ //printf("missile_create()");
+ missile_create();
+ }
+ // update the missiles and draw them
+ missile_update_position();
+}
+
+void missile_create(void){
+ MISSILE* M = (MISSILE*)malloc(sizeof(MISSILE));
+ M->y = 0;
+ //each missile has its own tick
+ M->tick = 0;
+ //set a random source for the missile
+ M->source_x = rand() % SIZE_X;
+ //set a random target for the missile
+ M->target_x = rand() % SIZE_X;
+ //the missile starts at its source
+ M->x = M->source_x;
+
+ M->status = MISSILE_ACTIVE;
+
+ insertHead(missileDLL, M);
+}
+
+/** This function update the position of all missiles and draw them
+*/
+void missile_update_position(void){
+ //controls how fast the missile will move
+ int rate = MISSILE_SPEED * 25;
+ //delta_x and delta_y account for the slope of the missile
+ double delta_x, delta_y;
+ LLNode* current = missileDLL->head;
+ MISSILE* newMissile;
+ //iterate over all missiles
+ while(current)
+ { newMissile = (MISSILE*) current->data;
+ if(newMissile->status == MISSILE_EXPLODED)
+ {
+ // clear the missile on the screen
+ missile_draw(newMissile, BACKGROUND_COLOR);
+
+ // Remove it from the list
+ //pc.printf("deleting missile node...\n");
+ deleteNode(missileDLL, current);
+ //pc.printf("missile node deleted.\n");
+ }
+ else
+ {
+ //cover the last missile location
+ missile_draw(newMissile, BACKGROUND_COLOR);
+
+ // update missile position
+ delta_y = 200/rate;
+ delta_x = (newMissile->target_x - newMissile->source_x)/rate;
+ newMissile->y = (int)(delta_y*(newMissile->tick%rate));
+ newMissile->x = (int)(newMissile->source_x + delta_x*(newMissile->tick%rate));
+ // draw missile
+ missile_draw(newMissile, MISSILE_COLOR);
+ //update missile's internal tick
+ newMissile->tick++;
+ }
+ // Advance the loop
+ current = current->next;
+ }
+}
+
+// set missile speed (default speed is 4)
+void set_missile_speed(int speed){
+ ASSERT_P(speed>=1 && speed<=8,ERROR_MISSILE_SPEED);
+ if(speed>=1 && speed<=8){
+ MISSILE_SPEED = speed;
+ }
+}
+
+// set missile interval (default interval is 10)
+void set_missile_interval(int interval){
+ ASSERT_P(interval>=1 && interval<=100,ERROR_MISSILE_INTERVAL);
+ if(interval>=1 && interval<=100){
+ MISSILE_INTERVAL = interval;
+ }
+}
+
+// See comments in missile_public.h
+DLinkedList* get_missile_list() {
+ return missileDLL;
+}
+
+/** This function draws a missile.
+ @param missile The missile to be drawn
+ @param color The color of the missile
+*/
+void missile_draw(MISSILE* missile, int color){
+ int init_x,init_y,current_x,current_y;
+
+ init_x = missile->source_x;
+ init_y = 0;
+ current_x = missile->x;
+ current_y = missile->y;
+ uLCD.line(init_x, init_y, current_x, current_y, color);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/missile_private.h Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,31 @@ +//================================================================= +// The header file defining the missile module +// +// Copyright 2020 Georgia Tech. All rights reserved. +// The materials provided by the instructor in this course are for +// the use of the students currently enrolled in the course. +// Copyrighted course materials may not be further disseminated. +// This file must not be made publicly available anywhere. +//================================================================== +#ifndef MISSILE_PRIVATE_H +#define MISSILE_PRIVATE_H + +#include "mbed.h" +#include "globals.h" +#include "missile_public.h" + +//==== [private settings] ==== +int MISSILE_INTERVAL = 10; +int MISSILE_SPEED = 6; +#define MISSILE_COLOR 0xFF0000 + +//==== [private type] ==== + +//==== [private function] ==== +void missile_create(void); +void missile_update_position(void); +void missile_draw(MISSILE* missile, int color); + +#endif //MISSILE_PRIVATE_H + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/missile_public.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,58 @@
+//=================================================================
+// The header file defining the missile module
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+/** @file missile_public.h */
+#ifndef MISSILE_PUBLIC_H
+#define MISSILE_PUBLIC_H
+
+#include "doubly_linked_list.h"
+
+typedef enum {
+ MISSILE_EXPLODED=0,
+ MISSILE_ACTIVE=1,
+} MISSILE_STATUS;
+
+/// The structure to store the information of a missile
+typedef struct {
+ int x; ///< The x-coordinate of missile current position
+ int y; ///< The y-coordinate of missile current position
+ double source_x; ///< The x-coordinate of the missile's origin
+ double target_x; ///< The x-coordinate of the missile's target
+ int tick; ///< The missile's internal tick
+ MISSILE_STATUS status; ///< The missile status, see MISSILE_STATUS
+} MISSILE;
+
+/** Call missile_init() only once at the begining of your code */
+void missile_init(void);
+
+/** Call missile_init() only once at the begining of your code */
+void missile_init(void);
+
+/** This function draw the missiles onto the screen
+ Call missile_generator() repeatedly in your game-loop. ex: main()
+*/
+void missile_generator(void);
+
+/** This function will return a linked-list of all active MISSILE structures.
+ This can be used to modify the active missiles. Marking missiles with status
+ MISSILE_EXPLODED will cue their erasure from the screen and removal from the
+ list at the next missile_generator() call.
+*/
+DLinkedList* get_missile_list();
+
+/** Set the speed of missiles, Speed has range of 1-8 with 1 being fastest and 8 being slowest
+*/
+void set_missile_speed(int speed);
+
+/** Set the interval that the missiles fire, interval has range of 1-100 with 1 being fired in
+ very quick succession and 100 being fired very slowly after one another
+*/
+void set_missile_interval(int interval);
+
+#endif //MISSILE_PUBLIC_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/player.cpp Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,90 @@
+//=================================================================
+// Implementation for the player module
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+#include "player_private.h"
+
+PLAYER player; // structure of player
+
+PLAYER player_get_info(void){ // getter for user to acquire info without accessing structure
+ return player;
+}
+
+// initialize the player's position, missile status, draw player,
+void player_init(void) {
+ player.x = PLAYER_INIT_X; player.y = PLAYER_INIT_Y; player.status = ALIVE;
+ player.playerMissiles = create_dlinkedlist();
+ player.delta = PLAYER_DELTA;
+ player.width = PLAYER_WIDTH;
+ player.height = PLAYER_HEIGHT;
+ player_draw(PLAYER_COLOR);
+}
+
+// move player PLAYER_DELTA pixels to the left, except if it would go off screen.
+void player_moveLeft(void) {
+ // Complete this function. Hint: one way to animate moving an object is to
+ // "erase" it at its current position (draw it using the background color)
+ // and redraw it at the new position.
+}
+
+// move player PLAYER_DELTA pixels to the right, except if it would go off screen.
+void player_moveRight(void) {
+ // Complete this function.
+}
+
+// generate an active missile to shoot
+void player_fire() {
+ // Complete this function. It should allocate a PLAYER_MISSILE, initialize
+ // it and insert it into the player's playerMissiles list.
+}
+
+// draw/updates the line of any active missiles, "erase" deactive missiles
+void player_missile_draw(void) {
+ PLAYER_MISSILE* playerMissile;
+ LLNode* current = player.playerMissiles->head;
+ while(current){
+ playerMissile = (PLAYER_MISSILE*)current->data;
+ if(playerMissile->status == PMISSILE_EXPLODED) {
+ //pc.printf("pmd:exploded\n");
+ uLCD.line(playerMissile->x, player.y-player.delta, playerMissile->x, playerMissile->y, BACKGROUND_COLOR);
+ //pc.printf("deleting node...\n");
+ deleteNode(player.playerMissiles, current);
+ //pc.printf("node deleted.\n");
+ }
+ else { // update missile position
+ playerMissile->y -= PLAYER_MISSILE_SPEED;
+ if (playerMissile->y < 0) {
+ //pc.printf("pmd:at top of screen\n");
+ uLCD.line(playerMissile->x, player.y-player.delta, playerMissile->x, 0, BACKGROUND_COLOR);
+ // Remove from list
+ //pc.printf("deleting node...\n");
+ deleteNode(player.playerMissiles, current);
+ //pc.printf("node deleted.\n");
+ }
+ else {
+ //pc->printf("pmd:normal\n");
+ // draw missile
+ uLCD.line(playerMissile->x, playerMissile->y+PLAYER_MISSILE_SPEED, playerMissile->x, playerMissile->y, PLAYER_MISSILE_COLOR);
+ }
+ }
+ current = current->next;
+ }
+}
+
+
+// ==== player_private.h implementation ====
+void player_draw(int color) {
+ uLCD.filled_rectangle(player.x, player.y, player.x+player.width, player.y+player.height, color);
+ uLCD.filled_rectangle(player.x+player.delta, player.y-player.delta, player.x+player.width-player.delta, player.y+player.height, color);
+}
+
+// destroy and "erase" the player off the screen. change status to DESTROYED
+void player_destroy() {
+ player_draw(BACKGROUND_COLOR);
+ player.status = DESTROYED;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/player_private.h Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,38 @@ +//================================================================= +// The header file is for module "player" +// +// Copyright 2020 Georgia Tech. All rights reserved. +// The materials provided by the instructor in this course are for +// the use of the students currently enrolled in the course. +// Copyrighted course materials may not be further disseminated. +// This file must not be made publicly available anywhere. +//================================================================== + +#ifndef PLAYER_PRIVATE_H +#define PLAYER_PRIVATE_H + +#include "mbed.h" +#include "globals.h" +#include "player_public.h" + +//==== [private settings] ==== +#define PLAYER_INIT_X 60 +#define PLAYER_INIT_Y 100 +#define PLAYER_DELTA 3 // used in design of player, pixels to move, euclidean distance +#define PLAYER_WIDTH 10 +#define PLAYER_HEIGHT 3 +#define PLAYER_COLOR 0x0000FF //blue +#define PLAYER_MISSILE_SPEED 3 +#define PLAYER_MISSILE_COLOR 0x0000FF //blue + + +//==== [private type] ==== + +void player_draw(int color); +void player_missile_draw(PLAYER_MISSILE* missile, int color); + +//==== [private function] ==== + + +#endif //PLAYER_PRIVATE_H +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/player_public.h Wed Jun 24 21:09:03 2020 +0000
@@ -0,0 +1,54 @@
+//=================================================================
+// The header file is for module "player"
+//
+// Copyright 2020 Georgia Tech. All rights reserved.
+// The materials provided by the instructor in this course are for
+// the use of the students currently enrolled in the course.
+// Copyrighted course materials may not be further disseminated.
+// This file must not be made publicly available anywhere.
+//==================================================================
+#ifndef PLAYER_PUBLIC_H
+#define PLAYER_PUBLIC_H
+
+#include "doubly_linked_list.h"
+
+typedef enum {
+ PMISSILE_EXPLODED = 0,
+ PMISSILE_ACTIVE = 1
+} PLAYER_MISSILE_STATUS; // is missile active or exploded?
+
+typedef struct {
+ int x; /// The x-coordinate of missile current position
+ int y; /// The y-coordinate of missile current position
+ PLAYER_MISSILE_STATUS status; /// The missile status, see PLAYER_MISSILE_STATUS
+} PLAYER_MISSILE;
+
+typedef enum {
+ ALIVE = 1,
+ DESTROYED = 0
+} PLAYER_STATUS; // is player aircraft alive or destroyed?
+
+typedef struct {
+ int x; int y; // x,y-coordinate of player - top left pixel
+ int delta; // delta x,y
+ int width; int height;
+ PLAYER_STATUS status;
+ DLinkedList* playerMissiles;
+} PLAYER; // structure for player
+
+
+PLAYER player_get_info(void);
+void player_init(void); // initialize the player's attributes
+void player_moveLeft(void); // move delta pixels to the left
+void player_moveRight(void); // move delta pixels to the right
+void player_fire(void); // fire missiles
+
+void player_missile_draw(void); // updates the drawing of missiles on screen
+void player_draw(int color);
+
+//void player_missile_exploded(int i);
+//void player_missile_exploded(PLAYER_MISSILE *playerMissile); //method overload
+
+void player_destroy(void); // destroy the player to end game
+
+#endif //PLAYER_PUBLIC_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wave_player.lib Wed Jun 24 21:09:03 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/sravet/code/wave_player/#acc3e18e77ad