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

📄 sprite.cpp

📁 吃豆子游戏源码
💻 CPP
字号:
/**
 *	File	:	Sprite.h
 *  Author	:	Kevin Lynx
 *	Date	:	2007/7/30
 */
#include "stdafx.h"
#include "Sprite.h"
#include "World.h"
#include "AnimManager.h"
#include "App.h"

/////////////////////////////////////////////////////////////////////////////////////
//
//	SpriteStatus class
//
/////////////////////////////////////////////////////////////////////////////////////
SpriteStatus::SpriteStatus()
{
	mBeginTime = 0;
	mKeepTime = 0;
	mStatus = NORMAL;
	mBornBeginTime = 0;
	mBornKeepTime = 0;
}

void	SpriteStatus::changeStatus( int curStatus, int spriteType )
{
	u32 curTime = App::GetSingletonPtr()->getRealTime();

	if( curStatus == NORMAL || curStatus == DEAD )
	{
		mBeginTime = App::GetSingletonPtr()->getRealTime();
	}

	if( curStatus == NORMAL )
	{
		/// so , change to dead
		mStatus = DEAD;
		if( spriteType == Sprite::ST_PLAYER )
		{
			mKeepTime = PLAYER_DEAD_TIME;
		}
		else
		{
			mKeepTime = MONSTER_DEAD_TIME;
		}
	}
	else if( curStatus == DEAD )
	{
		/// and, change to born
		mStatus = BORN_SHOW;
		mBeginTime = curTime;
		mKeepTime = SPRITE_BORN_TIME;
		mBornBeginTime = mBeginTime;
		mBornKeepTime = SPRITE_SHOW_TIME;
	}
	else if( curStatus == BORN_SHOW )
	{
		/// change to BORN_HIDE
		mStatus = BORN_HIDE;
		mBornBeginTime = curTime;
		mBornKeepTime = SPRITE_HIDE_TIME;
	}
	else if( curStatus == BORN_HIDE )
	{
		/// change to born show
		mStatus = BORN_SHOW;
		mBornBeginTime = curTime;
		mBornKeepTime = SPRITE_SHOW_TIME;
	}
}

bool	SpriteStatus::update( int spriteType )
{
	u32 curTime = App::GetSingletonPtr()->getRealTime();
	
	if( mStatus == DEAD && curTime - mBeginTime >= mKeepTime )
	{
		changeStatus( mStatus, spriteType );
	}
	else if( ( mStatus == BORN_SHOW || mStatus == BORN_HIDE ) &&
		curTime - mBeginTime >= mKeepTime )
	{
		mStatus = NORMAL;
		return true;
	}
	else if( mStatus == BORN_SHOW &&
		curTime - mBornBeginTime >= mBornKeepTime ||
		mStatus == BORN_HIDE && curTime - mBornBeginTime >= mBornKeepTime )
	{
		changeStatus( mStatus, spriteType );
	}

	return false;
}

/////////////////////////////////////////////////////////////////////////////////////
//
//	Sprite class
//
/////////////////////////////////////////////////////////////////////////////////////
Sprite::Sprite( int type, float speed, vector3df dir ) :
	mDir( dir )
{
	mType = type;
	mSpeed = speed;
	mDir.normalize();
	mNode = 0;
	mMeshW = mMeshH = 0;
	mCollResult = 0;
	mAnimMgr = 0;

	mLastFireTime = 0;
	setFireDelay();
}

Sprite::~Sprite()
{
	if( mNode != 0 )
		mNode->remove();
	delete mAnimMgr;
}

bool	Sprite::init( ISceneManager *smgr, IAnimatedMesh *mesh, ITexture *texture )
{
	mNode = smgr->addAnimatedMeshSceneNode( mesh );
	
	if( texture != 0 )
		mNode->setMaterialTexture( 0, texture );
	mNode->setMaterialFlag( EMF_LIGHTING, false );

	aabbox3df box = mNode->getTransformedBoundingBox();
	mMeshW = box.MaxEdge.X - box.MinEdge.X;
	mMeshH = box.MaxEdge.Z - box.MinEdge.Z;
	
	mAnimMgr = new AnimManager( static_cast<IAnimatedMeshSceneNode*>( mNode ) );
	return true;
}

void	Sprite::update( float dt )
{
	vector3df curPos = mNode->getPosition();
	vector3df newPos = curPos + mDir * mSpeed * dt;
	
	setPosition( newPos );
}

void	Sprite::render()
{
}

aabbox3df Sprite::getWorldAABB()
{
	return mNode->getTransformedBoundingBox(); 
}

const vector3df Sprite::getPosition()
{
	return mNode->getPosition();
}

const vector3df Sprite::getExpPosition()
{
	const vector3df pos = getPosition();
	return vector3df( pos.X, pos.Y + mMeshH / 2, pos.Z );
}

void	Sprite::move( float dt )
{
	if( equals( mSpeed, 0.0f ) )
	{
		return ;	//speed = 0
	}

	vector3df curPos = mNode->getPosition();
	vector3df newPos = curPos + mDir * mSpeed * dt;

	/// construct a 2d box arount the new position
	rect<float> box2d( newPos.X - mMeshW / 2 - 2, newPos.Z + mMeshH / 2 + 2,	// + 2, -2 makes it bigger
					   newPos.X + mMeshW / 2 + 2, newPos.Z - mMeshH / 2 - 2 );
	
	if( mType == Sprite::ST_PLAYER )
	{
		/// make the rect smaller ....just give it a try and see what will happen
		box2d.UpperLeftCorner.X += 5;
		box2d.UpperLeftCorner.Y -= 5;
		box2d.LowerRightCorner.X -= 5;
		box2d.LowerRightCorner.Y += 5;
	}

	mCollResult = World::GetSingletonPtr()->collision( box2d, mDir );

	if( mCollResult == 0 || mCollResult >= World::STONE_COUNT )
	{
		/// move the node to new position
		//mNode->setPosition( newPos );
		setPosition( newPos );
	}
	/// other wise ignore it
	else if( mType >= World::MONSTER_2 && mType <= World::MONSTER_4 )
 	{
		cout << "Monster cannot move--it's a bug" << endl;
		setPosition( newPos );
	}
	else if( mType == Sprite::ST_PLAYER )
	{
		/// player, should adjust its position
		/// till now, these codes does not work pertectly for me . 
		/// god, the world is not perfect too..
		//World::GetSingletonPtr()->adjustPos( box2d, mDir, curPos );
		//setPosition( curPos );
	}
}

void	Sprite::setPosition( const vector3df &pos )
{
	mNode->setPosition( pos );
	mNode->updateAbsolutePosition();
}


void	Sprite::rotate( const vector3df &dir )
{
	if( equals( dir.X, -1.0f ) )
	{
		// face -x
		mNode->setRotation( vector3df( 0, 90, 0 ) );
	}
	if( equals( dir.X, 1.0f ) )
	{
		// face x
		mNode->setRotation( vector3df( 0, -90, 0 ) );
	}
	if( equals( dir.Z, -1.0f ) )
	{
		// face -z
		mNode->setRotation( vector3df( 0, 0, 0 ) );
	}
	if( equals( dir.Z, 1.0f ) )
	{
		// face x
		mNode->setRotation( vector3df( 0, 180, 0 ) );
	}

}

void	Sprite::getArrayPos( int &ax, int &az )
{
	vector3df pos = mNode->getPosition();
	World::GetSingletonPtr()->worldToMap( pos.X, pos.Z, ax, az ); 
}

vector2di Sprite::getArrayPos()
{
	int ax, az;
	getArrayPos( ax, az );
	return vector2di( ax, az );
}

void	Sprite::setFireDelay( u32 delay )
{
	if( delay != -1 )
	{
		mFireDelay = delay;
	}
	else
	{
		switch( mType )
		{
		case ST_PLAYER:
			mFireDelay = FD_PLAYER;
			break;
		case World::MONSTER_2:
			mFireDelay = FD_MONSTER2;
			break;
		case World::MONSTER_3:
			mFireDelay = FD_MONSTER3;
			break;
		case World::MONSTER_4:
			mFireDelay = FD_MONSTER4;
			break;
		default:
			mFireDelay = 0;
		}
	}
}

rect<f32> Sprite::getXZRect()
{
	vector3df pos = this->getPosition();
	return rect<f32>( pos.X - mMeshW / 2, pos.Z + mMeshH / 2,
		pos.X + mMeshW / 2, pos.Z - mMeshH / 2 );
}

void	Sprite::setVisible( bool visible )
{
	mNode->setVisible( visible );
}

AnimManager *Sprite::accessAnimMgr()
{
	return mAnimMgr;
}

ISceneNode *Sprite::accessNode()
{
	return mNode;
}

void	Sprite::setSpeed( float speed )
{
	mSpeed = speed;
}

void	Sprite::setDir( vector3df dir )
{
	mDir = dir;
}


⌨️ 快捷键说明

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