⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 car.cpp

📁 是3D游戏一书中所讲的游戏引擎fly3D 包括fly3D引擎的源码及应用此引擎开发出来的游戏实例 有fly3D引擎的教程,易于step by step跟学
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		// normalize velocity
		vel/=len;
		if (len>maxvel)
			len=maxvel;
		
		// project velocity in car local axes
		v.x=vec_dot(vel,X)*len;
		v.y=vec_dot(vel,Y)*len;
		v.z=vec_dot(vel,Z)*len;

		// apply damping to individual axes
		// X for sliding and Z for breaking
		for( int i=0;i<3;i++ )
			if (v[i]>=0.0f)
				{
				v[i]-=veldamp[i]*dt;
				if (v[i]<0.0) v[i]=0.0f;
				}
			else
				{
				v[i]+=veldamp[i]*dt;
				if (v[i]>0.0) v[i]=0.0f;
				}
		
		// restore velocity vector from axes components
		vel=X*v.x + Y*v.y + Z*v.z;

		// compute wheel roll based on forward motion and wheel radius
		wheelroll+=v.z*dt/(M_2Pi*wheelradius)*360.0f;
		wheelroll=(float)fmod(wheelroll,360);
		
		// move by applying the car velocity
		p=pos+vel*(float)dt;
		flyengine->excludecollision=this;
		if (flyengine->collision_bsp(flyengine->bsp,pos,p))
		{
			contactobj=flyengine->hitmesh;
			contactfacenum=flyengine->hitface;
		}
		else contactobj=0;
		flyengine->excludecollision=0;
		if (contactobj)
			pos=flyengine->hitip+contactobj->faces[contactfacenum]->normal*carheight;
		else pos=p;
	} 
	else v.null();

	if (contactobj==0)
	{
		// ray intesect collision detection to check for ground contact
		p=pos-Y*carheight;
		flyengine->excludecollision=this;
		if (flyengine->collision_bsp(flyengine->bsp,pos,p))
		{
			contactobj=flyengine->hitmesh;
			contactfacenum=flyengine->hitface;
		} 
		else contactobj=0;
		flyengine->excludecollision=0;
	}
	
	// if in contact
	if (contactobj)
	{
		// position the car at a fixed distance from the ground
		pos=flyengine->hitip+Y*(carheight-0.1f);
		// align car with ground if no collision with wall
	 	if (contactobj->localfaces==0 && contactobj->faces[contactfacenum]->normal.z<0.5f)
		{
			rotate(Y,vector(0,0,1));
			v.z=-v.z;
			v.x=-v.x;
		}
		else rotate(Y,contactobj->faces[contactfacenum]->normal,0.1f*dt);
		// recompute velocity
		vel=X*v.x + Y*v.y + Z*v.z;
		// rotate car body based on forward motion and steering angle if in contact
		rotate(-wheelrot*v.z*dt/carwheelrot,Y);
	}

	return 1;
}

void car::check_keys(int dt)
{
	unsigned char *diks=directx->diks;
	
	if (diks[0xcb])	// left arrow
		wheelrot+=wheelrotvel*dt;

	if (diks[0xcd])	// right arrow
		wheelrot-=wheelrotvel*dt;

	if (contactobj)
	{
	if (diks[0xc8])	// up arrow
		vel-=Z*(accel*dt);

	if (diks[0xd0])	// down arrow
		vel+=Z*(accel*dt);
	}
}

void car::check_robot_keys(int dt)
{
	if (track==0)
		return;

	vector P,T,V;
	float len,dot;

	// get position of rabbit
	curtracktime=(curtracktime+dt)%totaltracktime;
	track->evaluate((float)curtracktime/totaltracktime,&P.x);
	P.z+=track->pivot.z-50;
	T=P-pos;
	len=T.length();
	T/=len;
	dot=vec_dot(T,Z);
	if (dot<0.996)   // 0.996=cosd(8)
		{
		V.cross(T,Z);
		if (vec_dot(V,Y)>0)
			wheelrot+=wheelrotvel*dt; // rotate right
		else
			wheelrot-=wheelrotvel*dt; // rotate left
		}

	if (contactobj)
	if (len>500)
		vel-=Z*(accel*dt); // move forward
}

void car::mp_send_pos(int msgtype,int msgflag)
{
	static struct mp_data data;
	
	data.type=msgtype;
	data.dpid=directx->players[player].dpid;
	data.flag=msgflag;
	data.pos=pos;
	data.vel=vel;
	data.Y=Y;
	data.Z=Z;
	data.wheelrot=wheelrot;

	directx->send_message((mp_msg *)&data,sizeof(struct mp_data));
}

void mp_message(int from,mp_msg *msg)
{	
	switch( msg->type )
		{
		case FLYMP_MSG_POS:
			{
				mp_data *data=(mp_data *)&msg->type;
				car *c=(car *)directx->players[from].data;
				if (from>0)
					{
					c->remove_from_bsp();
					c->pos=data->pos;
					c->vel=data->vel;
					c->Y=data->Y;
					c->Z=data->Z;
					c->X.cross(c->Y,c->Z);
					c->wheelrot=data->wheelrot;
					c->update_mat();
					c->add_to_bsp();
					}
			}
			break;
		case FLYMP_MSG_JOIN:
			{
				player_data *data=(player_data *)&msg->type;
				car *c=(car *)flyengine->player->clone();
				c->player=directx->add_player(data->name,data->dpid,c);
				flyengine->set_status_msg("%s HAS JOINED THE GAME",data->name);
				flyengine->activate(c,(directx->mpmode==FLYMP_SERVER));
			}
			break;
		case FLYMP_MSG_QUIT:
			{
				player_data *data=(player_data *)&msg->type;
				if (from<directx->nplayers)
					{
					flyengine->set_status_msg("%s HAS LEFT THE GAME",directx->players[from].name);
					bsp_object *obj=(bsp_object *)directx->remove_player(from);
					for( int i=from;i<directx->nplayers;i++ )
						((car *)directx->players[i].data)->player=i;
					if (obj) obj->life=-1;
					}
			}
			break;
		}
}

bsp_object *camera::clone()
{
	camera *tmp=new camera;
	*tmp=*this;
	tmp->source=this;
	return tmp;
}

int camera::get_custom_param_desc(int i,param_desc *pd)
{
	if (pd!=0)
	switch(i)
	{
	case 0:
		pd->type='f';
		pd->data=&height;
		strcpy(pd->name,"height");
		break;
	case 1:
		pd->type='f';
		pd->data=&dist;
		strcpy(pd->name,"dist");
		break;
	case 2:
		pd->type='d';
		pd->data=&target;
		strcpy(pd->name,"target");
		break;
	case 3:
		pd->type='f';
		pd->data=&maxvel;
		strcpy(pd->name,"maxvel");
		break;
	case 4:
		pd->type=TYPE_SUN;
		pd->data=&s;
		strcpy(pd->name,"sun");
		break;
	}
	return 5;
}

void camera::init()
{
	if (target)
	{
	lp=target->pos;
	pos=target->source->pos;
	}
}

int camera::step(int dt)
{
	vector dir,p;

	if (target)
		{
		dir.x=target->pos.x-pos.x;
		dir.y=target->pos.y-pos.y;
		dir.z=0;
		dir.normalize();

		p.x=target->pos.x-dir.x*dist;
		p.y=target->pos.y-dir.y*dist;
		p.z=target->pos.z+height;

		float dist;
		dir=p-pos;
		dist=dir.length();
		if (dist>0.01f)
			{
			dir/=dist;
			if (dist>maxvel*dt)
				dist=maxvel*dt;
			pos+=dir*dist;		
			}
		
		if (flyengine->collision_bsp(flyengine->bsp,pos,vector(pos.x,pos.y,pos.z-flyengine->viewmindist*2)))
			pos.vec(flyengine->hitip.x,flyengine->hitip.y,flyengine->hitip.z+flyengine->viewmindist*2);

		dir=target->pos-lp;
		dist=dir.length();
		if (dist>0.01f)
			{
			dir/=dist;
			if (dist>maxvel*dt)
				dist=maxvel*dt;
			lp+=dir*dist;		
			}

		dir=pos-lp;
		dir.normalize();
		align_z(dir);
		}

	return 1;
}

bsp_object *sun::clone()
{
	sun *tmp=new sun;
	*tmp=*this;
	tmp->source=this;
	return tmp;
}

int sun::get_custom_param_desc(int i,param_desc *pd)
{
	if (pd!=0)
	switch(i)
	{
	case 0:
		pd->type='3';
		pd->data=&objmesh;
		strcpy(pd->name,"objmesh");
		break;
	case 1:
		pd->type='c';
		pd->data=&color;
		strcpy(pd->name,"color");
		break;
	case 2:
		pd->type='f';
		pd->data=&color.w;
		strcpy(pd->name,"transp");
		break;
	case 3:
		pd->type='p';
		pd->data=&halopic;
		strcpy(pd->name,"halopic");
		break;
	case 4:
		pd->type='f';
		pd->data=&halosize;
		strcpy(pd->name,"halosize");
		break;
	}
	return 5;
}

void sun::init()
{
	if (objmesh)
		pos=objmesh->pivotpos;
}

void sun::draw()
{
	static vector x,y;

	int d=(int)(pos-flyengine->cam->pos).length()/10*10;
	glMatrixMode( GL_PROJECTION );
	glPushMatrix();
	glLoadIdentity();
	gluPerspective( flyengine->camangle, flyengine->aspect, d/2,2*d);
	glMatrixMode( GL_MODELVIEW );

	glDisable(GL_FOG);
	glDisable(GL_DEPTH_TEST);

	glPushMatrix();
	glTranslatef(pos.x,pos.y,pos.z);
	if (objmesh)
		objmesh->draw();

	x=flyengine->cam->X*halosize;
	y=flyengine->cam->Y*halosize;

	glBlendFunc(GL_ONE,GL_ONE);
	glDepthMask(GL_FALSE);
	
	glColor3f(color.x*color.w,color.y*color.w,color.z*color.w);

	tc->use(halopic);

	glBegin(GL_QUADS);

	glTexCoord2f(1,0);
	glVertex3f(x.x-y.x, x.y-y.y, x.z-y.z);

	glTexCoord2f(1,1);
	glVertex3f(x.x+y.x, x.y+y.y, x.z+y.z);

	glTexCoord2f(0,1);
	glVertex3f(y.x-x.x, y.y-x.y, y.z-x.z);

	glTexCoord2f(0,0);
	glVertex3f(-x.x-y.x, -x.y-y.y, -x.z-y.z);

	glEnd();
	glPopMatrix();

	glDepthMask(GL_TRUE);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_DEPTH_TEST);
	if (flyengine->fog) glEnable(GL_FOG);

	glMatrixMode( GL_PROJECTION );
	glPopMatrix();
	glMatrixMode( GL_MODELVIEW );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -