Beispiel #1
0
static int
jarhead_hit(struct foe_jarhead *f, const vector2 *hit)
{
	const float radius = foe_data[f->common.type].radius;

	if (vec2_distance_squared(hit, &f->common.pos) < radius*radius) {
		if (f->state == JARHEAD_ALIVE) {
			if (irand(3) == 0) {
				foe_common_gen_explosion(&f->common, 1.f);
				kill_foe(&f->common);
			} else {
				vector2 s = ship.pos;
				f->state = JARHEAD_EXPLODING;
				vec2_mul_scalar(&s, .1f);
				vec2_sub_from(&f->common.dir, &s);

				f->hit_dir = f->common.dir;
				vec2_mul_scalar(&f->hit_dir,
						.02f/vec2_length(&f->hit_dir));

				f->common.angle_speed *= -4.f;
				f->ttl = JARHEAD_TTL_AFTER_HIT;
				f->spin_angle = .2f + .2f*frand();
				if (irand(2))
					f->spin_angle = -f->spin_angle;
			}
			foe_common_bump_score(&f->common);
		}
		return 1;
	}

	return 0;
}
Beispiel #2
0
static int
ninja_hit(struct foe_ninja *f, const vector2 *hit)
{
	int r = 0;
	const float radius = foe_data[FOE_NINJA].radius;

	if (vec2_distance_squared(hit, &f->common.pos) < radius*radius) {
		r = 1;

		if (--f->hit_count <= 0) {
			foe_common_gen_explosion(&f->common, 1.f);
			kill_foe(&f->common);
			foe_common_bump_score(&f->common);
		} else {
			vector2 s = ship.pos;

			f->state = NINJA_RECOVERING;
			vec2_mul_scalar(&s, .15f);
			vec2_sub_from(&f->common.dir, &s);

			f->hit_dir = f->common.dir;
			vec2_mul_scalar(&f->hit_dir,
					.03f/vec2_length(&f->hit_dir));

			f->common.angle_speed *= -4.f;
			f->recover_ttl = NINJA_RECOVER_TTL;
			f->spin_angle = .2f + .2f*frand();
			if (irand(2))
				f->spin_angle = -f->spin_angle;
		}
	}

	return r;
}
static void _control_camera(Game* G, float delta_time)
{
    if(G->num_points == 1) {
        Vec2 curr = G->points[0].pos;
        Vec2 delta = vec2_sub(curr, G->prev_single);

        /* L-R rotation */
        Quaternion q = quat_from_axis_anglef(0, 1, 0, delta_time*delta.x*0.2f);
        G->camera.orientation = quat_multiply(G->camera.orientation, q);

        /* U-D rotation */
        q = quat_from_axis_anglef(1, 0, 0, delta_time*delta.y*0.2f);
        G->camera.orientation = quat_multiply(q, G->camera.orientation);

        G->prev_single = curr;
    } else if(G->num_points == 2) {
        float camera_speed = 0.1f;
        Vec3 look = quat_get_z_axis(G->camera.orientation);
        Vec3 right = quat_get_x_axis(G->camera.orientation);
        Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos);
        Vec2 delta;

        avg = vec2_mul_scalar(avg, 0.5f);
        delta = vec2_sub(avg, G->prev_double);

        look = vec3_mul_scalar(look, -delta.y*camera_speed);
        right = vec3_mul_scalar(right, delta.x*camera_speed);


        G->camera.position = vec3_add(G->camera.position, look);
        G->camera.position = vec3_add(G->camera.position, right);

        G->prev_double = avg;
    }
}
Beispiel #4
0
static void
foe_add_trail(const vector2 *pos, const vector2 *dir, int palette)
{
	const int nparticles = 3 + irand(7);
	int i;
	vector2 tp = *pos, e = *dir;
	vec2_mul_scalar(&e, 1.02f);
	vec2_sub_from(&tp, &e);

	for (i = 0; i < nparticles; i++) {
		particle *p = add_particle();

		if (!p)
			break;

		p->ttl = 15 + irand(15);
		p->t = 0;
		p->palette = palette;
		p->width = p->height = .2f + .1f*frand();
		p->pos.x = tp.x + .2f*frand() - .1f;
		p->pos.y = tp.y + .2f*frand() - .1f;
		vec2_set(&p->dir, 1, 0);
		p->speed = 0.f;
		p->friction = .9f;
	}
}
Beispiel #5
0
static void
foe_common_spawn(struct foe_common *f, const vector2 *source, int type)
{
	vector2 *pos = &f->pos;
	vector2 *dir = &f->dir;
	float speed;

	f->used = 1;

	*pos = *source;

	speed = .05f + .05f*frand();

	dir->x = frand() - .5f;
	dir->y = frand() - .5f;
	vec2_mul_scalar(dir, speed/vec2_length(dir));

	f->tics = 0;
	f->type = type;

	f->angle = 0;
	f->angle_speed = 5.f*frand();

	f->rot_axis.x = frand() - .5f;
	f->rot_axis.y = frand() - .5f;
	f->rot_axis.z = frand() - .5f;
	vec3_normalize(&f->rot_axis);

	foe_data[f->type].create_fn((foe *)f);
}
Beispiel #6
0
static void
evolved_duck_create(struct foe_evolved_duck *f)
{
	f->num_trail_segs = 1;
	f->trail_seg_head = 0;
	f->trail_seg[f->trail_seg_head] = f->common.pos;
	f->trail_texture_id = duck_trail;
	f->max_turn_angle = MAX_EVOLVED_DUCK_TURN_ANGLE;
	vec2_mul_scalar(&f->common.dir, .1f);
}
Beispiel #7
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);
}
void add_touch_points(Game* G, int num_touch_points, TouchPoint* points)
{
    int ii;
    for(ii=0;ii<num_touch_points;++ii) {
        G->points[G->num_points++] = points[ii];
    }

    if(G->num_points == 1) {
        G->prev_single = G->points[0].pos;
        G->tap_timer = 0.0f;
    } else if(G->num_points == 2) {
        Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos);
        avg = vec2_mul_scalar(avg, 0.5f);
        G->prev_double = avg;
    }
}
Beispiel #9
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);
	}
}
Beispiel #10
0
static void
get_foe_pos_for_border_generator(struct foe_generator *generator, vector2 *pos,
  int foe_type)
{
	const int border = generator->border;
	const vector2 *p0 = &cur_arena->verts[border];
	const vector2 *p1 = &cur_arena->verts[(border + 1)%cur_arena->nverts];
	vector2 n;
	float t;

	n.x = -(p1->y - p0->y);
	n.y = p1->x - p0->x;
	vec2_mul_scalar(&n, 1.5*foe_data[foe_type].radius/vec2_length(&n));

	t  = frand();

	pos->x = p0->x + t*(p1->x - p0->x) + n.x;
	pos->y = p0->y + t*(p1->y - p0->y) + n.y;
}
void remove_touch_points(Game* G, int num_touch_points, TouchPoint* points)
{
    int orig_num_points = G->num_points;
    int ii, jj;
    for(ii=0;ii<orig_num_points;++ii) {
        for(jj=0;jj<num_touch_points;++jj) {
            if(G->points[ii].index == points[jj].index) {
                /* This is the removed touch, swap it with the end of the list */
                G->points[ii] = G->points[--G->num_points];
                break;
            }
        }
    }

    if(G->num_points == 1) {
        G->prev_single = G->points[0].pos;
    } else if(G->num_points == 2) {
        Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos);
        avg = vec2_mul_scalar(avg, 0.5f);
        G->prev_double = avg;
    } else {
        if(G->tap_timer < 0.5f) {
            if(G->prev_single.x < G->width/2) {
                if(G->prev_single.y < G->height/2) { // Top Left
                    cycle_renderers(G->graphics);
                } else { // bottom left
                    G->dynamic_lights = !G->dynamic_lights;
                }

            } else {
                if(G->prev_single.y < G->height/2) { // Top right
                } else { // bottom right
                }
            }
        }
    }
}
Beispiel #12
0
static int
brute_hit(struct foe_brute *f, const vector2 *hit)
{
	const vector2 *pos = &f->common.pos;
	const float radius = foe_data[FOE_BRUTE].radius;

	if (vec2_distance_squared(hit, pos) < radius*radius) {
		if (--f->hit_count == 0) {
			foe_common_gen_explosion(&f->common, 1.3f);
			kill_foe(&f->common);
			foe_common_bump_score(&f->common);
		} else {
			vector2 s, os;
			float t;
			f->last_hit_tic = gc.level_tics;

			s = f->common.pos;
			vec2_sub_from(&s, &ship.pos);
			vec2_normalize(&s);

			vec2_set(&os, -s.y, s.x);

			t = 5.f*(frand() - .5f);
			s.x += t*os.x;
			s.y += t*os.y;
			vec2_mul_scalar(&s, .3f/vec2_length(&s));

			vec2_add_to(&f->common.dir, &s);

			f->common.angle_speed *= 2;
		}

		return 1;
	}

	return 0;
}
Beispiel #13
0
static void
gen_explosion(float x, float y)
{
	int i, n, c;
	particle *p;

	n = 150 + irand(150);
	c = irand(NUM_PALETTES);

	for (i = 0; i < n; i++) {
		vector2 offs;

		p = add_particle();

		if (!p)
			break;

		p->ttl = 20 + irand(20);
		p->t = 0;
		p->width = .3f*(.6f + .1f*frand());
		p->height = .3f*(2.8f + .4f*frand());
		p->pos.x = x;
		p->pos.y = y;
		p->palette = c;

		vec2_set(&p->dir, frand() - .5f, frand() - .5f);
		vec2_normalize(&p->dir);

		offs = p->dir;
		vec2_mul_scalar(&offs, 1.3f*frand());
		vec2_add_to(&p->pos, &offs);

		p->speed = PARTICLE_SPEED + .05f*frand();
		p->friction = .96f;
	}
}
Beispiel #14
0
static void
evolved_duck_draw(struct foe_evolved_duck *f)
{
	float u, du;
	float t, s, hs;
	int i, j, k;

	glPushAttrib(GL_ALL_ATTRIB_BITS);

	glDisable(GL_LIGHTING);
	glShadeModel(GL_FLAT);
	glDisable(GL_CULL_FACE);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, gl_texture_id(f->trail_texture_id));
	glDisable(GL_DEPTH_TEST);

	s = vec2_length(&f->common.dir);
	hs = .5f*foe_data[f->common.type].max_speed;

	if (s < hs)
		t = 0.f;
	else
		t = (s - hs)/hs;

	glColor4f(t, t, t, t);

	glBegin(GL_TRIANGLE_STRIP);

	if (f->num_trail_segs > 1) {
		vector2 d, n, *from, *to;

		/* head */

		j = f->trail_seg_head;
		k = f->trail_seg_head - 1;

		if (k < 0)
			k = MAX_TRAIL_SEGS - 1;

		from = &f->trail_seg[j];
		to = &f->trail_seg[k];

		d.x = -(to->y - from->y);
		d.y = to->x - from->x;

#define HS 3.f
#define HL 1.5
		vec2_mul_scalar(&d, .5f*HL/vec2_length(&d));

		assert(from->x == f->common.pos.x);
		assert(from->y == f->common.pos.y);

		n.x = from->x + HS*f->common.dir.x;
		n.y = from->y + HS*f->common.dir.y;

		glTexCoord2f(0, 0);
		glVertex3f(n.x - d.x, n.y - d.y, 0);

		glTexCoord2f(1, 0);
		glVertex3f(n.x + d.x, n.y + d.y, 0);

		/* tail */

		/* draw tail */
#define START_U .15f
		du = (1.f - START_U)/f->num_trail_segs;
		u = START_U;

		j = f->trail_seg_head;

		for (i = 0; i < f->num_trail_segs - 1; i++) {
			vector2 d, *from, *to;

			k = j - 1;
			if (k < 0)
				k = MAX_TRAIL_SEGS - 1;

			from = &f->trail_seg[j];
			to = &f->trail_seg[k];

			d.x = -(to->y - from->y);
			d.y = to->x - from->x;

			if (i < f->num_trail_segs - 2) {
				vector2 *next_to;
				int l = k - 1;
				if (l < 0)
					l = MAX_TRAIL_SEGS - 1;

				next_to = &f->trail_seg[l];

				d.x += -(next_to->y - to->y);
				d.y += next_to->x - to->x;
			}

			assert(vec2_length_squared(&d) > 0.f);

			vec2_mul_scalar(&d, .5f*HL/vec2_length(&d));

			glTexCoord2f(0, u);
			glVertex3f(from->x - d.x, from->y - d.y, 0.f);

			glTexCoord2f(1, u);
			glVertex3f(from->x + d.x, from->y + d.y, 0.f);

			j = k;

			u += du;
		}
	}

	glEnd();
	glPopAttrib();
	
	{
		float dir_angle = f->common.angle = 180.f +
		  360.f*atan2(-f->common.dir.x, f->common.dir.y)/
		  2.f/M_PI;

	glPushMatrix();
	glTranslatef(f->common.pos.x, f->common.pos.y, 0.f);
	glRotatef(dir_angle, 0, 0, 1);
	glRotatef(f->common.angle, 0, 1, 0);

	if (f->common.tics < SPAWN_TICS) {
		static const struct rgb white = { 0.f, 1.f, 1.f };
		float s = (float)f->common.tics/SPAWN_TICS;
		mesh_render_modulate_color(foe_meshes[f->common.type], &white, s);
	} else {
		mesh_render(foe_meshes[f->common.type]);
	}

	glPopMatrix();
	}

}
Beispiel #15
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);
}