space_pirate space_pirate_update(space_pirate p, whitgl_fvec target) { if(!p.e.active) return p; whitgl_fvec diff = whitgl_fvec_sub(target, p.e.pos); whitgl_float target_angle = whitgl_fvec_to_angle(diff)+whitgl_pi/2; whitgl_float ang_diff = whitgl_fwrap(target_angle-p.e.angle, -whitgl_pi, whitgl_pi); whitgl_bool r, l; if(ang_diff > 0.2) { r = true; l = false; } else if(ang_diff < -0.2) { r = false; l = true; } else { l = true; r = true; } if(l&&r) { whitgl_fvec impulse = {0,-0.002}; impulse = whitgl_rotate_point_around_point(impulse, whitgl_fvec_zero, p.e.angle); p.speed = whitgl_fvec_add(p.speed, impulse); } if(l) p.angle_speed = whitgl_fclamp(p.angle_speed-0.01, -0.2, 0.2); if(r) p.angle_speed = whitgl_fclamp(p.angle_speed+0.01, -0.2, 0.2); p.angle_speed = p.angle_speed*0.9; p.e.angle = whitgl_fwrap(p.e.angle+p.angle_speed, 0, whitgl_pi*2); p.e.pos = whitgl_fvec_add(p.e.pos, p.speed); p.speed = whitgl_fvec_interpolate(p.speed, whitgl_fvec_zero, 0.01); whitgl_int i; for(i=0; i<2; i++) { whitgl_bool on = i == 0 ? r : l; // if(on && !p.was_on[i]) // whitgl_sound_play(i == 0 ? SOUND_THRUST_L : SOUND_THRUST_R, 1.0); // p.was_on[i] = on; whitgl_float target = on ? 1 : 0; p.engine_thrust[i] = p.engine_thrust[i]*0.6 + 0.4*target; } return p; }
whitgl_bool game_snake_collide(game_snake snake, whitgl_faabb box) { whitgl_int j; for(j=0; j<snake.size; j++) { whitgl_faabb snake_col; snake_col.a = whitgl_ivec_to_fvec(snake.pos[j]); snake_col.b = whitgl_fvec_add(snake_col.a, whitgl_fvec_val(1)); if(whitgl_faabb_intersects(snake_col, box)) return true; } return false; }
game_game game_update(game_game game, const game_map* map, whitgl_ivec screen_size) { game.snake = game_snake_update(game.snake, map); whitgl_int i, j; for(i=0; i<NUM_WALKERS; i++) game.walkers[i] = game_walker_update(game.walkers[i], &game, map); for(i=0; i<NUM_BLOOD; i++) game.blood[i] = game_blood_update(game.blood[i], map); for(i=0; i<NUM_SHOTS; i++) game.shots[i] = game_shot_update(game.shots[i], map); for(i=0; i<NUM_PICKUPS; i++) game.pickups[i] = game_pickup_update(game.pickups[i]); whitgl_fvec target = _game_camera_target(game, screen_size); game.fcamera = whitgl_fvec_interpolate(game.fcamera, whitgl_fvec_inverse(target), 0.08); whitgl_fvec shake = {(whitgl_randfloat()-0.5)*game.camera_shake*16, (whitgl_randfloat()-0.5)*game.camera_shake*16}; game.camera = whitgl_fvec_to_ivec(whitgl_fvec_add(game.fcamera, shake)); game.camera_shake -= 0.05; if(game.camera_shake < 0) game.camera_shake = 0; for(i=0; i<NUM_WALKERS; i++) { if(!game.walkers[i].active) continue; whitgl_faabb walk_col = game_walker_collider(game.walkers[i]); if(!game_snake_collide(game.snake, walk_col)) continue; game.walkers[i].active = false; game.snake.size++; game.snake.old_pos = game.snake.pos[game.snake.size]; whitgl_sound_play(SOUND_SPLAT00+whitgl_randint(6), whitgl_randfloat()/5+0.9); whitgl_fvec speed = whitgl_fvec_scale(whitgl_facing_to_fvec(game.snake.dir), whitgl_fvec_val(0.3)); game = _game_spawn_blood(game, game.walkers[i].pos, speed); game.camera_shake += 0.75; } for(i=0; i<NUM_SHOTS; i++) { if(!game.shots[i].active) continue; whitgl_faabb shot_col = game_shot_collider(game.shots[i]); if(!game_map_collide(map, shot_col, false)) continue; game.shots[i].active = false; whitgl_sound_play(SOUND_GLANCE, whitgl_randfloat()*0.5+0.75); game.camera_shake += 0.2; } for(i=0; i<NUM_SHOTS; i++) { if(!game.shots[i].active) continue; whitgl_faabb shot_col = game_shot_collider(game.shots[i]); if(!game_snake_collide(game.snake, shot_col)) continue; game.shots[i].active = false; if(game.snake.size > 3) game.snake.size--; game.snake.old_pos = game.snake.pos[game.snake.size]; whitgl_sound_play(SOUND_HURT00+whitgl_randint(4), whitgl_randfloat()*0.5+0.75); game = _game_spawn_blood(game, game.shots[i].pos, game.shots[i].speed); game.camera_shake += 1; } for(i=0; i<NUM_WALKERS; i++) { if(!game.walkers[i].active) continue; for(j=0; j<NUM_SHOTS; j++) { if(!game.shots[j].active) continue; if(game.shots[j].owner == i) continue; whitgl_faabb shot_col = game_shot_collider(game.shots[j]); whitgl_faabb walk_col = game_walker_collider(game.walkers[i]); if(!whitgl_faabb_intersects(shot_col, walk_col)) continue; game.shots[j].active = false; game.walkers[i].active = false; whitgl_sound_play(SOUND_HIT, whitgl_randfloat()*0.5+0.75); game = _game_spawn_blood(game, game.shots[j].pos, game.shots[j].speed); game.camera_shake += 0.5; } } for(i=0; i<NUM_WALKERS; i++) { if(!game.walkers[i].active) continue; if(!game.walkers[i].shooting) continue; game.shots[game.next_shot] = game_shot_spawn(game.walkers[i].pos, game.walkers[i].speed < 0, i); game.next_shot = whitgl_iwrap(game.next_shot+1, 0, NUM_SHOTS); whitgl_sound_play(SOUND_LASER, whitgl_randfloat()*0.5+0.75); game.camera_shake += 0.2; } for(i=0; i<NUM_PICKUPS; i++) { if(!game.pickups[i].active) continue; if(game.pickups[i].picked) continue; whitgl_faabb pickup_col = game_pickup_collider(game.pickups[i]); if(!game_snake_collide(game.snake, pickup_col)) continue; game.pickups[i] = game_pickup_picked(game.pickups[i]); game.camera_shake += 0.1; game.score++; } if(whitgl_randfloat() > 1-game.snake.size*0.005) { whitgl_int segment = whitgl_randint(game.snake.size); whitgl_fvec spawn_point = {game.snake.pos[segment].x+0.5,game.snake.pos[segment].y+0.5}; whitgl_fvec speed = whitgl_fvec_zero; speed.y -= 0.3; game.blood[game.next_blood] = game_blood_spawn(spawn_point, speed); game.next_blood = whitgl_iwrap(game.next_blood+1, 0, NUM_BLOOD); } game.time_taken += 1.0/60.0; return game; }