object_type_t *add_object(coordinate_t coordinate,object_t object,dir_t dir,standpoint_t standpoint,int number,object_type_t *object_type) { object_type_t *ot=object_type; object_type_t *ret=NULL; do{ if(NULL==ot){ break; } switch(object){ case OBJECT_TANK: ret=add_tank(coordinate,dir,standpoint,number,ot); break; case OBJECT_BULLET: ret=add_bullet(coordinate,dir,standpoint,ot); break; case OBJECT_BARRIER: ret=add_barrier(coordinate,ot); break; } }while(0); return ret; }
//posun hry o casovy tik void update_game(float time, int k_up, int k_down, int k_right, int k_left, int k_fire) { //pozadi pro koncovy screen hry if (playerdead) { move_stars(time); move_enemies(time); move_bullets(time); update_particles(time); move_bonuses(time); deathtimer-=time; if ((deathtimer<=0) && k_fire) { //zacatek nove hry finish_game(); init_game(); } } else { handle_levels(); //odecteni casu od casovacu bonusu shieldtimer-=time; canontimer-=time; reload+=time; //ovladani raketky (funkce z main.c) if (k_left) speedx-=time*1300; if (k_right) speedx+=time*1300; if (k_up) speedy+=time*1300; if (k_down) speedy-=time*1300; //strelba mozna jen po specifickem casovem intervalu if (k_fire && ((canontimer>0)?(reload>(0.2/(plevel))):(reload>(0.5/(plevel*0.9))))) { if (canontimer<=0) //strelba zavisla na power levelu add_bullet(posx, posy+50, 0, 200, plevel, 1, 1); else //silenej gun po sebrani zeleneho bonusu add_bullet(posx, posy+50, 0.8*speedx+200*DFRAND*DFRAND*DFRAND, 300+speedy+20*DFRAND, 10*plevel, 1, 1); reload=0; } //aplikace rychlosti raketky na pozici posx+=speedx*time; posy+=speedy*time; //aby raketka brzdila stejne pri ruznem frameratu speedx*=powf(0.02, time); //powf = exponenciela speedy*=powf(0.02, time); //okraje hraciho pole pro raketku if (posx<-225) {posx=-225; speedx=0;} if (posx>225) {posx=225; speedx=0;} if (posy<-335) {posy=-335; speedy=0;} if (posy>-100) {posy=-100; speedy=0;} move_stars(time); move_enemies(time); move_bullets(time); update_particles(time); move_bonuses(time); } }
static DskJsonValue * create_user_update (User *user) { Game *game = user->base.game; /* width/height in various units, rounded up */ unsigned tile_width = (user->width + TILE_SIZE - 1) / TILE_SIZE; unsigned tile_height = (user->height + TILE_SIZE - 1) / TILE_SIZE; unsigned cell_width = (tile_width + CELL_SIZE * 2 - 2) / CELL_SIZE; unsigned cell_height = (tile_height + CELL_SIZE * 2 - 2) / CELL_SIZE; /* left/upper corner, rounded down */ int min_tile_x = user->base.x - (tile_width+1) / 2; int min_tile_y = user->base.y - (tile_height+1) / 2; int min_cell_x = int_div (min_tile_x, CELL_SIZE); int min_cell_y = int_div (min_tile_y, CELL_SIZE); unsigned alloced = 16; DskJsonValue **elements = dsk_malloc (sizeof (DskJsonValue *) * alloced); unsigned n_elements = 0; unsigned x, y; for (x = 0; x < cell_width; x++) for (y = 0; y < cell_height; y++) { int ucx = x + min_cell_x; /* un-wrapped x, y */ int ucy = y + min_cell_y; int px = (ucx * CELL_SIZE - user->base.x) * TILE_SIZE + user->width / 2 - TILE_SIZE / 2; int py = (ucy * CELL_SIZE - user->base.y) * TILE_SIZE + user->height / 2 - TILE_SIZE / 2; unsigned cx, cy; Cell *cell; /* deal with wrapping (or not) */ if (ucx < 0) { if (!game->wrap) continue; cx = ucx + game->universe_width; } else if ((unsigned) ucx >= game->universe_width) { cx = ucx; if (game->wrap) cx -= game->universe_width; } else cx = ucx; if (ucy < 0) { if (!game->wrap) continue; cy = ucy + game->universe_height; } else if ((unsigned) ucy >= game->universe_height) { cy = ucy; if (game->wrap) cy -= game->universe_height; } else cy = ucy; /* render walls */ if (cy < game->universe_height && cx <= game->universe_width && game->v_walls[cx + cy * game->universe_width]) { /* render vertical wall */ add_wall (&n_elements, &elements, &alloced, px, py, TILE_SIZE, TILE_SIZE * (CELL_SIZE+1)); } if (cy <= game->universe_height && cx < game->universe_width && game->h_walls[cx + cy * game->universe_width]) { /* render horizontal wall */ add_wall (&n_elements, &elements, &alloced, px, py, TILE_SIZE * (CELL_SIZE+1), TILE_SIZE); } if (cx >= game->universe_width || cy >= game->universe_height) continue; cell = game->cells + (game->universe_width * cy + cx); /* render bullets */ Object *object; for (object = cell->objects[OBJECT_TYPE_BULLET]; object; object = object->next_in_cell) { int bx = px + (object->x - cx * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; int by = py + (object->y - cy * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; add_bullet (&n_elements, &elements, &alloced, bx, by); } /* render dudes */ for (object = cell->objects[OBJECT_TYPE_USER]; object; object = object->next_in_cell) { int bx = px + (object->x - cx * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; int by = py + (object->y - cy * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; add_user (&n_elements, &elements, &alloced, bx, by, user == (User*) object); } /* render bad guys */ for (object = cell->objects[OBJECT_TYPE_ENEMY]; object; object = object->next_in_cell) { int bx = px + (object->x - cx * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; int by = py + (object->y - cy * CELL_SIZE) * TILE_SIZE + TILE_SIZE / 2; add_enemy (&n_elements, &elements, &alloced, bx, by); } /* render generators */ if (cell->generator) { int bx = px + (cell->generator->x - cx * CELL_SIZE) * TILE_SIZE + TILE_SIZE; int by = py + (cell->generator->y - cy * CELL_SIZE) * TILE_SIZE + TILE_SIZE; add_generator (&n_elements, &elements, &alloced, bx, by, user->base.game->latest_update); } } DskJsonValue *rv; rv = dsk_json_value_new_array (n_elements, elements); dsk_free (elements); user->last_update = game->latest_update; return rv; }
int move_player1(ENTITY *e,int frame_time) { int printinfo=FALSE; if(e==0) return 0; if(key_state('p')){ switch(e->state_action){ default: e->state_action=S_ACTION_PAUSE1; break; case S_ACTION_PAUSE3: case S_ACTION_PAUSE2: e->state_action=S_ACTION_PAUSE3; break; } }else{ switch(e->state_action){ default: e->state_action=0; break; case S_ACTION_PAUSE2: case S_ACTION_PAUSE1: e->state_action=S_ACTION_PAUSE2; break; } } if(e->state_action==S_ACTION_PAUSE1 || e->state_action==S_ACTION_PAUSE2) return 0; if(key_state(VK_LEFT)){ //printf("delta=%i\n",delta); e->rotx=-1; e->speedx=frame_time/2; } else if(key_state(VK_RIGHT)){ e->rotx=1; e->speedx=frame_time/2; } else{ e->speedx-=frame_time; } if(key_state(VK_DOWN)){ e->posz+=100; printinfo=TRUE; } if(key_state(VK_UP)){ e->posz-=100; printinfo=TRUE; } if(key_state(VK_CONTROL)){ e->speedy=frame_time; } else{ e->speedy-=frame_time/6; } if(key_state(VK_MENU)){ int s[3]={0,0,0},p[3]={0,0,0}; if(e->rotx<0) s[0]=-2; else s[0]=2; p[0]=e->posx; p[1]=e->posy; p[2]=e->posz; if(e->state_action==0){ e->state_action=S_ACTION_FIRE; e->stime_action=0; add_bullet(e,s,p); } printf("menu\n"); } switch(e->state_action){ case S_ACTION_FIRE: e->stime_action+=frame_time; if(e->stime_action>250) e->state_action=0; break; } if(e->speedx>100) e->speedx=100; else if(e->speedx<0) e->speedx=0; if(e->speedy>100) e->speedy=100; else if(e->speedy<-100) e->speedy=-100; e->posx+=e->speedx*e->rotx; e->posy+=e->speedy; //if(posz>100) // posz=0; //else if(posz<0) // posz=0; if(e->posx>500) e->posx=500; else if(e->posx<-500) e->posx=-500; if(e->posy>500) e->posy=500; else if(e->posy<-100){ e->posy=-100; e->speedy=0; } if(e->speedx==0) e->frame=0; else{ e->time+=e->speedx; if(e->time>12){ e->time=0; e->frame++; if(e->frame>=(e->tcols*e->trows)) e->frame=0; } } // if(e->speedx!=0 || e->speedy!=0 || e->speedz!=0 || printinfo) // printf("sx=% 5.1f sy=% 5.1f sz=% 5.1f px=% 5.1f py=% 5.1f pz=% 5.1f\n",e->speedx,e->speedy,e->speedz,e->posx,e->posy,e->posz); return 0; }
void run_play() { sp1_ClearRectInv(&cr, BRIGHT | INK_WHITE | PAPER_BLACK, 32, SP1_RFLAG_TILE | SP1_RFLAG_COLOUR); sp1_UpdateNow(); sp1_SetPrintPos(&ps0, 0, 0); sp1_PrintString(&ps0, ptiles); // setup the game sprites[PLAYER].x = 15 * 8; sprites[PLAYER].y = 20 * 8; sprites[PLAYER].frame = 0; sprites[PLAYER].delay = 0; sprites[PLAYER].sprite = player; update_player(); horde_count = 0; wave_delay = 0; wave = 0; score = 0; lives = 3; invulnerable = 0; update_score(); while(1) { // TODO: pause/resume if (in_inkey() == 12) // exit current game break; key = (joyfunc)(&joy_k); if (key & IN_STICK_LEFT && !(key & IN_STICK_RIGHT)) { if (sprites[PLAYER].x - 4 > ORIGINX) { sprites[PLAYER].x -= 4; sprites[PLAYER].frame = 2; sprites[PLAYER].delay = 4; update_player(); } } if (key & IN_STICK_RIGHT && !(key & IN_STICK_LEFT)) { if (sprites[PLAYER].x + 16 + 8 + 4 < WIDTH) { sprites[PLAYER].x += 4; sprites[PLAYER].frame = 1; sprites[PLAYER].delay = 4; update_player(); } } if (cooldown > 0) --cooldown; if (key & IN_STICK_FIRE && !cooldown) { // fire rate cooldown = 10; add_bullet(ST_BULLET, sprites[PLAYER].x + 4, sprites[PLAYER].y - 2); playfx(FX_FIRE); } // change the frame to normal? if (sprites[PLAYER].delay) { if (!--sprites[PLAYER].delay) { sprites[PLAYER].frame = 0; update_player(); } } update_horde(); update_sprites(); update_script(); if (invulnerable > 0) { // will be 0, but in case of "the unexpected" if (lives <= 0) { // GAME OVER // some noise playfx(FX_EXPLO); playfx(FX_EXPLO); playfx(FX_EXPLO); // we don't want the player to miss the game over music in_wait_nokey(); sp1_SetPrintPos(&ps0, 11, 8); sp1_PrintString(&ps0, "\x14\x46" "G A M E O V E R"); sp1_UpdateNow(); dzx7_standard(song2, TEMPMEM); ntropic_play(TEMPMEM, 0); for (i = 0; i < 32; ++i) wait(); // leave the game break; } --invulnerable; update_player(); } wait(); intrinsic_halt(); // inline halt without impeding optimizer sp1_UpdateNow(); } destroy_type_sprite(ST_ALL); collect_sprites(); // the player sprite is never destroyed, so hide it sp1_MoveSprAbs(sprites[PLAYER].s, &cr, NULL, 0, 34, 0, 0); sp1_UpdateNow(); sp1_ClearRectInv(&cr, BRIGHT | INK_BLACK | PAPER_BLACK, 32, SP1_RFLAG_TILE | SP1_RFLAG_COLOUR); sp1_UpdateNow(); }
void update_sprites(void) { for (sp_iter = sp_used; sp_iter; sp_iter = sp_iter->n) { if (!sp_iter->alive) continue; switch(sp_iter->type) { default: break; case ST_BULLET: sp_iter->x += sp_iter->ix; sp_iter->y += sp_iter->iy; // out of screen if(sp_iter->x < ORIGINX || sp_iter->x > WIDTH || sp_iter->y + 8 < ORIGINY || sp_iter->y > HEIGHT) { remove_sprite(sp_iter); // no drawing required break; } // enemy check for (sp_iter2 = sp_used; sp_iter2; sp_iter2 = sp_iter2->n) if (sp_iter2->type == ST_ENEMY && sp_iter2->alive && sp_iter->x + 4 < sp_iter2->x + 16 && sp_iter2->x < sp_iter->x + 4 && sp_iter->y + 4 < sp_iter2->y + 16 && sp_iter2->y < sp_iter->y + 4) { score += 25; if (score > hi_score) hi_score = score; update_score(); // convert into an explosion sp_iter2->sprite = explosion; sp_iter2->frame = 0; sp_iter2->delay = 0; sp_iter2->type = ST_EXPLO; playfx(FX_EXPLO); // remove the bullet remove_sprite(sp_iter); // one less enemy --horde_count; } // draw only if it didn't hit anything if (sp_iter->alive) sp1_MoveSprPix(sp_iter->s, &cr, sp_iter->sprite, 8 + sp_iter->x, 8 + sp_iter->y); break; case ST_EBULLET: sp_iter->y += sp_iter->iy; // out of screen if (sp_iter->y > HEIGHT) { remove_sprite(sp_iter); // no drawing required break; } // player check if (!invulnerable && sp_iter->x + 4 < sprites[PLAYER].x + 16 && sprites[PLAYER].x < sp_iter->x + 4 && sp_iter->y + 4 < sprites[PLAYER].y + 16 && sprites[PLAYER].y < sp_iter->y + 4) { // convert into an explosion sp_iter->sprite = impact + 2 * 4 * 8; sp_iter->frame = 0; sp_iter->delay = 0; sp_iter->type = ST_HIT; playfx(FX_EXPLO); if (!invulnerable) { // we hit the player, kill him! --lives; update_score(); invulnerable = 10; } continue; } sp1_MoveSprPix(sp_iter->s, &cr, sp_iter->sprite, 8 + sp_iter->x, 8 + sp_iter->y); break; case ST_ENEMY: if (!horde_delay) { if (!horde_iy) sp_iter->x += horde_ix; else sp_iter->y += horde_iy; // change frame sp_iter->frame = !sp_iter->frame; if (sp_iter->sprite == bomber) { if (!sp_iter->delay--) { sp_iter->delay = 15 + rand() % 15; add_bullet(ST_EBULLET, sp_iter->x + 4, sp_iter->y + 16); } } } // player check if (!invulnerable && sp_iter->x < sprites[PLAYER].x + 16 && sprites[PLAYER].x < sp_iter->x + 16 && sp_iter->y < sprites[PLAYER].y + 16 && sprites[PLAYER].y < sp_iter->y + 16) { // convert into an explosion sp_iter->sprite = explosion; sp_iter->frame = 0; sp_iter->delay = 0; sp_iter->type = ST_EXPLO; // one less enemy --horde_count; playfx(FX_EXPLO); if (!invulnerable) { // we hit the player, kill him! --lives; update_score(); invulnerable = 10; } continue; } // out of screen? if (sp_iter->y > HEIGHT) { // one less enemy --horde_count; // repeat the wave not_clean = 1; remove_sprite(sp_iter); // no drawing required break; } sp1_MoveSprPix(sp_iter->s, &cr, sp_iter->sprite + sp_iter->frame * 8 * 12, 8 + sp_iter->x, 8 + sp_iter->y); break; case ST_EXPLO: // first frame must be half frame longer if (sp_iter->delay < 2) sp_iter->delay++; else { sp_iter->delay = 1; sp_iter->frame++; if (sp_iter->frame == 3) { // we're done! remove_sprite(sp_iter); break; } } sp1_MoveSprPix(sp_iter->s, &cr, sp_iter->sprite + sp_iter->frame * 8 * 12 , 8 + sp_iter->x, 8 + sp_iter->y); break; case ST_HIT: // first frame must be half frame longer if (sp_iter->delay < 2) sp_iter->delay++; else { sp_iter->delay = 0; sp_iter->frame++; if (sp_iter->frame == 2) { // we're done! remove_sprite(sp_iter); break; } } sp1_MoveSprPix(sp_iter->s, &cr, sp_iter->sprite + sp_iter->frame * 4 * 8 , 8 + sp_iter->x, 8 + sp_iter->y); break; } } // update the lists collect_sprites(); }
void hit_task_fire_weapon(hitbox_t shooter, weapontype_t w){ uint16_t start_x=0, start_y=0; bullet_t b; //Définit la position de départ selon l'emplacement du tireur if(w == BOMB){ //Position en bas au milieu de l'invader qui tire start_x = shooter.x + shooter.width/2; start_y = shooter.y+shooter.height+1; } else{ //Position en haut au milieu du vaisseau start_x = shooter.x + shooter.width/2; start_y = shooter.y-1; } //Tir de la bullet switch(w){ case BOMB: b.weapon = &weapons[BOMB]; b.hitbox.x = start_x-BOMB_WIDTH/2; b.hitbox.y = start_y; b.hitbox.width = BOMB_WIDTH; b.hitbox.height = BOMB_HEIGHT; b.hitbox.bitmap = (uint16_t *)bmp_bomb; break; case GUN: b.weapon = &weapons[GUN]; b.hitbox.x = start_x-GUN_WIDTH/2; b.hitbox.y = start_y-GUN_HEIGHT; b.hitbox.width = GUN_WIDTH; b.hitbox.height = GUN_HEIGHT; b.hitbox.bitmap = (uint16_t *)bmp_gun; break; case RAIL: b.weapon = &weapons[RAIL]; b.hitbox.x = start_x-RAIL_WIDTH/2; b.hitbox.y = GAME_ZONE_Y_MIN; b.hitbox.width = RAIL_WIDTH; b.hitbox.height = start_y - GAME_ZONE_Y_MIN; b.hitbox.bitmap = (uint16_t *)bmp_rail; break; case ROCKET: b.weapon = &weapons[ROCKET]; b.hitbox.x = start_x-ROCKET_WIDTH/2; b.hitbox.y = start_y-ROCKET_HEIGHT; b.hitbox.width = ROCKET_WIDTH; b.hitbox.height = ROCKET_HEIGHT; b.hitbox.bitmap = (uint16_t *)bmp_rocket; break; case WAVE: b.weapon = &weapons[WAVE]; b.hitbox.x = 0; b.hitbox.y = start_y-WAVE_HEIGHT; b.hitbox.width = WAVE_WIDTH; b.hitbox.height = WAVE_HEIGHT; b.hitbox.bitmap = (uint16_t *)bmp_wave; break; } //ajoute la bullet à la liste des bullets en jeu add_bullet(b); }//fire_weapon()
void update_explorer(Explorer& obj) { char i, vx, vy; short wx, wy, ww, wh; short nvx, nvy; // Game over if button pressed while dead if(!obj.active) { if((B_PRESSED || A_PRESSED) && !quitGame) { doGameOver(); } return; } // Add health from rolling health if(rollingHealth > 0) { rollingHealth -= 10; obj.health += 10; if(obj.health > 1000) { obj.health = 1000; rollingHealth = 0; } } // Decrease health if(obj.nextHealthDecrease <= 0) { obj.nextHealthDecrease = 5; damage_explorer(obj, 1); } obj.nextHealthDecrease--; // Update animation if(LEFT_DOWN || RIGHT_DOWN || UP_DOWN || DOWN_DOWN) { obj.frameTime ++; if(obj.frameTime > 8) { obj.frame = !obj.frame; obj.frameTime = 0; } } else { // If facing left or right, set sprite to standing if(obj.direction == FACE_LEFT || obj.direction == FACE_RIGHT) obj.frame = true; } // Get horizontal velocity if(RIGHT_DOWN) { vx = 1; obj.direction = FACE_RIGHT; } else if(LEFT_DOWN) { vx = -1; obj.direction = FACE_LEFT; } else { vx = 0; } // Update horizontal position obj.x += vx; obj.x = (obj.x + 8 > gamew) ? gamew - 8 : obj.x; obj.x = (obj.x < 0) ? 0 : obj.x; // WALL COLLISION for(i = 0; i<numWalls; ++i) { if(!walls[i].active) continue; wx = walls[i].x*8; wy = walls[i].y*8; ww = walls[i].w*8; wh = walls[i].h*8; collideSpriteWall(obj.x, obj.y, true, vx, wx, wy, ww, wh); } // SPAWNER COLLISION for(i = 0; i<numSpawners; ++i) { if(!spawners[i].active) continue; wx = spawners[i].x*8; wy = spawners[i].y*8; collideSpriteSprite(obj.x, obj.y, true, vx, wx, wy); } // BADGUY COLLISION for(i = 0; i<numBadguys; ++i) { if(!badguys[i].active) continue; wx = badguys[i].x; wy = badguys[i].y; if(collideSpriteSprite(obj.x, obj.y, true, vx, wx, wy)) { damage_explorer(p1, 1); } } // Get vertical velocity if(DOWN_DOWN) { vy = 1; obj.direction = FACE_DOWN; } else if(UP_DOWN) { vy = -1; obj.direction = FACE_UP; } else { vy = 0; } // Update vertical position obj.y += vy; obj.y = (obj.y + 8 > gameh) ? gameh - 8 : obj.y; obj.y = (obj.y < 0) ? 0 : obj.y; // WALL COLLISION for(i = 0; i<numWalls; ++i) { if(!walls[i].active) continue; wx = walls[i].x*8; wy = walls[i].y*8; ww = walls[i].w*8; wh = walls[i].h*8; collideSpriteWall(obj.x, obj.y, false, vy, wx, wy, ww, wh); } // SPAWNER COLLISION for(i = 0; i<numSpawners; ++i) { if(!spawners[i].active) continue; wx = spawners[i].x*8; wy = spawners[i].y*8; collideSpriteSprite(obj.x, obj.y, false, vy, wx, wy); } // BADGUY COLLISION for(i = 0; i<numBadguys; ++i) { if(!badguys[i].active) continue; wx = badguys[i].x; wy = badguys[i].y; if(collideSpriteSprite(obj.x, obj.y, false, vy, wx, wy)) { damage_explorer(p1, 1); } } // KEY COLLISION for(i = 0; i<numKeys; ++i) { if(!keys[i].active) continue; wx = keys[i].x * 8; wy = keys[i].y * 8; if(intersectSpriteSprite(obj.x, obj.y, wx, wy)) { activate_key(keys[i]); } } // EXIT COLLISION for(i = 0; i<numExits; ++i) { if(!exits[i].active) continue; wx = exits[i].x * 8; wy = exits[i].y * 8; if(intersectSpriteSprite(obj.x, obj.y, wx, wy)) { activate_exit(exits[i]); } } // TREASURE COLLISION for(i = 0; i<numTreasures; ++i) { if(!treasures[i].active) continue; wx = treasures[i].x * 8; wy = treasures[i].y * 8; if(intersectSpriteSprite(obj.x, obj.y, wx, wy)) { activate_treasure(treasures[i]); } } // Player shooting if(A_PRESSED) { autoFireTime = 8; nvx = (obj.direction == FACE_LEFT || LEFT_DOWN) ? -2 : 0; nvx = (obj.direction == FACE_RIGHT || RIGHT_DOWN) ? 2 : nvx; nvy = (obj.direction == FACE_UP || UP_DOWN) ? -2 : 0; nvy = (obj.direction == FACE_DOWN || DOWN_DOWN) ? 2 : nvy; add_bullet(obj.x+3, obj.y+3, nvx+vx, nvy+vy); } // Update Camera scrollx = 64 - obj.x; scrolly = 32 - obj.y; }