Пример #1
0
static void
sitting_duck_update(struct foe_sitting_duck *f)
{
	foe_common_update(&f->common);
	hit_ship(&f->common.pos, foe_data[f->common.type].radius);
	vec2_clamp_length(&f->common.dir, foe_data[f->common.type].max_speed);
}
Пример #2
0
/* Task c: Ask coordinates (two integers) from user, and shoot the location.
 * Returns -1 if user gave invalid input or coordinates, 0 if there was no ship
 * at the given location; and 1 if there was a ship hit at the location.
 */
int shoot(void)
{
    int x, y;
    scanf("%d %d", &x, &y);
    if (x < 0 || x >= xsize || y < 0 || y >= ysize) return -1;
    checked(x, y);
    if (is_ship(x, y) == '+') {
        hit_ship(x, y);
        return 1;
    }
    return 0;
}
Пример #3
0
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);
	}
}
Пример #4
0
static void
brute_update(struct foe_brute *f)
{
	vector2 *dir = &f->common.dir;
	vector2 s = ship.pos;
	vec2_sub_from(&s, &f->common.pos);
	vec2_mul_scalar(&s, .004f);
	vec2_add_to(dir, &s);
	foe_common_update(&f->common);
	hit_ship(&f->common.pos, foe_data[FOE_BRUTE].radius);

	if (vec2_length(dir) > foe_data[FOE_BRUTE].max_speed);
		vec2_mul_scalar(dir, .7);

	if (f->common.angle_speed > BRUTE_MAX_ANGLE_SPEED)
		f->common.angle_speed *= .7;

	if (brute_is_recovering(f))
		foe_add_trail(&f->common.pos, &f->common.dir, PAL_YELLOW);
}
Пример #5
0
/* Task c: Ask coordinates (two integers) from user, and shoot the location.
 * Returns -1 if user gave invalid input or coordinates, 0 if there was no ship
 * at the given location; and 1 if there was a ship hit at the location.
 */
int shoot(void)
{
	unsigned int xpos, ypos;
	char space;
	int ret_x = scanf("%u", &xpos);
	int ret_space = scanf("%c", &space);
	int ret_y = scanf("%u", &ypos);

	if (ret_x == 0 || ret_y == 0 || ret_space == 0) {
		return -1;
	}

	if (xpos >= xsize || ypos >= ysize) {
		return -1;
	}

	checked(xpos, ypos);
	if (is_ship(xpos, ypos) == '+') {
		hit_ship(xpos, ypos);
		return 1;
	}

	return 0;
}
Пример #6
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);
}
Пример #7
0
static void
update_inner_state(void)
{
	static int prev_level_tics;

	inner_state.tics++;

	switch (inner_state.state) {
		case IS_WAVE_TITLE:
			if (inner_state.tics >= WAVE_TITLE_TICS) {
				set_inner_state(IS_IN_GAME);
				/* set_inner_state(IS_PRE_WAVE_CLEARED); */
			} else {
				if (inner_state.tics == WAVE_TITLE_TICS/2) {
					if (!ship.is_alive)
						spawn_new_ship();
					else
						reset_ship();
				}
			}
			break;

		case IS_IN_GAME:
			level_stat_counters.tics++;
			game_stat_counters.tics++;

			if (gc.tics_remaining <= 0) {
				/* boom. */
				hit_ship(&ship.pos, 1.f);
				trigger_game_over();
			} else {
				gc.tics_remaining--;

				if (!ship.is_alive) {
					prev_level_tics = inner_state.tics;
					set_inner_state(IS_RESPAWNING_SHIP);
				} else if (!gc.foes_left) {
					level_stat_counters.waves++;
					game_stat_counters.waves++;
					if (gc.tics_remaining > TIME_BONUS_MIN_TICS)
						gc.score += gc.tics_remaining*TIME_BONUS_PER_TIC;
					set_inner_state(IS_PRE_WAVE_CLEARED);
				} else {
					spawn_new_foes();
				}
			}
			break;

		case IS_PRE_WAVE_CLEARED:
			if (inner_state.tics >= PRE_WAVE_CLEARED_TICS) {
				gen_ship_implosion();
				reset_powerups();
				reset_missiles();
				reset_bombs();
				reset_lasers();
				vec2_set(&ship.pos, 0.f, 0.f); /* HACK */
				play_fx(FX_WAVE_TRANSITION);
				set_inner_state(IS_WAVE_CLEARED);
			}
			break;

		case IS_RESPAWNING_SHIP:
			if (inner_state.tics >= TICS_UNTIL_RESPAWN) {
				if (gc.ships_left) {
					spawn_new_ship();
					set_inner_state(IS_IN_GAME);
					inner_state.tics = prev_level_tics;
				} else {
					trigger_game_over();
				}
			}
			break;

		case IS_GAME_OVER:
			break;

		case IS_RANK:
			if (inner_state.tics >= RANK_TOTAL_TICS) {
				stop_music();

				if (is_highscore(gc.score)) {
					set_inner_state(IS_HIGHSCORE_INPUT);
					SDL_ShowCursor(SDL_ENABLE);
					start_highscore_input();
				} else {
					/* loser. */
					SDL_ShowCursor(SDL_ENABLE);
					start_main_menu();
				}
			}
			break;

		case IS_WAVE_CLEARED:
			if (gc.cur_wave == levels[gc.cur_level]->num_waves - 1 &&
				inner_state.tics >= WAVE_CLEARED_TICS/2) {
				initialize_stats_table(&level_stat_counters);
				set_inner_state(IS_LEVEL_CLEARED);
			} else if (inner_state.tics >= WAVE_CLEARED_TICS) {
				gc.cur_wave++;
				assert(gc.cur_wave < levels[gc.cur_level]->num_waves);
				reset_wave();
				set_inner_state(IS_WAVE_TITLE);
			}
			break;

		case IS_HIGHSCORE_INPUT:
			break;

		case IS_LEVEL_CLEARED:
			break;

		case IS_LEVEL_TRANSITION:
			if (inner_state.tics >= LEVEL_TRANSITION_TOTAL_TICS) {
				gc.cur_level = (gc.cur_level + 1)%NUM_LEVELS;
				set_inner_state(IS_WAVE_TITLE);
				reset_level();
			}
			break;

		default:
			assert(0);
	}
}