示例#1
0
void physics(Game *g)
{
	Flt d0,d1,dist;
	//Update ship position
	g->ship.pos[0] += g->ship.vel[0];
	g->ship.pos[1] += g->ship.vel[1];
	//Check for collision with window edges
	if (g->ship.pos[0] < 0.0) {
		g->ship.pos[0] += (float)xres;
	}
	else if (g->ship.pos[0] > (float)xres) {
		g->ship.pos[0] -= (float)xres;
	}
	else if (g->ship.pos[1] < 0.0) {
		g->ship.pos[1] += (float)yres;
	}
	else if (g->ship.pos[1] > (float)yres) {
		g->ship.pos[1] -= (float)yres;
	}
	//
	//
	//Update bullet positions
	struct timespec bt;
	clock_gettime(CLOCK_REALTIME, &bt);
	Bullet *b = g->bhead;
	while (b) {
		//How long has bullet been alive?
		double ts = timeDiff(&b->time, &bt);
		if (ts > 2.5) {
			//time to delete the bullet.
			Bullet *saveb = b->next;
			deleteBullet(g, b);
			b = saveb;
			g->nbullets--;
			continue;
		}
		//move the bullet
		b->pos[0] += b->vel[0];
		b->pos[1] += b->vel[1];
		//Check for collision with window edges
		if (b->pos[0] < 0.0) {
			b->pos[0] += (float)xres;
		}
		else if (b->pos[0] > (float)xres) {
			b->pos[0] -= (float)xres;
		}
		else if (b->pos[1] < 0.0) {
			b->pos[1] += (float)yres;
		}
		else if (b->pos[1] > (float)yres) {
			b->pos[1] -= (float)yres;
		}
		b = b->next;
	}
	//
	//Update asteroid positions
	Asteroid *a = g->ahead;
	while (a) {
		a->pos[0] += a->vel[0];
		a->pos[1] += a->vel[1];
		//Check for collision with window edges
		if (a->pos[0] < -100.0) {
			a->pos[0] += (float)xres+200;
		}
		else if (a->pos[0] > (float)xres+100) {
			a->pos[0] -= (float)xres+200;
		}
		else if (a->pos[1] < -100.0) {
			a->pos[1] += (float)yres+200;
		}
		else if (a->pos[1] > (float)yres+100) {
			a->pos[1] -= (float)yres+200;
		}
		a->angle += a->rotate;
		a = a->next;
	}
	//
	//Asteroid collision with bullets?
	//If collision detected:
	//     1. delete the bullet
	//     2. break the asteroid into pieces
	//        if asteroid small, delete it
	a = g->ahead;
	while (a) {
		//is there a bullet within its radius?
		Bullet *b = g->bhead;
		while (b) {
			d0 = b->pos[0] - a->pos[0];
			d1 = b->pos[1] - a->pos[1];
			dist = (d0*d0 + d1*d1);
			if (dist < (a->radius*a->radius)) {
				//std::cout << "asteroid hit." << std::endl;
				//this asteroid is hit.
				if (a->radius > 20.0) {
					//break it into pieces.
					Asteroid *ta = a;
					buildAsteroidFragment(ta, a);
					int r = rand()%10+5;
					for (int k=0; k<r; k++) {
						//get the next asteroid position in the array
						Asteroid *ta = new Asteroid;
						buildAsteroidFragment(ta, a);
						//add to front of asteroid linked list
						ta->next = g->ahead;
						if (g->ahead != NULL)
							g->ahead->prev = ta;
						g->ahead = ta;
						g->nasteroids++;
					}
				} else {
					a->color[0] = 1.0;
					a->color[1] = 0.1;
					a->color[2] = 0.1;
					//asteroid is too small to break up
					//delete the asteroid and bullet
					Asteroid *savea = a->next;
					deleteAsteroid(g, a);
					a = savea;
					g->nasteroids--;
				}
				//delete the bullet...
				Bullet *saveb = b->next;
				deleteBullet(g, b);
				b = saveb;
				g->nbullets--;
				if (a == NULL)
					break;
				continue;
			}
			b = b->next;
		}
		if (a == NULL)
			break;
		a = a->next;
	}
	//---------------------------------------------------
	//check keys pressed now
	if (keys[XK_Left]) {
		g->ship.angle += 4.0;
		if (g->ship.angle >= 360.0f)
			g->ship.angle -= 360.0f;
	}
	if (keys[XK_Right]) {
		g->ship.angle -= 4.0;
		if (g->ship.angle < 0.0f)
			g->ship.angle += 360.0f;
	}
	if (keys[XK_Up]) {
		//apply thrust
		//convert ship angle to radians
		Flt rad = ((g->ship.angle+90.0) / 360.0f) * PI * 2.0;
		//convert angle to a vector
		Flt xdir = cos(rad);
		Flt ydir = sin(rad);
		g->ship.vel[0] += xdir*0.02f;
		g->ship.vel[1] += ydir*0.02f;
		Flt speed = sqrt(g->ship.vel[0]*g->ship.vel[0]+
										g->ship.vel[1]*g->ship.vel[1]);
		if (speed > 10.0f) {
			speed = 10.0f;
			normalize(g->ship.vel);
			g->ship.vel[0] *= speed;
			g->ship.vel[1] *= speed;
		}
	}
	if (keys[XK_space]) {
		//a little time between each bullet
		struct timespec bt;
		clock_gettime(CLOCK_REALTIME, &bt);
		double ts = timeDiff(&g->bulletTimer, &bt);
		if (ts > 0.1) {
			timeCopy(&g->bulletTimer, &bt);
			//shoot a bullet...
			Bullet *b = new Bullet;
			timeCopy(&b->time, &bt);
			b->pos[0] = g->ship.pos[0];
			b->pos[1] = g->ship.pos[1];
			b->vel[0] = g->ship.vel[0];
			b->vel[1] = g->ship.vel[1];
			//convert ship angle to radians
			Flt rad = ((g->ship.angle+90.0) / 360.0f) * PI * 2.0;
			//convert angle to a vector
			Flt xdir = cos(rad);
			Flt ydir = sin(rad);
			b->pos[0] += xdir*20.0f;
			b->pos[1] += ydir*20.0f;
			b->vel[0] += xdir*6.0f + rnd()*0.1;
			b->vel[1] += ydir*6.0f + rnd()*0.1;
			b->color[0] = 1.0f;
			b->color[1] = 1.0f;
			b->color[2] = 1.0f;
			//add to front of bullet linked list
			b->next = g->bhead;
			if (g->bhead != NULL)
				g->bhead->prev = b;
			g->bhead = b;
			g->nbullets++;
		}
	}
}
示例#2
0
void physics(Game *g)
{
	Flt d0,d1,dist;
	//Update ship position
	g->ship.pos[0] += g->ship.vel[0];
	g->ship.pos[1] += g->ship.vel[1];
	//Check for collision with window edges
	if (g->ship.pos[0] < 0.0) {
		g->ship.pos[0] += (float)xres;
	}
	else if (g->ship.pos[0] > (float)xres) {
		g->ship.pos[0] -= (float)xres;
	}
	else if (g->ship.pos[1] < 0.0) {
		g->ship.pos[1] += (float)yres;
	}
	else if (g->ship.pos[1] > (float)yres) {
		g->ship.pos[1] -= (float)yres;
	}

	//Update asteroid positions
	Asteroid *a = g->ahead;
	while (a) {
		a->pos[0] += a->vel[0];
		a->pos[1] += a->vel[1];
		//Check for collision with window edges
		if (a->pos[0] < -100.0) {
			a->pos[0] += (float)xres+200;
		}
		else if (a->pos[0] > (float)xres+100) {
			a->pos[0] -= (float)xres+200;
		}
		else if (a->pos[1] < -100.0) {
			a->pos[1] += (float)yres+200;
		}
		else if (a->pos[1] > (float)yres+100) {
			a->pos[1] -= (float)yres+200;
		}
		a->angle += a->rotate;
		a = a->next;
	}
	//
	//Asteroid collision with bullets?
	//If collision detected:
	//     1. delete the bullet
	//     2. break the asteroid into pieces
	//        if asteroid small, delete it
	a = g->ahead;
	while (a) {
		//is there a bullet within its radius?
		d0 = g->ship.pos[0] - a->pos[0];
		d1 = g->ship.pos[1] - a->pos[1];
		d0 = g->ship.pos[0] - a->pos[0];
		d1 = g->ship.pos[1] - a->pos[1];
		dist = (d0*d0 + d1*d1);
		if (dist < (a->radius*a->radius)) {
			//std::cout << "asteroid hit." << std::endl;
			//this asteroid is hit.
			if (a->radius > 20.0) {
				//break it into pieces.
				Asteroid *ta = a;
				buildAsteroidFragment(ta, a);
				int r = rand()%10+5;
				for (int k=0; k<r; k++) {
					//get the next asteroid position in the array
					Asteroid *ta = new Asteroid;
					buildAsteroidFragment(ta, a);
					//add to front of asteroid linked list
					ta->next = g->ahead;
					if (g->ahead != NULL)
						g->ahead->prev = ta;
					g->ahead = ta;
					g->nasteroids++;
				}
			} else {
				a->color[0] = 1.0;
				a->color[1] = 0.1;
				a->color[2] = 0.1;
				//asteroid is too small to break up
				//delete the asteroid and bullet
				Asteroid *savea = a->next;
				deleteAsteroid(g, a);
				a = savea;
				g->nasteroids--;
				g->ship.radius++;
			}
			if (a == NULL)
				break;
			continue;
		}
		if (a == NULL)
			break;
		a = a->next;
	}
	//---------------------------------------------------
	//check keys pressed now
	if (keys[XK_Left]) {
		g->ship.angle += 4.0;
		if (g->ship.angle >= 360.0f)
			g->ship.angle -= 360.0f;
	}
	if (keys[XK_Right]) {
		g->ship.angle -= 4.0;
		if (g->ship.angle < 0.0f)
			g->ship.angle += 360.0f;
	}
	if (keys[XK_Up]) {
		//apply thrust
		//convert ship angle to radians
		Flt rad = ((g->ship.angle+90.0) / 360.0f) * PI * 2.0;
		//convert angle to a vector
		Flt xdir = cos(rad);
		Flt ydir = sin(rad);
		g->ship.vel[0] += xdir*0.02f;
		g->ship.vel[1] += ydir*0.02f;
		Flt speed = sqrt(g->ship.vel[0]*g->ship.vel[0]+
										g->ship.vel[1]*g->ship.vel[1]);
		if (speed > 10.0f) {
			speed = 10.0f;
			normalize(g->ship.vel);
			g->ship.vel[0] *= speed;
			g->ship.vel[1] *= speed;
		}
	}
}