/* **update\_level()** is called by the Cage game loop for every frame * and has to update the game state ( animations, positions, etc..) * as well as redraw the frame using **draw\_level()**. */ static void update_level(void* data, float elapsed_ms) { struct level_data* ldata = data; animate_wizard(ldata->wizard, elapsed_ms); animate_sprite(ldata->tree.sprite, elapsed_ms); draw_level(data, elapsed_ms); update_timeline(ldata->timeline, data, elapsed_ms); if (key_pressed(KB_ESC)) exit(0); }
static void* bling_title(void* data, float elapsed_ms, float progress) { struct level_data* ldata = data; UNUSED(elapsed_ms); draw_sprite(ldata->title.sprite, 20, 10); if (progress < 0.1) play_animation(ldata->title.sprite, ldata->title.bling); animate_sprite(ldata->title.sprite, elapsed_ms); return NULL; }
/* The wizard is controlled using the keyboard (for now). * **animate\_wizard()** sets the wizard animation * based on the player keypresses and the animation user-data * as it was set up in the **create\_wizard()** function. * * We use the user-data value as a speed constant. This * was setup as part of the animation. */ static void animate_wizard(struct wizard* wizard, float elapsed_ms) { const void* px; struct animation* active_anim; active_anim = key_down(KB_SPACE) ? wizard->spell : key_down(KB_RIGHT) ? wizard->walk_right : key_down(KB_LEFT) ? wizard->walk_left : wizard->stand; play_animation(wizard->sprite, active_anim); if ((px = animate_sprite(wizard->sprite, elapsed_ms)) != NULL) { wizard->speed = *((const float*)px); } wizard->pos.x += wizard->speed; }
int move_ball(Sprite *bola, Vector *vec_blocos) { //>>>>>>>>>>>>>>>>>>>>>> actualiza o bloco que simula a nave como um bloco para as colisões Bloco *nave_block = (Bloco*)get_back_element(vec_blocos); nave_block->sprite->x = nave_pos.x; nave_block->sprite->y = nave_pos.y; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> infos speed = sqrt(bola->xspeed * bola->xspeed + bola->yspeed * bola->yspeed); drawIntAt(pontuation, SCORE_X_POS, SCORE_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); drawIntAt(speed , SPEED_X_POS, SPEED_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); drawIntAt(lives, LIFES_X_POS, LIFES_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> colisão com as paredes Bool first_hit = true; //lado direito while ((bola->x + bola->width + COLLISION_DETECTION_OFFSET) > MAX_GAME_WINDOWS_X) { int new_xspeed = -abs(bola->xspeed); bola->xspeed = new_xspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); } first_hit = true; //lado esquerdo while ((bola->x - COLLISION_DETECTION_OFFSET) < MIN_GAME_WINDOWS_X) { int new_xspeed = abs(bola->xspeed); bola->xspeed = new_xspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); first_hit = false; } first_hit = true; //baixo while ((bola->y + bola->height + COLLISION_DETECTION_OFFSET) > MAX_GAME_WINDOWS_Y) { int new_yspeed = -abs(bola->yspeed); bola->yspeed = new_yspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&ground_hit); --lives; mili_sleep(10); delete_sprite(bola, VIDEO_BASE_ADDRESS); bola->x = (nave_pos.x + nave_parada->width / 2); bola->y = VRES * 0.82; bola->xspeed = 1; bola->yspeed = -2; first_hit = false; } first_hit = true; //cima while ((bola->y - COLLISION_DETECTION_OFFSET) < MIN_GAME_WINDOWS_Y) { int new_yspeed = abs(bola->yspeed); bola->yspeed = new_yspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); first_hit = false; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Tipos de movimentos da bola para saber como calcular a colisao com os blocos unsigned int collision_type; if ((bola->xspeed >= 0) && (bola->yspeed <= 0)) collision_type = 0; if ((bola->xspeed <= 0) && (bola->yspeed < 0)) collision_type = 1; if ((bola->xspeed < 0) && (bola->yspeed >= 0)) collision_type = 2; if ((bola->xspeed > 0) && (bola->yspeed > 0)) collision_type = 3; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Calcula se ocorre colisão unsigned int size_vec_blocos = sizeVector(vec_blocos); unsigned int i; switch(collision_type) { case 0: { // bola a mover-se para NE (nordeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > (block->sprite->x - COLLISION_DETECTION_OFFSET)) && (abs(bola->x) < (block->sprite->x + block->sprite->width)) && (((bola->y + bola->height) > block->sprite->y)) && ((bola->y < (block->sprite->y + block->sprite->height + COLLISION_DETECTION_OFFSET))) ) { //determina o lado em que bateu a bola int dx = abs(bola->x + bola->width - block->sprite->x); int dy = abs(bola->y - (block->sprite->y + block->sprite->height)); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_LEFT_OFFSET_IN_XPM) && (abs(block->sprite->x + block->sprite->width - bola->x) > NAVE_RIGHT_OFFSET_IN_XPM))) { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 1: { // bola a mover-se para NO (noroeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > block->sprite->x) && (abs(bola->x) < (block->sprite->x + block->sprite->width + COLLISION_DETECTION_OFFSET)) && ((bola->y + bola->height) > block->sprite->y) && ((bola->y < (block->sprite->y + block->sprite->height + COLLISION_DETECTION_OFFSET))) ) { //determina o lado em que bateu a bola int dx = abs(block->sprite->x + block->sprite->width - bola->x); int dy = abs(block->sprite->y + block->sprite->height - bola->y); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_RIGHT_OFFSET_IN_XPM) && (abs(bola->x + bola->width - block->sprite->x) > NAVE_LEFT_OFFSET_IN_XPM))) { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 2: { // bola a mover-se para SO (sudueste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > block->sprite->x) && (abs(bola->x) < (block->sprite->x + block->sprite->width + COLLISION_DETECTION_OFFSET)) && ((bola->y + bola->height) > (block->sprite->y - COLLISION_DETECTION_OFFSET)) && (bola->y < (block->sprite->y + block->sprite->height)) ) { //determina o lado em que bateu a bola int dx = abs(block->sprite->x + block->sprite->width - bola->x); int dy = abs(bola->y + bola->height - block->sprite->y); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_RIGHT_OFFSET_IN_XPM) && (abs(bola->x + bola->width - block->sprite->x)) > NAVE_LEFT_OFFSET_IN_XPM)) { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 3: { // bola a mover-se para SE (sodeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > (block->sprite->x - COLLISION_DETECTION_OFFSET)) && (abs(bola->x) < (block->sprite->x + block->sprite->width)) && ((bola->y + bola->height) > (block->sprite->y - COLLISION_DETECTION_OFFSET)) && (bola->y < (block->sprite->y + block->sprite->height)) ) { //determina o lado em que bateu a bola int dx = abs(bola->x + bola->width - block->sprite->x); int dy = abs(bola->y + bola->height - block->sprite->y); //actualiza a velocidade da bola if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_LEFT_OFFSET_IN_XPM) && (abs(block->sprite->x + block->sprite->width - bola->x)) > NAVE_RIGHT_OFFSET_IN_XPM)) { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } } animate_sprite(bola, VIDEO_BASE_ADDRESS); if (blocos_destruidos == (sizeVector(vec_blocos) - 1)) return 1; else if (lives < 0) return 2; else return 0; }
void main() { UBYTE i, j; disable_interrupts(); DISPLAY_OFF; LCDC_REG = 0x67; /* * LCD = Off * WindowBank = 0x9C00 * Window = On * BG Chr = 0x8800 * BG Bank = 0x9800 * OBJ = 8x16 * OBJ = On * BG = On */ doorstate = CLOSED; /* Set palettes */ BGP_REG = OBP0_REG = OBP1_REG = 0xE4U; /* Initialize the background */ set_bkg_data(0xFC, 0x04, std_data); set_bkg_data(0x00, 0x2D, bkg_data); /* * Draw the background * * Width = 0x100 = 0x20 * 8 * Height = 0x100 = 0x20 * 8 */ for(i = 0; i < 32; i+=8) for(j = 0; j < 32; j+=8) set_bkg_tiles(i, j, 8, 8, bkg_tiles); bposx.w = 0; SCX_REG = 0; bposy.w = 0; SCY_REG = 0; bspx.w = 0xFF00; bspy.w = 0x0080; /* Initialize the window */ set_win_data(0x80, 0x21, frame_data); /* * Draw the frame in the window * * Width = 0x80 = 0x10 * 8 * Height = 0x50 = 0x0A * 8 */ set_win_tiles(0, 0, 16, 10, frame_tiles); /* * Draw the door in the window * * Width = 0x60 = 0x20 * 12 * Height = 0x30 = 0x20 * 6 */ set_win_tiles(2, 2, 12, 6, door1_tiles); wposx.b.h = MAXWNDPOSX; wposx.b.l = 0; WX_REG = MAXWNDPOSX; wposy.b.h = MAXWNDPOSY; wposy.b.l = 0; WY_REG = MAXWNDPOSY; wspx.w = 0xFF80; wspy.w = 0xFFC0; /* Initialize the sprite */ set_sprite_data(0x00, 0x1C, earth_data); set_sprite_prop(0, 0x00); set_sprite_prop(1, 0x00); sframe = 0; sposx.w = 0x1000; sposy.w = 0x1000; sspx.w = 0x0040; sspy.w = 0x0040; tile_sprite(); place_sprite(); DISPLAY_ON; enable_interrupts(); while(1) { /* Skip four VBLs (slow down animation) */ for(i = 0; i < 4; i++) wait_vbl_done(); time++; fade(); door(); scroll(); animate_sprite(); i = joypad(); if(i & J_B) { if(i & J_UP) bspy.w -= 0x0010; if(i & J_DOWN) bspy.w += 0x0010; if(i & J_LEFT) bspx.w -= 0x0010; if(i & J_RIGHT) bspx.w += 0x0010; } else if(i & J_A) { if(i & J_UP) wspy.w -= 0x0010; if(i & J_DOWN) wspy.w += 0x0010; if(i & J_LEFT) wspx.w -= 0x0010; if(i & J_RIGHT) wspx.w += 0x0010; } else { if(i & J_SELECT) color = STARTFADE; if(i & J_START) if(doorstate == CLOSED) { doorstate = OPENING; doorpos = 0; } else if(doorstate == OPENED) { doorstate = CLOSING; doorpos = NBDFRAMES; } if(i & J_UP) sspy.w -= 0x0010; if(i & J_DOWN) sspy.w += 0x0010; if(i & J_LEFT) sspx.w -= 0x0010; if(i & J_RIGHT) sspx.w += 0x0010; } } }
int update_sprite(Sprite *sprite){ delete_sprite(sprite); animate_sprite(sprite, h_res, v_res); return 0; }