m_player.c

来自「著名物理引擎Hawk的源代码」· C语言 代码 · 共 330 行

C
330
字号
/* M_player.c, HAWK game engine
*
* Copyright 1997-1998 by Phil Frisbie, Jr.
* for Hawk Software
*
*/

#include "G_main.h"
#include "G_math.h"
#include "M_player.h"

#define STEP		16

#define	STOP_EPSILON	(float)0.1

/* this is one of two test clipping functions */
void clipMove(vec3_t in, vec3_t normal, vec3_t out)
{
	float	backoff;
	float	change;
	int		i;
	
	backoff = DotProduct(in, normal);

	for (i=0 ; i<3 ; i++)
	{
		change = normal[i]*backoff;
		out[i] = in[i] - change;
		if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
			out[i] = 0;
	}
}

void clipMove2(vec3_t move, GSURFACE *surf, vec3_t end)
{
	if(surf->normal[X] > 0.99f)
	{
		move[X] += surf->dist - end[X];
	}
	else if(surf->normal[Y] > 0.99f)
	{
		move[Y] += surf->dist - end[Y];
	}
	else if(surf->normal[Z] > 0.99f)
	{
		move[Z] += surf->dist - end[Z];
	}
	else
	{
	}
}

void playerMove(OBJECT *obj, vec3_t move)
{
	vec3_t neworigin;

	VectorAdd(move, obj->origin, neworigin);
/* This needs ALLOT of tweeking to get it right */
	if(0)
	/*if(obj->type & (O_WALLCOL|O_OBJCOL)) */
	{
		TRACE		*tr;
		vec3_t		vtemp, oldorigin;
		vec_t		moveleft = 1.0f;
		int			checks = 3;
		
		VectorCopy(obj->origin, oldorigin);
		/* first add step height */
		neworigin[Z] += STEP;
		oldorigin[Z] += STEP;
		tr = gi.TraceBBox(oldorigin, obj->mins, obj->maxs, neworigin, obj, MASK_PLAYERSOLID);
		while((tr->fraction < 1.0f)&&(checks))
		{
			VectorCopy(tr->endpos, oldorigin);
			moveleft -= moveleft * tr->fraction;
			VectorScale(move, moveleft, move);

			clipMove2(move, tr->surface, neworigin);
			VectorAdd(move, oldorigin, neworigin);
			tr = gi.TraceBBox(oldorigin, obj->mins, obj->maxs, neworigin, obj, MASK_PLAYERSOLID);
			checks--;
		}
		/* now push down from the end point */
		VectorCopy(neworigin, vtemp);
		neworigin[Z] -= 2 * STEP;
		tr = gi.TraceBBox(vtemp, obj->mins, obj->maxs, neworigin, obj, MASK_PLAYERSOLID);
		if(tr->fraction < 1.0)
		{
			VectorCopy(tr->endpos, neworigin);
		}
		VectorCopy(neworigin, obj->origin);
	}
	else
	{
		VectorCopy(neworigin, obj->origin);
	}
}

void M_PlayerUpdate(OBJECT *obj)
{
	int			i, frames = Frames;
	vec3_t		move;
	float		speed;
	BOOL		run = FALSE;
	BOOL		crouch = FALSE;
	
	/* you need to do this for fast 3D cards */
	if(!frames)
		return;
	
	/* Process movement events */
	if(obj->event&EV_FAST)
	{
		if(obj->event&EV_CROUCH)
		{
			speed = obj->acc;
			crouch = TRUE;
		}
		else
			speed = FAST * obj->acc;
	}
	else
	{
		if(obj->event&EV_CROUCH)
		{
			speed = obj->acc * 0.5;
			crouch = TRUE;
		}
		else
			speed = obj->acc;
	}
	if(obj->event&EV_LEFT)
	{
		obj->strafeSpeed += frames * speed;
		obj->strafeSpeed = MIN(obj->maxspeed, obj->strafeSpeed);
		run = TRUE;
	}
	if(obj->event&EV_TURNLEFT)
		obj->angles[Z] += frames * obj->turn;
	
	if(obj->event&EV_RIGHT)
	{
		obj->strafeSpeed -= frames * speed;
		obj->strafeSpeed = MAX(-obj->maxspeed, obj->strafeSpeed);
		run = TRUE;
	}
	if(obj->event&EV_TURNRIGHT)
		obj->angles[Z] -= frames * obj->turn;
	
	if(obj->event&EV_FORWARD)
	{
		if (obj->event&EV_UP)
			obj->speed= obj->maxspeed;
		else
			obj->speed += frames * speed;
		obj->speed = MIN(obj->maxspeed, obj->speed);
		run = TRUE;
	}
	if(obj->event&EV_BACKWARD)
	{
		obj->speed -= frames * speed;
		obj->speed = MAX(-obj->maxspeed, obj->speed);
		run = TRUE;
	}
	if(obj->event&EV_UP)
	{
		obj->vertSpeed += frames * speed;
		obj->vertSpeed = MIN(obj->maxspeed, obj->vertSpeed);
	}
	if(obj->event&EV_DOWN)
	{
		obj->vertSpeed -= frames * speed;
		obj->vertSpeed = MAX(-obj->maxspeed, obj->vertSpeed);
	}
	if(obj->event&EV_LOOKUP)
	{
		obj->pitch += frames * 2;
		obj->pitch = MIN(89.9, obj->pitch);
	}
	if(obj->event&EV_LOOKDOWN)
	{
		obj->pitch -= frames * 2;
		obj->pitch = MAX(-89.9, obj->pitch);
	}
	
	if((fabs(obj->speed) > STOPPED_LIMIT)
		|| (fabs( obj->strafeSpeed ) > STOPPED_LIMIT)
		|| (fabs( obj->vertSpeed ) > STOPPED_LIMIT))
	{
		move[X] = frames * (obj->speed * cos(RAD(obj->angles[Z]))
			+ obj->strafeSpeed
			* cos(RAD(obj->angles[Z] + (float)90.0)));
		move[Y] = frames * (obj->speed * sin(RAD(obj->angles[Z]))
			+ obj->strafeSpeed
			* sin(RAD(obj->angles[Z] + (float)90.0)));
		move[Z] = frames * obj->vertSpeed;
	}
	else
	{
		move[X] = move[Y] = move[Z] = 0.0;
	}
	
	/* apply friction */
	if(!(obj->type & O_NOFRIC))
	{
		for (i = 0; i < frames; ++i)
		{
			obj->speed *= Level->force;
			obj->strafeSpeed *= Level->force;
			obj->vertSpeed *= Level->force;
		}
	}
	
	/* adjust the bounding box */
	if(crouch)
	{
		if(!obj->param[2])
			obj->maxs[Z] -= 20;
	}
	else
	{
		if(obj->param[2])
			obj->maxs[Z] += 20;
	}
	
	/* set the animation */
	if((run == !obj->param[1])||(crouch == !obj->param[2]))
	{
		if(run)
		{
			obj->param[1] = TRUE;
			if(crouch)
			{
				gi.AnimationSetNext(obj->animation, FRAME_crwalk1, FRAME_crwalk6, -1);
				gi.AnimationSetLoop(obj->animation, TRUE);
				obj->param[2] = TRUE;
			}
			else
			{
				gi.AnimationSetNext(obj->animation, FRAME_run1, FRAME_run6, -1);
				gi.AnimationSetLoop(obj->animation, TRUE);
				obj->param[2] = FALSE;
			}
		}
		else
		{
			obj->param[1] = FALSE;
			if(crouch)
			{
				gi.AnimationSetNext(obj->animation, FRAME_crstnd01, FRAME_crstnd19, -1);
				gi.AnimationSetLoop(obj->animation, TRUE);
				obj->param[2] = TRUE;
			}
			else
			{
				gi.AnimationSetNext(obj->animation, FRAME_stand01, FRAME_stand40, -1);
				gi.AnimationSetLoop(obj->animation, TRUE);
				obj->param[2] = FALSE;
			}
		}
	}

	playerMove(obj, move);
	
	/* now process other effects */
	obj->param[0] -= frames;
	if((obj->event&EV_SHOOT)&&(obj->param[0] <=0))
	{
		obj->param[0] = 15;
		G_objShoot(obj);
	}
}

void SP_info_player_start(entity_t *entity)
{
	OBJECT		*player;


	if(Level->view[0]->object)
	{
		if(ValueForKey(entity, "targetname"))
			return;
	}

	player = gi.ObjectAdd();

	/* set the player start info */
	GetVectorForKey (entity, "origin", player->origin);
	player->angles[Z] = FloatForKey(entity, "angle");
	player->mins[X] = -16;
	player->mins[Y] = -16;
	player->mins[Z] = -24;
	player->maxs[X] = 16;
	player->maxs[Y] = 16;
	player->maxs[Z] = 32;
	player->pitch = 0;
	player->radius = 16;
	player->height = 24;
	player->speed = 0;
	player->maxspeed = 20;
	player->strafeSpeed = 0;
	player->vertSpeed = 0;
	player->classname = "player";
	player->turn = 2;
	player->acc = 2;
	player->type = O_PLAYER;
	player->next = NULL;
	player->model = gi.ModelLoad("players/male/tris.md2");
	player->weapon = gi.ModelLoad("players/male/weapon.md2");
	player->animation = gi.AnimationAdd();
	gi.AnimationSetDefault(player->animation, FRAME_stand01, FRAME_stand40);
	player->update = M_PlayerUpdate;

	Level->view[0]->object = player;
	if(Level->view[1])
		Level->view[1]->object = player;
}

void SP_info_player_deathmatch (int e)
{
}

void SP_info_player_coop (int e)
{
}

void SP_info_player_intermission (int e)
{
}

⌨️ 快捷键说明

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