OK, bon, je n’ai pas tout compris avec le problème actuellement sur les variables locales mais du coup j’ai réécris un peu le programme pour que ça fonctionne et comme ça ne bougeait pas fort en réponse à mon petit challenge, j’ai rajouté le test de collision entre le tir du vaisseau et les ennemis.
Du coup ça donne ça:
// Tuto Space invader - Part 5: Add timer for shots and invaders move and make them go down
/*settings*{"name":"Space_Invad","author":"Jicehel","image":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,119,7,112,0,112,0,119,7,119,0,0,112,0,7,7,7,7,7,0,7,0,0,0,7,112,7,7,7,7,7,0,7,112,0,0,0,7,7,112,7,119,7,0,7,0,0,0,119,112,7,0,7,7,0,119,7,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,112,7,7,0,7,0,112,7,112,0,0,112,119,7,7,0,7,0,112,7,7,0,0,112,119,119,0,112,112,7,7,7,7,0,0,112,112,119,0,112,112,7,119,7,7,0,0,112,112,7,0,7,0,7,7,7,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}*/
// define constantes
#define invader_init_speed 2
#define invader_lines 4
#define invader_columns 6
#define timer_ship_shot 1
#define timer_invaders 2
#define timer_invaders_shot 3
#define debug 0
// Sprites
// Invader 8 pixels x 8 pixels x 5 rows x 2 frames with 2 separation lines between rows
char invader[]= {
0x00, 0x70, 0x07, 0x00,
0x00, 0x77, 0x77, 0x00,
0x07, 0x77, 0x77, 0x70,
0x07, 0x77, 0x77, 0x70,
0x77, 0x07, 0x70, 0x77,
0x77, 0x77, 0x77, 0x77,
0x07, 0x70, 0x07, 0x70,
0x07, 0x00, 0x00, 0x70,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x50, 0x00,
0x00, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x50,
0x55, 0x05, 0x50, 0x55,
0x55, 0x55, 0x55, 0x55,
0x00, 0x50, 0x05, 0x00,
0x05, 0x05, 0x50, 0x50,
0x50, 0x50, 0x05, 0x05,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x50, 0x00,
0x00, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x50,
0x55, 0x05, 0x50, 0x55,
0x55, 0x55, 0x55, 0x55,
0x00, 0x50, 0x05, 0x00,
0x05, 0x00, 0x00, 0x50,
0x00, 0x50, 0x05, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x06, 0x00,
0x00, 0x06, 0x60, 0x00,
0x06, 0x66, 0x66, 0x60,
0x06, 0x06, 0x60, 0x60,
0x60, 0x66, 0x66, 0x06,
0x66, 0x00, 0x00, 0x66,
0x60, 0x60, 0x06, 0x06,
0x06, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x60, 0x60, 0x06, 0x06,
0x60, 0x06, 0x60, 0x06,
0x66, 0x66, 0x66, 0x66,
0x66, 0x06, 0x60, 0x66,
0x00, 0x66, 0x66, 0x00,
0x06, 0x00, 0x00, 0x60,
0x06, 0x60, 0x06, 0x60,
0x66, 0x00, 0x00, 0x66,
0x00, 0x70, 0x07, 0x00,
0x00, 0x77, 0x77, 0x00,
0x07, 0x77, 0x77, 0x70,
0x07, 0x77, 0x77, 0x70,
0x77, 0x07, 0x70, 0x77,
0x77, 0x77, 0x77, 0x77,
0x07, 0x70, 0x07, 0x70,
0x07, 0x00, 0x00, 0x70,
0x70, 0x00, 0x00, 0x07,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x50, 0x00,
0x00, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x50,
0x55, 0x05, 0x50, 0x55,
0x55, 0x55, 0x55, 0x55,
0x00, 0x50, 0x05, 0x00,
0x05, 0x00, 0x00, 0x50,
0x00, 0x50, 0x05, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x50, 0x00,
0x00, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x50,
0x55, 0x05, 0x50, 0x55,
0x55, 0x55, 0x55, 0x55,
0x00, 0x50, 0x05, 0x00,
0x05, 0x05, 0x50, 0x50,
0x50, 0x50, 0x05, 0x05,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x60, 0x60, 0x06, 0x06,
0x60, 0x06, 0x60, 0x06,
0x66, 0x66, 0x66, 0x66,
0x66, 0x06, 0x60, 0x66,
0x00, 0x66, 0x66, 0x00,
0x06, 0x60, 0x06, 0x60,
0x66, 0x00, 0x00, 0x66,
0x00, 0x60, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x60, 0x00,
0x06, 0x66, 0x66, 0x60,
0x06, 0x06, 0x60, 0x60,
0x60, 0x66, 0x66, 0x06,
0x66, 0x00, 0x00, 0x66,
0x60, 0x60, 0x06, 0x06,
0x06, 0x00, 0x00, 0x60,
0x06, 0x00, 0x00, 0x60
};
char bunker[]= {
0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00,
0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00,
0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50,
0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x50, 0x00, 0x00, 0x05, 0x55, 0x55,
0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55,
0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55,
0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55,
0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55
};
char player[]= {
0x00, 0x00, 0x01, 0x10, 0x00, 0x00,
0x00, 0x00, 0x26, 0x62, 0x00, 0x00,
0x00, 0x00, 0x63, 0x16, 0x00, 0x00,
0x00, 0x02, 0x63, 0x16, 0x20, 0x00,
0x02, 0x21, 0x63, 0x36, 0x12, 0x20,
0x21, 0xc1, 0x26, 0x62, 0x1c, 0x12,
0x21, 0xc2, 0x21, 0x12, 0x2c, 0x12,
0x22, 0x20, 0x04, 0x40, 0x02, 0x22
};
char shot_beam{] = {
0x22,
0x22,
0x22,
0x22
};
//define variables
// invaders variables
int invader_x;
int invader_y = 20;
int invader_speed;
int frame; // We'll use 2 frames 0 and 1
int i;
int max_x, min_x, max_y, min_y;
int sprite_invader = 0; // max sprite invader = 18
int invader_w = 8;
int invader_h = 8;
int invader_space_w = 2;
int invader_space_h = 2;
int life_invader; // temp variable with noumber of lifes keeping
int col_hitted; // temp variable of column hitted
int shot; // temp variable of shot hitting
int first_column, last_column;
int last_row;
int y_endline;
int nb_life = 3;
// player variables
int player_x;
int player_y;
int player_speed;
int sprite_player = 9;
// shots variables
int max_shot = 6;
int sprite_shot = 10; // max sprite shot = 22
int shoots_done;
int next_shot;
int shot_speed = 2; // speed of the shot move
int timer_cooldown, delay_invader_shot, delay_move_invaders;
int shot_live;
int shot_x,shot_y;
// bunkers variables
int sprite_bunkers = 29;
int y_bunkers = 88;
// game variables
int key;
int score;
// Clear the shot then it goes out of the screen
void clear_shot() {
spritesetvalue(shot, S_LIVES, 0);
--shoots_done;
};
// The shot of the ship have hit something
void shot_hit() {
if (life_invader > 0) {
score = score + 10;
drawparticle(spritegetvalue(col_hitted, S_X + 0.5 * invader_w ), spritegetvalue(col_hitted, S_Y) + life_invader * (invader_h + invader_space_h), random(3)+1);
--life_invader;
spritesetvalue(col_hitted, S_LIVES, life_invader);
if (life_invader > 0){
int height = life_invader * (invader_h + invader_space_h) - invader_space_h
spritesetvalue(col_hitted, S_HEIGHT, life_invader * (invader_h + invader_space_h) - invader_space_h);
} else {
spritesetvalue(col_hitted, S_HEIGHT,0);
}
clear_shot();
}
};
// initialisation of values
void init(){
// init game
score = 0;
setbgcolor(0);
// init player
player_x = 58;
player_y = 105;
player_speed = 0;
spritesetvalue(sprite_player,S_WIDTH,12);
spritesetvalue(sprite_player,S_HEIGHT,8);
spritesetvalue(sprite_player, S_LIVES, nb_life);
getsprite(sprite_player,player);
// init invaders
invader_x = 0;
frame = 0;
invader_speed = invader_init_speed;
i = sprite_invader;
for( int col = 0; col < invader_columns; col++ ){
int x = invader_x + col * (invader_w + invader_space_w);
spritesetvalue(i, S_WIDTH, invader_w);
spritesetvalue(i, S_HEIGHT,invader_lines * (invader_h + invader_space_h)-invader_space_h);
spritesetvalue(i, S_LIVES, invader_lines);
getsprite(i, invader);
putsprite(i, x, invader_y);
i++;
}
}
first_column = 1;
last_column = invader_columns;
last_row = invader_lines;
max_x = invader_columns * (invader_w + invader_space_w);
min_x = 0;
min_y = invader_y;
max_y = invader_y + invader_lines * (invader_h + invader_space_h) - invader_space_h;
y_endline = 128 - invader_h;
getsprite(1,invader);
delay_move_invaders = 100;
// if (debug == 1) delay_move_invaders = 600;
delay_invader_shot = 500;
// init player shots
shoots_done = 0;
for(int s = sprite_shot; s < (sprite_shot + max_shot); s++) {
spritesetvalue(s, S_WIDTH, 2);
spritesetvalue(s, S_HEIGHT,4);
spritesetvalue(s, S_LIVES,0);
// spritesetvalue(s, S_ON_COLLISION, shot_hit);
// spritesetvalue(s, S_ON_EXIT_SCREEN, clear_shot);
getsprite(s, shot_beam);
}
timer_cooldown = 600;
// init bunkers
for(int b = 0; b < 3; b++) {
getsprite(b + sprite_bunkers, bunker);
spritesetvalue(b + sprite_bunkers, S_WIDTH, 16);
spritesetvalue(b + sprite_bunkers, S_HEIGHT, 12);
}
setframerate(30);
settimer( timer_ship_shot, timer_cooldown );
settimer( timer_invaders, delay_move_invaders);
settimer( timer_invaders_shot, delay_invader_shot);
}
// Ship shot add
void add_ship_shot() {
if (next_shot >= sprite_shot) {
putsprite(next_shot, player_x + 6, player_y - 5);
spritesetvalue(next_shot, S_LIVES, 1);
++shoots_done;
}
};
// Step procedure to make the game evolve between each draw
void step(){
// manage invaders
if (gettimer( timer_invaders ) <= 0 ) {
char change_ligne = 0;
frame = 1 - frame;
max_x = max_x + invader_speed;
min_x = min_x + invader_speed;
if (max_x > y_endline + invader_w) {
invader_speed = -invader_init_speed;
change_ligne = 1;
min_x = min_x + invader_speed;
max_x = max_x + invader_speed;
}
if (min_x < invader_init_speed) {
invader_speed = invader_init_speed;
change_ligne = 1;
min_x = min_x + invader_speed;
max_x = max_x + invader_speed;
}
for( int col = sprite_invader; col < (sprite_invader + invader_columns); col++ ){
if (spritegetvalue(col, S_LIVES) > 0) {
putsprite(col, spritegetvalue(col, S_X) + invader_speed, spritegetvalue(col, S_Y) + change_ligne * (invader_h + invader_space_h));
}
if ((change_ligne > 0) && (min_y > y_endline)) {
int x = invader_x + col * (invader_w + invader_space_w);
int y = invader_y;
spritesetvalue(col, S_X, x);
spritesetvalue(col, S_Y, y);
}
}
if (change_ligne > 0) {
if (min_y > y_endline) {
max_x = invader_columns * (invader_w + invader_space_w);
min_x = 0;
min_y = invader_y;
max_y = invader_y + invader_lines * (invader_h + invader_space_h) - invader_space_h;
invader_speed = invader_init_speed;
} else {
min_y = spritegetvalue(first_column,S_Y);
max_y = spritegetvalue(first_column,S_Y) + invader_lines * (invader_h + invader_space_h) - invader_space_h;
}
}
// if (debug == 1) {
// gotoxy(0,15); putn(min_y);puts(" ");putn(max_y);
// rect(min_x, min_y, max_x, max_y);
// }
settimer( timer_invaders, delay_move_invaders);
}
// manage shots
for(int s = 0; s < max_shot; s++) {
shot = s + sprite_shot;
shot_live = spritegetvalue(shot, S_LIVES);
if ( shot_live > 0) {
shot_y = spritegetvalue(shot, S_Y) - shot_speed;
if (shot_y < 10) {
clear_shot();
} else {
spritesetvalue(shot, S_Y, spritegetvalue(s + sprite_shot, S_Y) - shot_speed);
}
// test if an invader has been hitted
if ((shot_y < max_y ) && (shot_y >= min_y)) {
shot_x = spritegetvalue(shot, S_X);
if ((shot_x < max_x) && (shot_x >= min_x)) {
col_hitted = sprite_invader + ((shot_x - min_x) / (invader_w + invader_space_w));
life_invader = spritegetvalue(col_hitted, S_LIVES);
if (debug = 1) {
// setcolor(2);
// gotoxy(15,1); puts("col:");putn(col_hitted);puts(" ");
// setcolor(6);
// rect(min_x, min_y, max_x, (min_y + life_invader * (invader_h + invader_space_h)));
}
if (life_invader > 0) {
if (shot_y < (min_y + life_invader * (invader_h + invader_space_h))) shot_hit();
}
}
}
}
// manage keyboard inputs
key = getKey();
if (key & KEY_RIGHT) {
player_speed = player_speed + 3 ;
} else if (key & KEY_LEFT) {
player_speed = player_speed - 3 ;
}
// manage limits
player_x = player_x + player_speed;
if (player_x > 116) player_x = 116;
if (player_x < 0) player_x = 0;
// test if the player try to shoot
if (key & KEY_A) {
if (shoots_done < max_shot) {
if( gettimer( timer_ship_shot ) <= 0 ) {
settimer( timer_ship_shot, timer_cooldown );
for(int s = sprite_shot; s < (sprite_shot + max_shot); s++) {
if (spritegetvalue(s, S_LIVES) == 0) {
next_shot = s;
}
}
add_ship_shot();
}
}
}
// reset speed (no inertia)
player_speed = 0;
}
// Draw procedure
void draw(){
clearscreen();
if (debug == 1) {
setcolor(1);
gotoxy(0,0); putn(min_y); puts(" ");
gotoxy(10,0); putn(max_y);puts(" ");
gotoxy(0,1); putn(min_x); puts(" ");
gotoxy(10,1); putn(max_x);puts(" ");
} else {
gotoxy(0,0); puts("score:");putn(score); puts(" ");
gotoxy(10,0); puts("vies: ");
for(int v = 0; v < 3; v++) {
putimage(player, 88 + v*13, 1, 12, 8);
}
}
// draw shots
for(int s = 0; s < max_shot; s++) {
if (spritegetvalue(s + sprite_shot, S_LIVES) > 0) {
putsprite(s + sprite_shot, spritegetvalue(s + sprite_shot, S_X),spritegetvalue(s + sprite_shot, S_Y));
}
}
// draw invaders
i = sprite_invader;
for( int col = 0; col < invader_columns; col++ ){
int x = spritegetvalue(i, S_X);
int y = spritegetvalue(i, S_Y);
getsprite(i, invader + frame * 192);
putsprite(i, x, y);
i++;
}
// draw bunkers
putsprite(sprite_bunkers, 10, y_bunkers );
putsprite(sprite_bunkers +1, 56, y_bunkers );
putsprite(sprite_bunkers +2, 102, y_bunkers );
// draw ship of the player
putsprite(sprite_player, player_x, player_y); // draw the sprite of the ship played
delayredraw(); // wait until the frame is drawn.
}
// Main procedure
void main(){
init();
while(1){
step();
draw();
}
}
Bon il reste des choses à faire: Ajout des tir des aliens, test de collision des aliens avec le vaisseau, ajustement des valeurs maxi et mini pour gérer les déplacements des aliens et après on s’attaquera aux sons et à la musique… mais ça avance