コード例 #1
0
ファイル: ai_precalc.c プロジェクト: JINXSHADYLANE/quibble
float ai_navmesh_distance(NavMesh* navmesh, Vector2 p1, Vector2 p2) {
	assert(navmesh);

	uint navpoint1 = ai_nearest_navpoint(navmesh, p1);
	uint navpoint2 = ai_nearest_navpoint(navmesh, p2);

	float distance = vec2_length(vec2_sub(p1, navmesh->navpoints[navpoint1]));
	distance += vec2_length(vec2_sub(p2, navmesh->navpoints[navpoint2]));

	uint idx = IDX_2D(navpoint1, navpoint2, navmesh->n_nodes);
	distance += navmesh->distance[idx];

	return distance;
}
コード例 #2
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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;
}
コード例 #3
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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);
}
コード例 #4
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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;
}
コード例 #5
0
ファイル: touch_ctrls.c プロジェクト: JINXSHADYLANE/quibble
Vector2 touch_joystick(TexHandle tex, uint layer, const RectF* back_src,
	const RectF* nub_src, const Vector2* pos) {
	assert(back_src);
	assert(nub_src);
	assert(pos);

	Color nub_color = COLOR_WHITE;

	float back_width = rectf_width(back_src);
	float back_height = rectf_height(back_src);

	// Draw static back
	RectF dest = {
		pos->x - back_width / 2.0f,
		pos->y - back_height / 2.0f, 
		0.0f, 0.0f
	};
	video_draw_rect(tex, layer, back_src, &dest, COLOR_WHITE);

	Vector2 touch;
	if(!_get_touch(pos, joystick_area_radius, &touch)) {
		touch = vec2(0.0f, 0.0f);	
	}	
	else {	
		touch = vec2_sub(touch, *pos);	
		nub_color = pressed_color;
	}	

	float nub_width = rectf_width(nub_src);
	float nub_height = rectf_width(nub_src);

	assert(feql(back_width, back_height) && feql(nub_width, nub_height));

	float back_radius = back_width / 2.0f;
	float nub_radius = nub_width / 2.0f;
	
	float move_radius = back_radius - nub_radius;

	assert(move_radius > 4.0f);
	
	float offset_len = vec2_length(touch);
	if(offset_len > move_radius) {
		touch = vec2_scale(touch, move_radius / offset_len);
		offset_len = move_radius;
		nub_color = COLOR_WHITE;
	}	
	
	// Draw nub
	dest.left = pos->x + touch.x - nub_width / 2.0f;
	dest.top = pos->y + touch.y - nub_height / 2.0f;
	video_draw_rect(tex, layer, nub_src, &dest, nub_color);

	if(offset_len < joystick_deadzone_radius)
		return vec2(0.0f, 0.0f);

	float norm_len = normalize(offset_len, 
		joystick_deadzone_radius, move_radius);	
	
	return vec2_scale(touch, norm_len / offset_len);
}	
コード例 #6
0
ファイル: vec2.c プロジェクト: QuantumInfinity/AntiCaster
void vec2_normalize(vec2_t* v0, vec2_t* out)
{
	double length = vec2_length(v0);
	if (length < 0.000001)
		return;
	out->x = v0->x/length;
	out->y = v0->y/length;
}
コード例 #7
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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;
}
コード例 #8
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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);
}
コード例 #9
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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;
}
コード例 #10
0
ファイル: foe.c プロジェクト: mpersano/protozoa
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();
	}

}
コード例 #11
0
ファイル: ai_precalc.c プロジェクト: JINXSHADYLANE/quibble
NavMesh ai_precalc_navmesh(DArray geometry, DArray platforms,
	float width, float height) {
	NavMesh res;

	ai_precalc_bounds(width, height);

	DArray navpoints = _gen_navpoints(geometry, platforms);
	DArray edges = _gen_edges(navpoints, geometry);

	Vector2* navpoints_v = DARRAY_DATA_PTR(navpoints, Vector2);
	Edge* edges_e = DARRAY_DATA_PTR(edges, Edge);

	uint n = navpoints.size;

	res.n_nodes = n;
	res.navpoints = MEM_ALLOC(sizeof(Vector2) * n);
	res.neighbour_count = MEM_ALLOC(sizeof(uint) * n);
	res.neighbours_start = MEM_ALLOC(sizeof(uint) * n);
	float* adjacency = MEM_ALLOC(sizeof(float) * n*n);
	res.distance = MEM_ALLOC(sizeof(float) * n*n);
	res.radius = MEM_ALLOC(sizeof(float) * n);
	res.nn_grid_count = MEM_ALLOC(sizeof(uint) * nn_grid_cells);
	res.nn_grid_start = MEM_ALLOC(sizeof(uint) * nn_grid_cells);

	memset(res.neighbour_count, 0, sizeof(uint) * n);
	memset(adjacency, 0, sizeof(float) * n*n);
	memset(res.distance, 0, sizeof(float) * n*n);
	memset(res.nn_grid_count, 0, sizeof(uint) * nn_grid_cells);
	memset(res.nn_grid_start, 0, sizeof(uint) * nn_grid_cells);
		
	for(uint i = 0; i < navpoints.size; ++i) {
		res.navpoints[i] = 	navpoints_v[i];
		res.radius[i] = ai_wall_distance(navpoints_v[i], geometry);
	}

	for(uint i = 0; i < edges.size; ++i) {
		float dist = vec2_length(vec2_sub(
			navpoints_v[edges_e[i].v1], navpoints_v[edges_e[i].v2]));
		adjacency[IDX_2D(edges_e[i].v1, edges_e[i].v2, n)] = dist;
		adjacency[IDX_2D(edges_e[i].v2, edges_e[i].v1, n)] = dist;
		res.neighbour_count[edges_e[i].v1]++;
		res.neighbour_count[edges_e[i].v2]++;
	}

	// Pracalc node neighbour lists
	uint total_neighbours = res.neighbour_count[0];
	res.neighbours_start[0] = 0;
	for(uint i = 1; i < n; ++i) {
		res.neighbours_start[i] = 
			res.neighbours_start[i-1] + res.neighbour_count[i-1];
		total_neighbours +=	res.neighbour_count[i];
	}		
	res.neighbours = MEM_ALLOC(sizeof(uint) * total_neighbours);
	for(uint i = 0; i < n; ++i) {
		uint idx = res.neighbours_start[i];
		for(uint j = 0; j < n; ++j) {
			if(adjacency[IDX_2D(i, j, n)] > 0.0f)
				res.neighbours[idx++] = j;
		}
		assert(idx == res.neighbours_start[i] + res.neighbour_count[i]);
	}

	memcpy(res.distance, adjacency, sizeof(float) * n*n);
	// Change zero distances to infinities
	for(uint i = 0; i < n*n; ++i)
		if(res.distance[i] == 0.0f)
			res.distance[i] = 10000000.0f;

	// Floyd-Warshall
	for(uint i = 0; i < n; ++i)
		for(uint j = 0; j < n; ++j)
			for(uint k = 0; k < n; ++k)
				res.distance[IDX_2D(j, k, n)] = MIN(res.distance[IDX_2D(j, k, n)],
					res.distance[IDX_2D(j, i, n)]+res.distance[IDX_2D(i, k, n)]);

	// Precalc nearest-navpoint grid
	DArray grid_cell;
	DArray nn_grid;

	res.nn_grid_start[0] = 0;

	nn_grid = darray_create(sizeof(uint), 0);
	for(uint i = 0; i < nn_grid_cells; ++i) {
		grid_cell = darray_create(sizeof(uint), 0);
		
		for(uint j = 0; j < nn_samples; ++j) {
			Vector2 p = _rand_point_in_nn_grid_cell(i);
			uint nearest_navpoint = _nearest_navpoint(p, geometry, navpoints);
			if(nearest_navpoint >= n) // Point was inside wall, skip
				continue;

			bool unique = true;

			uint* existing_navpoints = DARRAY_DATA_PTR(grid_cell, uint);
			for(uint k = 0; k < grid_cell.size; ++k)
				if(existing_navpoints[k] == nearest_navpoint)
					unique = false;
			
			if(unique)
				darray_append(&grid_cell, &nearest_navpoint);
		}

		res.nn_grid_count[i] = grid_cell.size;
		if(i > 0)
			res.nn_grid_start[i] = 
				res.nn_grid_start[i-1] + res.nn_grid_count[i-1];
		
		uint* cell_navpoints = DARRAY_DATA_PTR(grid_cell, uint);
		darray_append_multi(&nn_grid, cell_navpoints, grid_cell.size);
		darray_free(&grid_cell);
	}	

	// Hack, works properly as long as darray_free only does
	// MEM_FREE(darray.data);
	res.nn_grid = (uint*)nn_grid.data;

	darray_free(&navpoints);
	darray_free(&edges);
	MEM_FREE(adjacency);

	_precalc_vis(geometry, &res);

	return res;
}
コード例 #12
0
ファイル: vector.c プロジェクト: SeMo810/CSCI-4229
VEC2 vec2_normalize(VEC2 v)
{
  return vec2_divide(v, vec2_length(v));
}