Fixed a bug when rendering the player's remaining number of lives.
This commit is contained in:
899
NXTInvaders.nxc
899
NXTInvaders.nxc
@@ -1,449 +1,450 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
; File : NXTInvaders.nxc
|
||||
; Description : A Space Invaders clone for the Mindstorms NXT.
|
||||
; Programmed by : Miguel Angel Astor, sonofgrendel@gmail.com
|
||||
; Version: 1.0
|
||||
; Date: 8/13/2013
|
||||
;-----------------------------------------------------------------------------*/
|
||||
|
||||
#download "ship.ric"
|
||||
#download "splash.ric"
|
||||
#download "invader.ric"
|
||||
#download "victory.ric"
|
||||
#download "defeat.ric"
|
||||
#define X_MAX 99
|
||||
#define Y_MAX 63
|
||||
#define X_MID (X_MAX + 1) / 2
|
||||
#define Y_MID (Y_MAX + 1) / 2
|
||||
#define DRAW_PARAMS DRAW_OPT_NORMAL | DRAW_OPT_LOGICAL_XOR | DRAW_OPT_FILL_SHAPE
|
||||
#define ALIEN_WIDTH 11
|
||||
#define BASE_ALIEN_X 2
|
||||
#define BASE_ALIEN_Y 32
|
||||
#define ALIENS 6
|
||||
|
||||
/*******************
|
||||
* Data structures *
|
||||
*******************/
|
||||
struct PLAYER_T{
|
||||
int x;
|
||||
int lives;
|
||||
int score;
|
||||
};
|
||||
|
||||
struct BULLET_T{
|
||||
int x, y;
|
||||
bool alive;
|
||||
};
|
||||
|
||||
struct ALIEN_T{
|
||||
int x, y;
|
||||
bool alive;
|
||||
};
|
||||
|
||||
/****************
|
||||
* Global data. *
|
||||
****************/
|
||||
const int alien_update_speed[] = {50, 72, 95,
|
||||
118, 140, 163,
|
||||
186, 209, 231,
|
||||
254, 277, 300 };
|
||||
int dead_aliens;
|
||||
bool victory;
|
||||
// keys[0] -> Left button; keys[1] -> Right button; keys[2] -> Center button.
|
||||
bool keys[3];
|
||||
// State: 0 -> Splash screen; 1 -> Game; 2 -> Hall of fame screen.
|
||||
int state, alien_frame, alien_x_offset;
|
||||
bool alien_x_forward, done;
|
||||
long then, then2;
|
||||
PLAYER_T player;
|
||||
BULLET_T p_bullets[3];
|
||||
ALIEN_T aliens1[ALIENS];
|
||||
ALIEN_T aliens2[ALIENS];
|
||||
BULLET_T a_bullets1[ALIENS];
|
||||
BULLET_T a_bullets2[ALIENS];
|
||||
|
||||
/*******************
|
||||
* Game functions. *
|
||||
*******************/
|
||||
/**
|
||||
* Catch the 3 possible player inputs.
|
||||
*/
|
||||
void input(){
|
||||
if(ButtonPressed(BTNLEFT, false)){
|
||||
keys[0] = true;
|
||||
}else{
|
||||
keys[0] = false;
|
||||
}
|
||||
|
||||
if(ButtonPressed(BTNRIGHT, false)){
|
||||
keys[1] = true;
|
||||
}else{
|
||||
keys[1] = false;
|
||||
}
|
||||
|
||||
if(ButtonPressed(BTNCENTER, false)){
|
||||
keys[2] = true;
|
||||
}else{
|
||||
keys[2] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes player input, moves game objects and updates the game's state.
|
||||
*/
|
||||
void update(){
|
||||
long now, delta_t, fire;
|
||||
|
||||
if(state == 0){
|
||||
if(keys[2]){
|
||||
state = 1;
|
||||
}
|
||||
}else if(state == 1){
|
||||
// Move the player.
|
||||
if(keys[0]){
|
||||
if(player.x - 1 >= 3){
|
||||
player.x -= 1;
|
||||
}
|
||||
}
|
||||
if(keys[1]){
|
||||
if(player.x + 1 <= X_MAX - 4){
|
||||
player.x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If the center button was pressed, fire a bullet.
|
||||
if(keys[2]){
|
||||
now = CurrentTick();
|
||||
delta_t = now - then;
|
||||
if(delta_t >= 500){
|
||||
// One bullet every 500 miliseconds.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(!p_bullets[i].alive){
|
||||
p_bullets[i].x = player.x;
|
||||
p_bullets[i].y = 0;
|
||||
p_bullets[i].alive = true;
|
||||
PlayTone(262, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
then = now;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the player's bullets.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
p_bullets[i].y += 1;
|
||||
if(p_bullets[i].y >= Y_MAX + 2){
|
||||
p_bullets[i].alive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the aliens.
|
||||
now = CurrentTick();
|
||||
delta_t = now - then2;
|
||||
if(delta_t >= alien_update_speed[11 - dead_aliens]){
|
||||
// Change the frame.
|
||||
if(alien_frame == 0){
|
||||
alien_frame = 11;
|
||||
}else{
|
||||
alien_frame = 0;
|
||||
}
|
||||
|
||||
// Move in the correct direction.
|
||||
if(alien_x_forward){
|
||||
alien_x_offset += 1;
|
||||
if(alien_x_offset >= 15){
|
||||
// Change direction 2 pixels before the edge of the screen.
|
||||
alien_x_offset -= 1;
|
||||
alien_x_forward = false;
|
||||
}
|
||||
}else{
|
||||
alien_x_offset -= 1;
|
||||
if(alien_x_offset <= 0){
|
||||
// Change direction 2 pixels before the edge of the screen.
|
||||
alien_x_offset += 1;
|
||||
alien_x_forward = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire on the player.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
if(aliens1[i].alive && !a_bullets1[i].alive){
|
||||
fire = rand() % 100;
|
||||
if(fire < 25){
|
||||
// 0.25 probability of firing.
|
||||
a_bullets1[i].alive = true;
|
||||
a_bullets1[i].x = aliens1[i].x + alien_x_offset + 5;
|
||||
a_bullets1[i].y = aliens1[i].y;
|
||||
PlayTone(400, 100);
|
||||
}
|
||||
}
|
||||
// Second row.
|
||||
if(aliens2[i].alive && !a_bullets2[i].alive){
|
||||
fire = rand() % 100;
|
||||
if(fire > 75){
|
||||
// 0.25 probability of firing.
|
||||
a_bullets2[i].alive = true;
|
||||
a_bullets2[i].x = aliens2[i].x + alien_x_offset + 5;
|
||||
a_bullets2[i].y = aliens2[i].y;
|
||||
PlayTone(400, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
then2 = now;
|
||||
}
|
||||
|
||||
// Update the alien's bullets.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
if(a_bullets1[i].alive){
|
||||
a_bullets1[i].y -= 1;
|
||||
if(a_bullets1[i].y < -2){
|
||||
a_bullets1[i].alive = false;
|
||||
}
|
||||
}
|
||||
// Second row.
|
||||
if(a_bullets2[i].alive){
|
||||
a_bullets2[i].y -= 1;
|
||||
if(a_bullets2[i].y < -2){
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any bullet shot by the player hit an alien.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
if(p_bullets[i].y >= 22 && p_bullets[i].y <= 30){
|
||||
// Check the second row first.
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
if(aliens2[j].alive){
|
||||
if(p_bullets[i].x >= aliens2[j].x + alien_x_offset &&
|
||||
p_bullets[i].x <= aliens2[j].x + alien_x_offset + 11){
|
||||
aliens2[j].alive = false;
|
||||
p_bullets[i].alive = false;
|
||||
player.score += 100;
|
||||
dead_aliens += 1;
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(p_bullets[i].y >= 32 && p_bullets[i].y <= 40){
|
||||
// Check the first row last.
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
if(aliens1[j].alive){
|
||||
if(p_bullets[i].x >= aliens1[j].x + alien_x_offset &&
|
||||
p_bullets[i].x <= aliens1[j].x + alien_x_offset + 11){
|
||||
aliens1[j].alive = false;
|
||||
p_bullets[i].alive = false;
|
||||
player.score += 150;
|
||||
dead_aliens += 1;
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check alien bullet collisions with player.
|
||||
// First row.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets1[i].alive && a_bullets1[i].y <= 2){
|
||||
if(a_bullets1[i].x >= player.x - 3 && a_bullets1[i].x <= player.x + 4){
|
||||
// If the bullet hit the player, reset the game.
|
||||
player.x = X_MID;
|
||||
player.lives -= 1;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
a_bullets1[i].alive = false;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second row
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets2[i].alive && a_bullets2[i].y <= 2){
|
||||
if(a_bullets2[i].x >= player.x - 3 && a_bullets2[i].x <= player.x + 4){
|
||||
// If the bullet hit the player, reset the game.
|
||||
player.x = X_MID;
|
||||
player.lives -= 1;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
a_bullets1[i].alive = false;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check victory/defeat conditions.
|
||||
if(dead_aliens == 12){
|
||||
state = 2;
|
||||
victory = true;
|
||||
PlayTone(500, 1000);
|
||||
ClearScreen();
|
||||
}else if(player.lives < 0){
|
||||
state = 2;
|
||||
victory = false;
|
||||
PlayTone(100, 1000);
|
||||
ClearScreen();
|
||||
}
|
||||
}else{
|
||||
if(keys[2]){
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all game objects to the LCD screen of the robot.
|
||||
*/
|
||||
void render(){
|
||||
int params[3] = {0, 0, 0};
|
||||
if(state == 0){
|
||||
// Render the splash screen.
|
||||
GraphicOut(0, 0, "splash.ric");
|
||||
}else if(state == 1){
|
||||
ClearScreen();
|
||||
// Render informative text.
|
||||
TextOut(0, LCD_LINE1, "LIVES:");
|
||||
//NumOut(35, LCD_LINE1, player.lives);
|
||||
params[0] = 35;
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
if(player.lives > 1){
|
||||
params[0] = 44;
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
if(player.lives > 2){
|
||||
params[0] = 53;
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
}
|
||||
}
|
||||
TextOut(0, LCD_LINE2, "SCORE:");
|
||||
NumOut(35, LCD_LINE2, player.score);
|
||||
|
||||
// Render the player's sprite.
|
||||
params[0] = player.x - 3;
|
||||
GraphicOutEx(0, 0, "ship.ric", params);
|
||||
|
||||
// Render the player's bullets.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
RectOut(p_bullets[i].x, p_bullets[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the aliens.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(aliens1[i].alive){
|
||||
// First row.
|
||||
params[0] = alien_frame;
|
||||
params[1] = aliens1[i].x + alien_x_offset;
|
||||
params[2] = aliens1[i].y;
|
||||
GraphicOutEx(0, 0, "invader.ric", params);
|
||||
}
|
||||
if(aliens2[i].alive){
|
||||
// Second row.
|
||||
params[0] = alien_frame;
|
||||
params[1] = aliens2[i].x + alien_x_offset;
|
||||
params[2] = aliens2[i].y;
|
||||
GraphicOutEx(0, 0, "invader.ric", params);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the aliens's bullets.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets1[i].alive){
|
||||
RectOut(a_bullets1[i].x, a_bullets1[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
if(a_bullets2[i].alive){
|
||||
RectOut(a_bullets2[i].x, a_bullets2[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// Render the hall of fame.
|
||||
if(victory){
|
||||
params[0] = player.score;
|
||||
GraphicOutEx(0, 0, "victory.ric", params);
|
||||
}else{
|
||||
GraphicOut(0, 0, "defeat.ric");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The heart of the game.
|
||||
*/
|
||||
void game_loop(){
|
||||
while(!done){
|
||||
input();
|
||||
update();
|
||||
render();
|
||||
Wait(50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all game data and call the game loop.
|
||||
*/
|
||||
task main(){
|
||||
// Initialize game data.
|
||||
state = 0;
|
||||
done = false;
|
||||
alien_frame = 0;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
|
||||
// Initialize the player and bullets.
|
||||
player.x = X_MID;
|
||||
player.lives = 3;
|
||||
player.score = 0;
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
p_bullets[i].x = 0;
|
||||
p_bullets[i].y = 0;
|
||||
p_bullets[i].alive = false;
|
||||
}
|
||||
|
||||
// Initialize the aliens.
|
||||
dead_aliens = 0;
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
aliens1[i].x = BASE_ALIEN_X + (i * 14);
|
||||
aliens1[i].y = BASE_ALIEN_Y;
|
||||
aliens1[i].alive = true;
|
||||
// Second row.
|
||||
aliens2[i].x = BASE_ALIEN_X + (i * 14);
|
||||
aliens2[i].y = BASE_ALIEN_Y - 10;
|
||||
aliens2[i].alive = true;
|
||||
// Alien bullets, first row.
|
||||
a_bullets1[i].x = 0;
|
||||
a_bullets1[i].y = 0;
|
||||
a_bullets1[i].alive = false;
|
||||
// Second row.
|
||||
a_bullets2[i].x = 0;
|
||||
a_bullets2[i].y = 0;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
|
||||
// Initialize time variables.
|
||||
then = CurrentTick();
|
||||
then2 = CurrentTick();
|
||||
|
||||
// Start the game!
|
||||
PlayTone(500, 1000);
|
||||
game_loop();
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
; File : NXTInvaders.nxc
|
||||
; Description : A Space Invaders clone for the Mindstorms NXT.
|
||||
; Programmed by : Miguel Angel Astor, sonofgrendel@gmail.com
|
||||
; Version: 1.0
|
||||
; Date: 8/13/2013
|
||||
;-----------------------------------------------------------------------------*/
|
||||
|
||||
#download "ship.ric"
|
||||
#download "splash.ric"
|
||||
#download "invader.ric"
|
||||
#download "victory.ric"
|
||||
#download "defeat.ric"
|
||||
#define X_MAX 99
|
||||
#define Y_MAX 63
|
||||
#define X_MID (X_MAX + 1) / 2
|
||||
#define Y_MID (Y_MAX + 1) / 2
|
||||
#define DRAW_PARAMS DRAW_OPT_NORMAL | DRAW_OPT_LOGICAL_XOR | DRAW_OPT_FILL_SHAPE
|
||||
#define ALIEN_WIDTH 11
|
||||
#define BASE_ALIEN_X 2
|
||||
#define BASE_ALIEN_Y 32
|
||||
#define ALIENS 6
|
||||
|
||||
/*******************
|
||||
* Data structures *
|
||||
*******************/
|
||||
struct PLAYER_T{
|
||||
int x;
|
||||
int lives;
|
||||
int score;
|
||||
};
|
||||
|
||||
struct BULLET_T{
|
||||
int x, y;
|
||||
bool alive;
|
||||
};
|
||||
|
||||
struct ALIEN_T{
|
||||
int x, y;
|
||||
bool alive;
|
||||
};
|
||||
|
||||
/****************
|
||||
* Global data. *
|
||||
****************/
|
||||
const int alien_update_speed[] = {50, 72, 95,
|
||||
118, 140, 163,
|
||||
186, 209, 231,
|
||||
254, 277, 300 };
|
||||
int dead_aliens;
|
||||
bool victory;
|
||||
// keys[0] -> Left button; keys[1] -> Right button; keys[2] -> Center button.
|
||||
bool keys[3];
|
||||
// State: 0 -> Splash screen; 1 -> Game; 2 -> Hall of fame screen.
|
||||
int state, alien_frame, alien_x_offset;
|
||||
bool alien_x_forward, done;
|
||||
long then, then2;
|
||||
PLAYER_T player;
|
||||
BULLET_T p_bullets[3];
|
||||
ALIEN_T aliens1[ALIENS];
|
||||
ALIEN_T aliens2[ALIENS];
|
||||
BULLET_T a_bullets1[ALIENS];
|
||||
BULLET_T a_bullets2[ALIENS];
|
||||
|
||||
/*******************
|
||||
* Game functions. *
|
||||
*******************/
|
||||
/**
|
||||
* Catch the 3 possible player inputs.
|
||||
*/
|
||||
void input(){
|
||||
if(ButtonPressed(BTNLEFT, false)){
|
||||
keys[0] = true;
|
||||
}else{
|
||||
keys[0] = false;
|
||||
}
|
||||
|
||||
if(ButtonPressed(BTNRIGHT, false)){
|
||||
keys[1] = true;
|
||||
}else{
|
||||
keys[1] = false;
|
||||
}
|
||||
|
||||
if(ButtonPressed(BTNCENTER, false)){
|
||||
keys[2] = true;
|
||||
}else{
|
||||
keys[2] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes player input, moves game objects and updates the game's state.
|
||||
*/
|
||||
void update(){
|
||||
long now, delta_t, fire;
|
||||
|
||||
if(state == 0){
|
||||
if(keys[2]){
|
||||
state = 1;
|
||||
}
|
||||
}else if(state == 1){
|
||||
// Move the player.
|
||||
if(keys[0]){
|
||||
if(player.x - 1 >= 3){
|
||||
player.x -= 1;
|
||||
}
|
||||
}
|
||||
if(keys[1]){
|
||||
if(player.x + 1 <= X_MAX - 4){
|
||||
player.x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If the center button was pressed, fire a bullet.
|
||||
if(keys[2]){
|
||||
now = CurrentTick();
|
||||
delta_t = now - then;
|
||||
if(delta_t >= 500){
|
||||
// One bullet every 500 miliseconds.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(!p_bullets[i].alive){
|
||||
p_bullets[i].x = player.x;
|
||||
p_bullets[i].y = 0;
|
||||
p_bullets[i].alive = true;
|
||||
PlayTone(262, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
then = now;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the player's bullets.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
p_bullets[i].y += 1;
|
||||
if(p_bullets[i].y >= Y_MAX + 2){
|
||||
p_bullets[i].alive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the aliens.
|
||||
now = CurrentTick();
|
||||
delta_t = now - then2;
|
||||
if(delta_t >= alien_update_speed[11 - dead_aliens]){
|
||||
// Change the frame.
|
||||
if(alien_frame == 0){
|
||||
alien_frame = 11;
|
||||
}else{
|
||||
alien_frame = 0;
|
||||
}
|
||||
|
||||
// Move in the correct direction.
|
||||
if(alien_x_forward){
|
||||
alien_x_offset += 1;
|
||||
if(alien_x_offset >= 15){
|
||||
// Change direction 2 pixels before the edge of the screen.
|
||||
alien_x_offset -= 1;
|
||||
alien_x_forward = false;
|
||||
}
|
||||
}else{
|
||||
alien_x_offset -= 1;
|
||||
if(alien_x_offset <= 0){
|
||||
// Change direction 2 pixels before the edge of the screen.
|
||||
alien_x_offset += 1;
|
||||
alien_x_forward = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire on the player.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
if(aliens1[i].alive && !a_bullets1[i].alive){
|
||||
fire = rand() % 100;
|
||||
if(fire < 25){
|
||||
// 0.25 probability of firing.
|
||||
a_bullets1[i].alive = true;
|
||||
a_bullets1[i].x = aliens1[i].x + alien_x_offset + 5;
|
||||
a_bullets1[i].y = aliens1[i].y;
|
||||
PlayTone(400, 100);
|
||||
}
|
||||
}
|
||||
// Second row.
|
||||
if(aliens2[i].alive && !a_bullets2[i].alive){
|
||||
fire = rand() % 100;
|
||||
if(fire > 75){
|
||||
// 0.25 probability of firing.
|
||||
a_bullets2[i].alive = true;
|
||||
a_bullets2[i].x = aliens2[i].x + alien_x_offset + 5;
|
||||
a_bullets2[i].y = aliens2[i].y;
|
||||
PlayTone(400, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
then2 = now;
|
||||
}
|
||||
|
||||
// Update the alien's bullets.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
if(a_bullets1[i].alive){
|
||||
a_bullets1[i].y -= 1;
|
||||
if(a_bullets1[i].y < -2){
|
||||
a_bullets1[i].alive = false;
|
||||
}
|
||||
}
|
||||
// Second row.
|
||||
if(a_bullets2[i].alive){
|
||||
a_bullets2[i].y -= 1;
|
||||
if(a_bullets2[i].y < -2){
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any bullet shot by the player hit an alien.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
if(p_bullets[i].y >= 22 && p_bullets[i].y <= 30){
|
||||
// Check the second row first.
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
if(aliens2[j].alive){
|
||||
if(p_bullets[i].x >= aliens2[j].x + alien_x_offset &&
|
||||
p_bullets[i].x <= aliens2[j].x + alien_x_offset + 11){
|
||||
aliens2[j].alive = false;
|
||||
p_bullets[i].alive = false;
|
||||
player.score += 100;
|
||||
dead_aliens += 1;
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(p_bullets[i].y >= 32 && p_bullets[i].y <= 40){
|
||||
// Check the first row last.
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
if(aliens1[j].alive){
|
||||
if(p_bullets[i].x >= aliens1[j].x + alien_x_offset &&
|
||||
p_bullets[i].x <= aliens1[j].x + alien_x_offset + 11){
|
||||
aliens1[j].alive = false;
|
||||
p_bullets[i].alive = false;
|
||||
player.score += 150;
|
||||
dead_aliens += 1;
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check alien bullet collisions with player.
|
||||
// First row.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets1[i].alive && a_bullets1[i].y <= 2){
|
||||
if(a_bullets1[i].x >= player.x - 3 && a_bullets1[i].x <= player.x + 4){
|
||||
// If the bullet hit the player, reset the game.
|
||||
player.x = X_MID;
|
||||
player.lives -= 1;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
a_bullets1[i].alive = false;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second row
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets2[i].alive && a_bullets2[i].y <= 2){
|
||||
if(a_bullets2[i].x >= player.x - 3 && a_bullets2[i].x <= player.x + 4){
|
||||
// If the bullet hit the player, reset the game.
|
||||
player.x = X_MID;
|
||||
player.lives -= 1;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
for(int j = 0; j < ALIENS; j++){
|
||||
a_bullets1[i].alive = false;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
PlayTone(100, 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check victory/defeat conditions.
|
||||
if(dead_aliens == 12){
|
||||
state = 2;
|
||||
victory = true;
|
||||
PlayTone(500, 1000);
|
||||
ClearScreen();
|
||||
}else if(player.lives < 0){
|
||||
state = 2;
|
||||
victory = false;
|
||||
PlayTone(100, 1000);
|
||||
ClearScreen();
|
||||
}
|
||||
}else{
|
||||
if(keys[2]){
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all game objects to the LCD screen of the robot.
|
||||
*/
|
||||
void render(){
|
||||
int params[3] = {0, 0, 0};
|
||||
if(state == 0){
|
||||
// Render the splash screen.
|
||||
GraphicOut(0, 0, "splash.ric");
|
||||
}else if(state == 1){
|
||||
ClearScreen();
|
||||
// Render informative text.
|
||||
TextOut(0, LCD_LINE1, "LIVES:");
|
||||
params[0] = 35;
|
||||
if(player.lives > 0){
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
if(player.lives > 1){
|
||||
params[0] = 44;
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
if(player.lives > 2){
|
||||
params[0] = 53;
|
||||
GraphicOutEx(0, LCD_LINE1 + 1, "ship.ric", params);
|
||||
}
|
||||
}
|
||||
}
|
||||
TextOut(0, LCD_LINE2, "SCORE:");
|
||||
NumOut(35, LCD_LINE2, player.score);
|
||||
|
||||
// Render the player's sprite.
|
||||
params[0] = player.x - 3;
|
||||
GraphicOutEx(0, 0, "ship.ric", params);
|
||||
|
||||
// Render the player's bullets.
|
||||
for(int i = 0; i < 3; i++){
|
||||
if(p_bullets[i].alive){
|
||||
RectOut(p_bullets[i].x, p_bullets[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the aliens.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(aliens1[i].alive){
|
||||
// First row.
|
||||
params[0] = alien_frame;
|
||||
params[1] = aliens1[i].x + alien_x_offset;
|
||||
params[2] = aliens1[i].y;
|
||||
GraphicOutEx(0, 0, "invader.ric", params);
|
||||
}
|
||||
if(aliens2[i].alive){
|
||||
// Second row.
|
||||
params[0] = alien_frame;
|
||||
params[1] = aliens2[i].x + alien_x_offset;
|
||||
params[2] = aliens2[i].y;
|
||||
GraphicOutEx(0, 0, "invader.ric", params);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the aliens's bullets.
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
if(a_bullets1[i].alive){
|
||||
RectOut(a_bullets1[i].x, a_bullets1[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
if(a_bullets2[i].alive){
|
||||
RectOut(a_bullets2[i].x, a_bullets2[i].y, 0, 2, DRAW_PARAMS);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
// Render the hall of fame.
|
||||
if(victory){
|
||||
params[0] = player.score;
|
||||
GraphicOutEx(0, 0, "victory.ric", params);
|
||||
}else{
|
||||
GraphicOut(0, 0, "defeat.ric");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The heart of the game.
|
||||
*/
|
||||
void game_loop(){
|
||||
while(!done){
|
||||
input();
|
||||
update();
|
||||
render();
|
||||
Wait(50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all game data and call the game loop.
|
||||
*/
|
||||
task main(){
|
||||
// Initialize game data.
|
||||
state = 0;
|
||||
done = false;
|
||||
alien_frame = 0;
|
||||
alien_x_offset = 0;
|
||||
alien_x_forward = true;
|
||||
|
||||
// Initialize the player and bullets.
|
||||
player.x = X_MID;
|
||||
player.lives = 3;
|
||||
player.score = 0;
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
p_bullets[i].x = 0;
|
||||
p_bullets[i].y = 0;
|
||||
p_bullets[i].alive = false;
|
||||
}
|
||||
|
||||
// Initialize the aliens.
|
||||
dead_aliens = 0;
|
||||
for(int i = 0; i < ALIENS; i++){
|
||||
// First row.
|
||||
aliens1[i].x = BASE_ALIEN_X + (i * 14);
|
||||
aliens1[i].y = BASE_ALIEN_Y;
|
||||
aliens1[i].alive = true;
|
||||
// Second row.
|
||||
aliens2[i].x = BASE_ALIEN_X + (i * 14);
|
||||
aliens2[i].y = BASE_ALIEN_Y - 10;
|
||||
aliens2[i].alive = true;
|
||||
// Alien bullets, first row.
|
||||
a_bullets1[i].x = 0;
|
||||
a_bullets1[i].y = 0;
|
||||
a_bullets1[i].alive = false;
|
||||
// Second row.
|
||||
a_bullets2[i].x = 0;
|
||||
a_bullets2[i].y = 0;
|
||||
a_bullets2[i].alive = false;
|
||||
}
|
||||
|
||||
// Initialize time variables.
|
||||
then = CurrentTick();
|
||||
then2 = CurrentTick();
|
||||
|
||||
// Start the game!
|
||||
PlayTone(500, 1000);
|
||||
game_loop();
|
||||
}
|
Reference in New Issue
Block a user