Sat Sep 13, 2014 1:25 pm
//imports the SPI library (needed to communicate with Gamebuino's screen)
#include <SPI.h>
//imports the Gamebuino library
#include <Gamebuino.h>
#include <stdlib.h>
//imports the header to make this blasted game work.
#include "MISCMD.h"
//creates a Gamebuino object named gb
Gamebuino gb;
// drawing functions
void drawTarget(int x,int y){
gb.display.drawFastHLine(x-5, y,4);
gb.display.drawFastHLine(x+1, y,4);
gb.display.drawFastVLine(x,y-5,4);
gb.display.drawFastVLine(x,y+1,4);
};
// missile controllers
boolean cpuFireRandomMissile(){
int missileID; // the index of the chosen missile in the array, used to make sure there's one avaible
while (missileID <= MISSILEARRAYSIZE - 1){
if (missileArray[missileID].active == true){
// missileid is already taken
missileID += 1;
}else{
// missileID isn't taken, set new values, set missile active, select random target
missileArray[missileID].active = true;
missileArray[missileID].start_x = random(LCDWIDTH); // random starting point, sans the very edges
missileArray[missileID].start_y = 0.0;
missileArray[missileID].target_y = LCDHEIGHT - 8;
missileArray[missileID].target_x = random(LCDWIDTH); // random target point, sans the very edges
missileArray[missileID].rel_frame = 0;
missileArray[missileID].num_frames = 10; /*(float) abs(sqrt(sq(missileArray[missileID].target_x - missileArray[missileID].start_x) + sq(missileArray[missileID].target_y - missileArray[missileID].start_y))) / 5; */ // number of frames of travel, based on speed
missileArray[missileID].player = false; // this is a CPU missile, after all
missileArray[missileID].velocity_x = (float)(missileArray[missileID].target_x - missileArray[missileID].start_x) / missileArray[missileID].num_frames;
missileArray[missileID].velocity_y = (float)(missileArray[missileID].target_y - missileArray[missileID].start_y) / missileArray[missileID].num_frames;
// plug into the init function, most of these values are simply reset, but this calculates the velocity of x and y
// init_missile(missileArray[missileID], missileArray[missileID].start_x, missileArray[missileID].start_y, missileArray[missileID].target_x, missileArray[missileID].target_y, missileArray[missileID].num_frames);
return true;
break;
};
};
return false;
};
void missileStep(){
// calculates the motion of all currently active missiles, calculate collisions or detonations (for player-fired missiles)
int missileID = 0;
while (missileID <= (MISSILEARRAYSIZE - 1)){
// scan and update all missile ID positions, if active.
missileArray[missileID].current_x += missileArray[missileID].velocity_x;
missileArray[missileID].current_y += missileArray[missileID].velocity_y;
missileID += 1;
};
};
// Drawing functinos.
void drawCity(int citycount){
// Draws the cities. takes the number of cities currently being used
// pick sprite based on percentage of city health
int cityx;
for (int curCity = 0; curCity <= citycount - 1; curCity++){
// sprite location is based on number of cities
cityx = (int) (LCDWIDTH/(citycount + 1)) * (curCity + 1); // determine spacing for the cities to draw
switch (cityArray[curCity].hp){
case 2:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityFull); // Two hits left, full health
break;
case 1:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityHalf); // One hit left, half health
break;
case 0:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityDestroyed); // And these residents will need to move.
break;
default:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityFull); // Two hits left, full health
break;
};
};
gb.display.drawFastHLine(0,LCDHEIGHT - 8, LCDWIDTH);
};
void drawMissiles(){
// draws all active missiles
int curMissile;
while (curMissile <= (MISSILEARRAYSIZE - 1)){
if (missileArray[curMissile].active == true){
// missile is active, draw the missile!
gb.display.drawLine(missileArray[curMissile].start_x, missileArray[curMissile].start_y, missileArray[curMissile].current_x, missileArray[curMissile].current_y);
//gb.display.drawPixel((int) missileArray[curMissile].current_x, (int) missileArray[curMissile].current_y);
};
curMissile += 1;
};
};
// the setup routine runs once when Gamebuino starts up
void setup(){
// initialize the Gamebuino object
gb.begin();
//display the main menu:
gb.titleScreen(F("Missle Command"));
gb.setFrameRate(1);
gb.pickRandomSeed();
// initialize memory space
}
// the loop routine runs over and over again forever
void loop(){
//updates the gamebuino (the display, the sound, the auto backlight... everything)
//returns true when it's time to render a new frame (20 times/second)
if(gb.update()){
while (cpuFireRandomMissile() == false){};
//if (gb.frameCount % 5 == 1){
missileStep();
// };
drawMissiles();
drawCity(3);
gb.display.cursorX = 0;
gb.display.cursorY = LCDHEIGHT - 7;
gb.display.setFont(font3x5);
gb.display.print(missileArray[1].start_x);
gb.display.print(" ");
gb.display.print(missileArray[1].start_y);
gb.display.print(" ");
gb.display.print(missileArray[1].target_x);
gb.display.print(" ");
gb.display.print(missileArray[1].target_y);
gb.display.print(" ");
gb.display.print(missileArray[1].current_x);
gb.display.print(" ");
gb.display.print(missileArray[1].current_y);
gb.display.print(" ");
gb.display.print(missileArray[1].active);
};
};
// header file for the game, which saves all of the sprites, data structures, and other things needed for the game to work.
//City Sprites
static unsigned char PROGMEM sprCityFull[] =
{
8,8,
B00000000,
B00000000,
B00001000,
B00011000,
B01011100,
B01111110,
B11111111,
B11111111,
};
static unsigned char PROGMEM sprCityHalf[] =
{
8,8,
B00000000,
B00010100,
B00101010,
B00010100,
B00101100,
B01111110,
B11111111,
B11111111,
};
static unsigned char PROGMEM sprCityDestroyed[] =
{
8,8,
B00000000,
B00010100,
B00101010,
B00010100,
B00101001,
B01010110,
B01101010,
B11111111,
};
// struct for cities;
typedef struct {
// hit points of the city.
int hp;
// how many missiles the city has left
int mis;
} city;
// structure for missiles
typedef struct {
int start_x, start_y; // The starting positions of the missile
int target_x, target_y; // The Target of the missile
float current_x, current_y; // current position of the missile
float velocity_x, velocity_y; // horizonatal and vertical speed of the missile, used for calculating current x and y
int num_frames; // The number of frames to move the missile in, calculated from linear distance and speed.
int rel_frame; //relitive frame since missile fired
boolean player; // is this a player missile?
boolean active; // is this missile active?
} missile;
// structure for a 'level'
typedef struct{
int citycount; // how many cities
int mismax; // how many missiles in each city 0 is unlimited
int emiscount; // how many missiles will the CPU try and fire?
int emisvolleycount; // how many missiles AT ONCE will the CPU try and fire.
int volleytime; // average time in frames between missile volleys
} mission;
// constants
const int MISSILEARRAYSIZE = 3;
const int CITYARRAYSIZE = 5;
// array for the cities
static city cityArray[CITYARRAYSIZE];
// array of all the missiles
static missile missileArray[MISSILEARRAYSIZE];
// motion functions
void init_missile(missile & mis, int start_x, int start_y, int target_x, int target_y, int num_frames)
{
mis.start_x = mis.current_x = start_x;
mis.start_y = mis.current_y = start_y;
mis.target_x = target_x;
mis.target_y = target_y;
mis.velocity_x = (float)(target_x - start_x) / num_frames;
mis.velocity_y = (float)(target_y - start_y) / num_frames;
mis.num_frames = num_frames;
};
void update_missile(missile & mis)
{
mis.current_x += mis.velocity_x;
mis.current_y += mis.velocity_y;
};
void resetMissile(int id){
missileArray[id].active = false;
missileArray[id].start_x = 0;
missileArray[id].start_y = 0;
missileArray[id].target_y = 0;
missileArray[id].target_x = 0;
missileArray[id].rel_frame = 0;
missileArray[id].num_frames = 0; // number of frames of travel, based on speed
missileArray[id].player = true; // this is a CPU missile, after all
missileArray[id].velocity_x = 0.0;
missileArray[id].velocity_y = 0.0;
};
// Drawing functions
extern const byte font3x5[];
Sat Sep 13, 2014 2:46 pm
Sat Sep 13, 2014 11:15 pm
void drawMissiles(){
// draws all active missiles
int curMissile; <--------- needs to be "int curMissile = 0;"
while (curMissile <= (MISSILEARRAYSIZE - 1)){
boolean cpuFireRandomMissile(){
int missileID; // the index of the chosen missile in the array, used to make sure there's one avaible
while (missileID <= MISSILEARRAYSIZE - 1){
missileArray[missileID].current_x += missileArray[missileID].velocity_x;
missileArray[missileID].current_y += missileArray[missileID].velocity_y;
missileArray[missileID].current_x = missileArray[missileID].start_x;
missileArray[missileID].current_y = missileArray[missileID].start_y;
while (cpuFireRandomMissile() == false){};
Sun Sep 14, 2014 9:04 am
Sun Sep 14, 2014 3:35 pm
//imports the SPI library (needed to communicate with Gamebuino's screen)
#include <SPI.h>
//imports the Gamebuino library
#include <Gamebuino.h>
#include <stdlib.h>
//imports the header to make this blasted game work.
#include "MISCMD.h"
//creates a Gamebuino object named gb
Gamebuino gb;
// drawing functions
void drawTarget(int x,int y){
gb.display.drawFastHLine(x-5, y,4);
gb.display.drawFastHLine(x+1, y,4);
gb.display.drawFastVLine(x,y-5,4);
gb.display.drawFastVLine(x,y+1,4);
};
// missile controllers
boolean cpuFireRandomMissile(){
int missileID = 0; // the index of the chosen missile in the array, used to make sure there's one avaible
while (missileID <= MISSILEARRAYSIZE - 1){
if (missileArray[missileID].active == true){
// missileid is already taken
missileID += 1;
}else{
// missileID isn't taken, set new values, set missile active, select random target
missileArray[missileID].active = true;
missileArray[missileID].start_x = random(LCDWIDTH); // random starting point, sans the very edges
missileArray[missileID].start_y = 0.0;
missileArray[missileID].current_x = missileArray[missileID].start_x;
missileArray[missileID].current_y = missileArray[missileID].start_y;
missileArray[missileID].target_y = LCDHEIGHT - 8;
missileArray[missileID].target_x = random(LCDWIDTH); // random target point, sans the very edges
missileArray[missileID].rel_frame = 0;
missileArray[missileID].num_frames = (float) 5 * abs(sqrt(sq(missileArray[missileID].target_x - missileArray[missileID].start_x) + sq(missileArray[missileID].target_y - missileArray[missileID].start_y))); // number of frames of travel, based on speed
missileArray[missileID].player = false; // this is a CPU missile, after all
missileArray[missileID].velocity_x = (float)(missileArray[missileID].target_x - missileArray[missileID].start_x) / missileArray[missileID].num_frames;
missileArray[missileID].velocity_y = (float)(missileArray[missileID].target_y - missileArray[missileID].start_y) / missileArray[missileID].num_frames;
// plug into the init function, most of these values are simply reset, but this calculates the velocity of x and y
// init_missile(missileArray[missileID], missileArray[missileID].start_x, missileArray[missileID].start_y, missileArray[missileID].target_x, missileArray[missileID].target_y, missileArray[missileID].num_frames);
return true;
break;
};
};
return false;
};
boolean playerFireMissile(int tX,int tY){
// Fire a missile at the given target will eventually take closest city into accunt
int sX = LCDWIDTH / 2;
int sY = LCDHEIGHT - 8;
int missileID = 0; // the index of the chosen missile in the array, used to make sure there's one avaible
while (missileID <= MISSILEARRAYSIZE - 1){
if (missileArray[missileID].active == true){
// missileid is already taken
missileID += 1;
}else{
// missileID isn't taken, set new values, set missile active, select random target
missileArray[missileID].active = true;
missileArray[missileID].start_x = sX;
missileArray[missileID].start_y = sY;
missileArray[missileID].current_x = missileArray[missileID].start_x;
missileArray[missileID].current_y = missileArray[missileID].start_y;
missileArray[missileID].target_y = tY;
missileArray[missileID].target_x = tX;
missileArray[missileID].rel_frame = 0;
missileArray[missileID].num_frames = (float) 1.5 * abs(sqrt(sq(missileArray[missileID].target_x - missileArray[missileID].start_x) + sq(missileArray[missileID].target_y - missileArray[missileID].start_y))); // number of frames of travel, based on speed
missileArray[missileID].player = true; // this is a player missile, after all
missileArray[missileID].velocity_x = (float)(missileArray[missileID].target_x - missileArray[missileID].start_x) / missileArray[missileID].num_frames;
missileArray[missileID].velocity_y = (float)(missileArray[missileID].target_y - missileArray[missileID].start_y) / missileArray[missileID].num_frames;
// plug into the init function, most of these values are simply reset, but this calculates the velocity of x and y
// init_missile(missileArray[missileID], missileArray[missileID].start_x, missileArray[missileID].start_y, missileArray[missileID].target_x, missileArray[missileID].target_y, missileArray[missileID].num_frames);
return true;
break;
};
};
};
void createExploionAtPos(int x, int y, int ID){
// finds a subtible ID to save an explosion in, and sets it there.
int curExpl = 0;
while (curExpl <= EXPLOSIONARRAYSIZE - 1){
// seach all explosion IDs
if (missileArray[ID].active != true || missileArray[ID].player != true){
// bail if something odd happend, hence the checking of the missile that set this one off.
break;
curExpl = 100;
};
if (explosionArray[curExpl].active == false){
// this ID is open, so use this.
explosionArray[curExpl].active = true;
explosionArray[curExpl].x = x;
explosionArray[curExpl].y = y;
explosionArray[curExpl].radius = 1;
explosionArray[curExpl].framecount = 0;
explosionArray[curExpl].downcount = 0;
curExpl +=1;
};
};
};
void missileStep(){
// calculates the motion of all currently active missiles, calculate collisions or detonations (for player-fired missiles)
int missileID = 0;
while (missileID <= (MISSILEARRAYSIZE - 1)){
// scan and update all missile ID positions, if active.
if (missileArray[missileID].active == true){
// move active missiles only
missileArray[missileID].current_x += missileArray[missileID].velocity_x;
missileArray[missileID].current_y += missileArray[missileID].velocity_y;
};
if (missileArray[missileID].current_x >= LCDWIDTH || missileArray[missileID].current_x < 0){
// off the left/right of the screen
resetMissile(missileID);
};
if (missileArray[missileID].player == false){
//CPU missiles
if (missileArray[missileID].target_y <= missileArray[missileID].current_y){
// missile hit the ground, city collsion goes here
resetMissile(missileID);
};
}else{
// player missiles
if (missileArray[missileID].current_y < 0){
// above screen
resetMissile(missileID);
}else{
// it didn't fly off into space, let's see if it reached close to it's target
int xdif = missileArray[missileID].current_x - missileArray[missileID].target_x;
int ydif = missileArray[missileID].current_y - missileArray[missileID].target_y;
xdif = abs(xdif);
ydif = abs(ydif);
if (xdif <= 2 && ydif <=2){
// missile has reached target, boom time!
if (missileArray[missileID].player == true){
createExploionAtPos(missileArray[missileID].current_x, missileArray[missileID].current_y, missileID);
resetMissile(missileID);
};
};
};
};
missileID += 1;
};
};
void explosionStep(){
// update all of the explosions, clearing IDS of expired blasts, and removing any AI missiles they destroy
int curExpl = 0;
int curMis = 0;
while (curExpl <= EXPLOSIONARRAYSIZE - 1){
if (explosionArray[curExpl].active == true){
// only check active explosions.
curMis = 0;
while (curMis <= MISSILEARRAYSIZE - 1){
if (missileArray[curMis].player == false && missileArray[curMis].active == true){
// missille is AI/CPU and active. If it's within range, destroy it, and count up one on the explosion's 'missiles shot down counter'
int xrad = missileArray[curMis].current_x - explosionArray[curExpl].x;
xrad = abs(xrad);
int yrad = missileArray[curMis].current_x - explosionArray[curExpl].x;
yrad = abs(xrad);
if (xrad <= explosionArray[curExpl].radius && yrad <= explosionArray[curExpl].radius){
// in blast range, destroy the missile.
resetMissile(curMis);
explosionArray[curExpl].downcount += 1;
};
};
curMis +=1; // scan the next missile
};
if (explosionArray[curExpl].framecount % 45 == 1){
explosionArray[curExpl].radius +=1; // expand the radius by one every 15 frames
};
if (explosionArray[curExpl].radius >= 3){
// explosion has reached max radius, destroy the explosion tally the score gained in here.
playerScore += (10 * explosionArray[curExpl].downcount) + ( 5 * (explosionArray[curExpl].downcount - 1));
explosionArray[curExpl].active = false;
explosionArray[curExpl].x = 0;
explosionArray[curExpl].y = 0;
explosionArray[curExpl].downcount = 0;
explosionArray[curExpl].radius = 0;
explosionArray[curExpl].framecount = 0;
};
explosionArray[curExpl].framecount +=1; //toggle this explosion's framecount
};
curExpl += 1;
};
};
// Drawing functinos.
void drawCity(int citycount){
// Draws the cities. takes the number of cities currently being used
// pick sprite based on percentage of city health
int cityx = 0;
for (int curCity = 0; curCity <= citycount - 1; curCity++){
// sprite location is based on number of cities
cityx = (int) (LCDWIDTH/(citycount + 1)) * (curCity + 1); // determine spacing for the cities to draw
switch (cityArray[curCity].hp){
case 2:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityFull); // Two hits left, full health
break;
case 1:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityHalf); // One hit left, half health
break;
case 0:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityDestroyed); // And these residents will need to move.
break;
default:
gb.display.drawBitmap(cityx - 4, LCDHEIGHT - 16, sprCityFull); // Two hits left, full health
break;
};
};
gb.display.drawFastHLine(0,LCDHEIGHT - 8, LCDWIDTH);
};
void drawMissiles(){
// draws all active missiles
int curMissile = 0;
while (curMissile <= (MISSILEARRAYSIZE - 1)){
if (missileArray[curMissile].active == true){
// missile is active, draw the missile!
gb.display.drawLine(missileArray[curMissile].start_x, missileArray[curMissile].start_y, missileArray[curMissile].current_x, missileArray[curMissile].current_y);
//gb.display.drawPixel((int) missileArray[curMissile].current_x, (int) missileArray[curMissile].current_y);
//drawTarget(missileArray[curMissile].target_x,missileArray[curMissile].target_y);
};
curMissile += 1;
};
};
void drawExplosions(){
// draws all active missiles
int curExpl = 0;
while (curExpl <= (EXPLOSIONARRAYSIZE - 1)){
if (explosionArray[curExpl].active == true){
gb.display.fillCircle(explosionArray[curExpl].x, explosionArray[curExpl].y, explosionArray[curExpl].radius);
};
curExpl += 1;
};
};
void playerControlTarget(){
// checks for key input, and moves the crosshair target appropriately.
if (gb.buttons.repeat(BTN_LEFT,1)){
//move target left to the edge of the screen
playerTargetX -= 1;
};
if (gb.buttons.repeat(BTN_RIGHT,1)){
//move target left to the edge of the screen
playerTargetX += 1;
};
if (gb.buttons.repeat(BTN_UP,1)){
//move target left to the edge of the screen
playerTargetY -= 1;
};
if (gb.buttons.repeat(BTN_DOWN,1)){
//move target left to the edge of the screen
playerTargetY += 1;
};
// constrain the values, why didn't I know about this for the tank game!?
playerTargetY = constrain(playerTargetY,0,LCDHEIGHT - 8);
playerTargetX = constrain(playerTargetX,0,LCDWIDTH);
};
void missileInitState(){
// calculates the motion of all currently active missiles, calculate collisions or detonations (for player-fired missiles)
int missileID = 0;
while (missileID <= (MISSILEARRAYSIZE - 1)){
resetMissile(missileID);
missileID += 1;
};
};
void explosionInitState(){
// calculates the motion of all currently active missiles, calculate collisions or detonations (for player-fired missiles)
int explosionID = 0;
while (explosionID <= (EXPLOSIONARRAYSIZE - 1)){
explosionArray[explosionID].x = 0;
explosionArray[explosionID].y = 0;
explosionArray[explosionID].active = false;
explosionArray[explosionID].downcount = 0;
explosionArray[explosionID].framecount = 0;
explosionArray[explosionID].radius = 0;
explosionID += 1;
};
};
// the setup routine runs once when Gamebuino starts up
void setup(){
// initialize the Gamebuino object
gb.begin();
//display the main menu:
gb.titleScreen(F("Missle Command"));
gb.setFrameRate(20);
gb.pickRandomSeed();
explosionInitState();
missileInitState();
framestowait = random(40,120);
};
// the loop routine runs over and over again forever
void loop(){
//updates the gamebuino (the display, the sound, the auto backlight... everything)
//returns true when it's time to render a new frame (20 times/second)
if(gb.update()){
// test game loop
playerControlTarget();
if (gb.buttons.pressed(BTN_A)){
// test firing of player missiles
playerFireMissile(playerTargetX,playerTargetY);
};
// testing some basic AI logic, so it's not like someone's loaned every Kaytusha launcher on the planet to pester the player with.
if (framestowait == 0){
// done waiting, now send some missiles the player's way
thisVolley = random(1,5);
int i=0;
while (i <= thisVolley){
// fire off random missiles
cpuFireRandomMissile();
i +=1;
};
framestowait = random(40,120);
};
framestowait -=1; // countdown to next wave
missileStep();
explosionStep();
drawMissiles();
drawExplosions();
drawCity(3);
drawTarget(playerTargetX,playerTargetY);
gb.display.cursorX = 0;
gb.display.cursorY = LCDHEIGHT - 7;
gb.display.setFont(font3x5);
//gb.display.print(framestowait);
gb.display.print("Score: ");
gb.display.print(playerScore);
/*gb.display.print(" ");
gb.display.print(missileArray[0].target_x);
gb.display.print(" ");
gb.display.print(missileArray[0].target_y);
gb.display.print(" ");
gb.display.print(missileArray[0].current_x);
gb.display.print(" ");
gb.display.print(missileArray[0].current_y);
gb.display.print(" ");
gb.display.print(missileArray[0].active); */
};
};
// header file for the game, which saves all of the sprites, data structures, and other things needed for the game to work.
//City Sprites
static unsigned char PROGMEM sprCityFull[] =
{
8,8,
B00000000,
B00000000,
B00001000,
B00011000,
B01011100,
B01111110,
B11111111,
B11111111,
};
static unsigned char PROGMEM sprCityHalf[] =
{
8,8,
B00000000,
B00010100,
B00101010,
B00010100,
B00101100,
B01111110,
B11111111,
B11111111,
};
static unsigned char PROGMEM sprCityDestroyed[] =
{
8,8,
B00000000,
B00010100,
B00101010,
B00010100,
B00101001,
B01010110,
B01101010,
B11111111,
};
// struct for cities;
typedef struct {
// hit points of the city.
int hp;
// how many missiles the city has left
int mis;
} city;
// structure for missiles
typedef struct {
int start_x, start_y; // The starting positions of the missile
int target_x, target_y; // The Target of the missile
float current_x, current_y; // current position of the missile
float velocity_x, velocity_y; // horizonatal and vertical speed of the missile, used for calculating current x and y
int num_frames; // The number of frames to move the missile in, calculated from linear distance and speed.
int rel_frame; //relitive frame since missile fired
boolean player; // is this a player missile?
boolean active; // is this missile active?
} missile;
// structure for explosions
typedef struct {
int active; // actively exploding or not
int x, y; // center of blast
int radius; // blast radius
int framecount; // number of frames the explosion has been alive
int downcount; // number of missiles downed, for soring
} explosion;
// structure for a 'level'
typedef struct{
int citycount; // how many cities
int mismax; // how many missiles in each city 0 is unlimited
int emiscount; // how many missiles will the CPU try and fire?
int emisvolleycount; // how many missiles AT ONCE will the CPU try and fire.
int volleytime; // average time in frames between missile volleys
} mission;
// constants
const int MISSILEARRAYSIZE = 16;
const int CITYARRAYSIZE = 5;
const int EXPLOSIONARRAYSIZE = 16; // unlike a Micheal Bay Movie, the Gamebuino can only support so many of these.
// array for the cities
static city cityArray[CITYARRAYSIZE];
// array of all the missiles
static missile missileArray[MISSILEARRAYSIZE];
// array of explosions
static explosion explosionArray[EXPLOSIONARRAYSIZE];
//Static Score
static int playerScore = 0;
static int playerTargetX = LCDWIDTH/2;
static int playerTargetY = LCDHEIGHT/2;
static int thisVolley = 0;
static int framestowait = 0;
// motion functions
void init_missile(missile & mis, int start_x, int start_y, int target_x, int target_y, int num_frames)
{
mis.start_x = mis.current_x = start_x;
mis.start_y = mis.current_y = start_y;
mis.target_x = target_x;
mis.target_y = target_y;
mis.velocity_x = (float)(target_x - start_x) / num_frames;
mis.velocity_y = (float)(target_y - start_y) / num_frames;
mis.num_frames = num_frames;
};
void update_missile(missile & mis)
{
mis.current_x += mis.velocity_x;
mis.current_y += mis.velocity_y;
};
void resetMissile(int id){
missileArray[id].active = false;
missileArray[id].start_x = 0;
missileArray[id].start_y = 0;
missileArray[id].target_y = 0;
missileArray[id].target_x = 0;
missileArray[id].rel_frame = 0;
missileArray[id].num_frames = 0; // number of frames of travel, based on speed
missileArray[id].player = true; // this is a CPU missile, after all
missileArray[id].velocity_x = 0.0;
missileArray[id].velocity_y = 0.0;
};
// Drawing functions
extern const byte font3x5[];
Sun Sep 14, 2014 10:14 pm
Sun Sep 14, 2014 10:47 pm
yodasvideoarcade wrote:Looks nice!
In case you're interested to make it more like the original:
- Computer missiles ALWAYS aim directly at a city or weapon-storage of the player. They NEVER go in between. Most important thing: You have to destroy all computer missiles, because each one will hit a city.
- Every city can be hit only once and is destroyed then, no multiple hits of cities.
- In the original, there's six cities and three weapon-storages (left, middle, right). You can fire them by using three different buttons.
For the gamebuino-screen, I'd recommend two weapon-storages (left and right), that can be fired using the A and B buttons. Then you can put 4 cities between them.
- Original cities are much more flat, so they don't take up too much vertical space.
- Ammo is limited and shown in the storages. Storages can also be hit, then the ammo is gone.
Looking forward to play the finished game!