基于Irrlicht引擎的3D游戏实例V0.1

最近研究Irrlicht引擎,做了个demon,包含如下功能:

1)地图中央有一架3D坦克

2)坦克可以前进、后退、旋转

3)第一人称视角

4)视角随坦克同步移动、旋转

5)可以用-/+键调节坦克的速度

6)灯光效果

7)前进后退可以与旋转同时进行

8)运动过程中加减速立即生效

9)实现了简单的碰撞效果,使坦克能在地图中上下楼


以下是实现坦克移动的核心代码:

#include "CSceneNodeAnimatorFlyFree.h"
#include "os.h"
#ifndef M_PI
#define M_PI       3.14159265358979323846
#endif
namespace irr
{
namespace scene
{


//! constructor
CSceneNodeAnimatorFlyFree::CSceneNodeAnimatorFlyFree(const core::vector3df& startPoint,u32 now, const core::vector3df& direction, irr::f32 straightSpeed, core::vector3df& rotateSpeed)
	: Start(startPoint), StartTime(now), LastAnimationTime(0), firstUpdate(true),StraightSpeed(straightSpeed),RotateSpeed(rotateSpeed),Camera(0),Distance(0),Hight(0)
{
	#ifdef _DEBUG
	setDebugName("CSceneNodeAnimatorFlyFree");
	#endif
	Direction = direction;
	Direction.normalize();
}

//! make the direction more friendly with the rotation
void makeItSmooth(core::vector3df& direction, core::vector3df& rotation)
{
	core::vector3df currentPos(0,0,0);
	core::vector3df newDir = direction;
	newDir.Y = 0;
	//if( event.KeyInput.Key == KEY_KEY_W )
	{
		if( rotation.Y > 90 && rotation.Y <= 270
			||  fmod(rotation.Y,360.0f) > -270 && fmod(rotation.Y , 360) <= -90
			)
		{
			newDir.X = (-1) * tan(rotation.Y / 180.0 * M_PI);
			newDir.Z = (-1);
		}
		else
		{
			newDir.X = tan(rotation.Y / 180.0 * M_PI);
			newDir.Z = 1;
		}
	}
	if(direction.X * newDir.X + direction.Z * newDir.Z >= 0)
	{
		direction += newDir;
	}
	else
	{
		direction -= newDir;
	}
	direction.normalize();
}

//! animates a scene node
void CSceneNodeAnimatorFlyFree::animateNode(ISceneNode* node, u32 timeMs)
{
	if (!node)
		return;

	if(firstUpdate)
	{
		LastAnimationTime = StartTime;
		firstUpdate = false;
	}
	u32 diffTime = timeMs - LastAnimationTime;
	if (diffTime != 0)
	{
		core::vector3df rot = node->getRotation();
		core::vector3df pos = node->getPosition();
		if( RotateSpeed != core::vector3df(0,0,0) )
		{
			rot += RotateSpeed * diffTime;
			if (rot.X>360.f)
				rot.X=fmodf(rot.X, 360.f);
			if (rot.Y>360.f)
				rot.Y=fmodf(rot.Y, 360.f);
			if (rot.Z>360.f)
				rot.Z=fmodf(rot.Z, 360.f);
			if (rot.X<-360.f)
				rot.X=fmodf(rot.X, -360.f);
			if (rot.Y<-360.f)
				rot.Y=fmodf(rot.Y, -360.f);
			if (rot.Z<-360.f)
				rot.Z=fmodf(rot.Z, -360.f);
			node->setRotation(rot);
			makeItSmooth(Direction, rot);
		}
		
		core::vector3df rel = Direction * diffTime * StraightSpeed;
		pos += rel;
		node->setPosition(pos);
		// move the camema, current version doesn't change 'Y'
		if(Camera && Camera->getType() == ESNT_CAMERA)
		{
			core::vector3df cameraPos = Camera->getPosition();
			if(rot.Y >= -90 && rot.Y < 90)
			{
				cameraPos.X = pos.X - Distance * sin(rot.Y / 180.0 * M_PI);
				cameraPos.Z = pos.Z - Distance * cos(rot.Y / 180.0 * M_PI);
			}
			else
			{
				cameraPos.X = pos.X - Distance * sin((180.0 - rot.Y) / 180.0 * M_PI);
				cameraPos.Z = pos.Z + Distance * cos((180.0 - rot.Y) / 180.0 * M_PI);
			}
			cameraPos.Y = pos.Y + Hight;
			Camera->setPosition(cameraPos);
		}

		LastAnimationTime = timeMs;
	}
}


//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorFlyFree::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
	out->addVector3d("Direction", Direction);
}


//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorFlyFree::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	Direction = in->getAttributeAsVector3d("Direction");
}


ISceneNodeAnimator* CSceneNodeAnimatorFlyFree::createClone(ISceneNode* node, ISceneManager* newManager)
{
	CSceneNodeAnimatorFlyFree * newAnimator = 
		new CSceneNodeAnimatorFlyFree(Start,StartTime, Direction, StraightSpeed, RotateSpeed);

	return newAnimator;
}

void CSceneNodeAnimatorFlyFree::resetDirection(core::vector3df& direction)
{
	Direction = direction;
	Direction.normalize();
}
void CSceneNodeAnimatorFlyFree::resetRotateSpeed(core::vector3df& rotateSpeed)
{
	RotateSpeed = rotateSpeed;
}
void CSceneNodeAnimatorFlyFree::resetStraightSpeed(irr::f32 straightSpeed)
{
	StraightSpeed = straightSpeed;
}
core::vector3df CSceneNodeAnimatorFlyFree::getDirection()
{
	return Direction;
}
core::vector3df CSceneNodeAnimatorFlyFree::getRotateSpeed()
{
	return RotateSpeed;
}
irr::f32 CSceneNodeAnimatorFlyFree::getStraightSpeed()
{
	return StraightSpeed;
}

void CSceneNodeAnimatorFlyFree::setCamera(scene::ICameraSceneNode* camera)
{
	Camera = camera;
}
void CSceneNodeAnimatorFlyFree::setDistanceFromCamera(f32 distance)
{
	Distance = distance;
}
void CSceneNodeAnimatorFlyFree::setHightFromCamera(f32 hight)
{
	Hight = hight;
}
} // end namespace scene
} // end namespace irr


阅读更多
个人分类: 3D游戏引擎
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭