static void jarhead_update(struct foe_jarhead *f) { switch (f->state) { case JARHEAD_ALIVE: { vector2 *dir = &f->common.dir; vector2 s = ship.pos; vec2_sub_from(&s, &f->common.pos); vec2_mul_scalar(&s, .0003f); vec2_add_to(dir, &s); foe_common_update(&f->common); hit_ship(&f->common.pos, foe_data[f->common.type].radius); vec2_clamp_length(dir, foe_data[f->common.type].max_speed); } break; case JARHEAD_EXPLODING: if (--f->ttl <= 0) { foe_common_gen_explosion(&f->common, 1.f); kill_foe(&f->common); } else { vector2 *dir = &f->common.dir; foe_common_update(&f->common); /* spiral */ vec2_rotate(dir, f->spin_angle); vec2_add_to(dir, &f->hit_dir); vec2_clamp_length(dir, JARHEAD_MAX_EXPLODING_SPEED); /* trail */ foe_add_trail(&f->common.pos, &f->common.dir, PAL_YELLOW); } break; default: assert(0); } }
int game_update(int mousedx, int mousedy) { const uint8_t* keys = SDL_GetKeyboardState(NULL); double rot = mousedx*PLAYER_ROTSPEED; if (keys[SDL_SCANCODE_LEFT]) rot -= 10*PLAYER_ROTSPEED; if (keys[SDL_SCANCODE_RIGHT]) rot += 10*PLAYER_ROTSPEED; vec2_rotate(&player.dir, rot, &player.dir); vec2_t dir = {0, 0}; double spd = PLAYER_MOVESPEED; if (keys[SDL_SCANCODE_LCTRL]) spd *= .1; if (keys[SDL_SCANCODE_LSHIFT]) spd *= 10.; vec2_t dirCrossed = {player.dir.y, -player.dir.x}; if (keys[SDL_SCANCODE_W] || keys[SDL_SCANCODE_UP]) vec2_add(&dir, &player.dir, &dir); if (keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_DOWN]) vec2_addScale(&dir, &player.dir, -1, &dir); if (keys[SDL_SCANCODE_A]) vec2_addScale(&dir, &dirCrossed, -1, &dir); if (keys[SDL_SCANCODE_D]) vec2_add(&dir, &dirCrossed, &dir); if (vec2_lengthSq(&dir) > 0.00001) { vec2_normalize(&dir, &dir); camera_t cam = player; cam.dir = dir; raycast_travel(&cam, spd, &m); player.pos = cam.pos; } return keys[SDL_SCANCODE_ESCAPE]; }
static void ninja_update(struct foe_ninja *f) { switch (f->state) { case NINJA_ALIVE: evolved_duck_update(&f->evolved_duck); break; case NINJA_RECOVERING: if (--f->recover_ttl <= 0) { /* THIS DOESN'T WORK! */ float a = (-f->common.angle + 270.f + 180.f)* 2.f*M_PI/360.f; f->common.dir.x = .01f*cos(a); f->common.dir.y = .01f*sin(a); f->evolved_duck.num_trail_segs = 0; f->state = NINJA_ALIVE; } else { vector2 *dir = &f->common.dir; foe_common_update(&f->common); vec2_rotate(dir, f->spin_angle); vec2_add_to(dir, &f->hit_dir); vec2_clamp_length(dir, JARHEAD_MAX_EXPLODING_SPEED); foe_add_trail(&f->common.pos, &f->common.dir, PAL_GREEN); f->common.angle_speed *= .8f; } break; default: assert(0); } }
static void evolved_duck_update(struct foe_evolved_duck *f) { vector2 d, od, t; float r; int ship_is_behind; foe_common_update(&f->common); if (foe_bounced) { f->num_trail_segs = 0; } else { if (f->num_trail_segs < MAX_TRAIL_SEGS) f->num_trail_segs++; if (++f->trail_seg_head >= MAX_TRAIL_SEGS) f->trail_seg_head = 0; f->trail_seg[f->trail_seg_head] = f->common.pos; } hit_ship(&f->common.pos, foe_data[f->common.type].radius); od.x = ship.pos.x - f->common.pos.x; od.y = ship.pos.y - f->common.pos.y; vec2_normalize(&od); t.x = -f->common.dir.y; t.y = f->common.dir.x; ship_is_behind = vec2_dot_product(&od, &t) > 0; /* accelerate if behind ship, brake otherwise */ if (ship_is_behind) vec2_mul_scalar(&f->common.dir, .99f); else vec2_mul_scalar(&f->common.dir, 1.2f); /* turn towards ship */ d.x = -(ship.pos.y - f->common.pos.y); d.y = ship.pos.x - f->common.pos.x; vec2_normalize(&d); r = 1.6f*vec2_dot_product(&d, &f->common.dir); if (r < 0) { if (ship_is_behind) r = -f->max_turn_angle; else { if (r < -f->max_turn_angle) r = -f->max_turn_angle; } } else { if (ship_is_behind) { r = f->max_turn_angle; } else { if (r > f->max_turn_angle) r = f->max_turn_angle; } } vec2_rotate(&f->common.dir, r); vec2_clamp_length(&f->common.dir, foe_data[f->common.type].max_speed); }