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

📄 hero.cpp

📁 仿游戏 Diablo 的源代码
💻 CPP
字号:
#include "object.h"
#define IsInMaze( a, b ) ((a)>0 && (b)>0 && (a)<MAZE_SIZE && (b)<MAZE_SIZE )

ObjectArray objects;

/*class ObjectArray{
	Object *obj[2048];
	int tail;
public:
	ObjectArray();
	int Login( Object*ptr );
	void Logout( WORD id );
};
*/
ObjectArray::ObjectArray()
{
	ZeroMemory( obj, sizeof(obj));
	tail = 1;
}

// if failed, return 0. else return id
WORD ObjectArray::Login( Object* ptr )
{
	if( ptr && tail < MAX_OBJECTS ){
		obj[tail] = ptr;
		return tail++;
	}
	else
		return 0;
}

void ObjectArray::Logout( WORD id )
{
	if( id < MAX_OBJECTS )
		obj[id] = 0;
}

/*class ActionStack : public CObject{
protected:
	int top;
	ActionInfo element[8];

public:
	ActionStack();
	
	ActionInfo* Pop( void );
	int Push( ActionInfo& );
	ActionInfo* GetTop( void );
	void Clear( void );
};
*/
//主角
ActionStack::ActionStack()
{
	top = 1;
	element[0].action = saStand;
}

//栈底元素始终不被弹出,通常是saStand
ActionInfo* ActionStack::Pop( void )
{
	if( top == 1 )
		return &element[0];
	else{
		top --;
	OutDebugInt( "pop stacktop=", top );
		return &element[top];
	}
}

//如果栈已满,则返回-1
int ActionStack::Push( ActionInfo& state )
{
	OutDebugInt( "push stacktop=", top );
	if( top == 7 )
		return -1;
	element[top] = state;
	top ++;
	return 0;
}

ActionInfo* ActionStack::GetTop( void )
{
	OutDebugInt( "gettop stacktop=", top );
	return &element[top-1];
}

//栈底元素不被清除,通常是saStand
void ActionStack::Clear( void )
{
	top = 1;
}
/////////////////////////////////////////////////////////////////////
int  Object::LoginMaze( void )
{
	id = objects.Login( this );
	maze[mx][my].sprite = id;
	return (id==0)? -1 : 0;
}

void Object::LogoutMaze( void )
{
}

int  Object::LoginCache( void )
{
	return 0;
}

void Object::LogoutCache( void )
{
}

char* Object::GetDescription( void )
{
	return NULL;
}

void Object::Interact( Interdata *in )
{
}

void Object::Update( void )
{
}
/////////////////////////////////////////////////////////////////////
static int adjust[8][2] = {{ -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, 1 }, 
					{ 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }};


Hero::Hero( int x, int y )
{
	timer = 0;
	mx = x;
	my = y;
	deltax = deltay = 0;
	dir = 0;
	saAction = saStand;
	clickDelay = 0;
}

int Hero::LoadPicture( void )
{
	int i;
	char *path = "data\\picture\\warrior\\";
	char num[4];
	char fname[100];
	
	for( i=0; i<8; i++ ){
		strcpy( fname, path );
		strcat( fname, "stand" );
		_itoa( i, num, 10 );
		strcat( fname, num );
		strcat( fname, ".ani" );
		stand[i] = LoadAnimate( fname );
		stand[i]->autoReverse = 1;
		stand[i]->SetXY( 80, 104 );
	}
	for( i=0; i<8; i++ ){
		strcpy( fname, path );
		strcat( fname, "walk" );
		_itoa( i, num, 10 );
		strcat( fname, num );
		strcat( fname, ".ani" );
		walk[i] = LoadAnimate( fname );
		walk[i]->SetXY( 80, 104 );
	}
	for( i=0; i<8; i++ ){
		strcpy( fname, path );
		strcat( fname, "fight" );
		_itoa( i, num, 10 );
		strcat( fname, num );
		strcat( fname, ".ani" );
		fight[i] = LoadAnimate( fname );
		fight[i]->SetXY( 80, 104 );
	}
	for( i=0; i<8; i++ ){
		strcpy( fname, path );
		strcat( fname, "gothit" );
		_itoa( i, num, 10 );
		strcat( fname, num );
		strcat( fname, ".ani" );
		behit[i] = LoadAnimate( fname );
		behit[i]->SetXY( 80, 104 );
	}
	currentFrame = stand[dir]->pic[0];
	return 0;
}

void Hero::UpdateStatus( ControlEvent *ce )
{
	if( ce && clickDelay == 0 && ce->what == ctMouse && saAction != saBeHit ){
		int sx, sy;
		if( saAction == saWalk ){
			sx = mx + adjust[dir][0];
			sy = my + adjust[dir][1];
		}
		else{ 
			sx = mx; sy = my;
		}
		if( ce->info[0] & MOUSE_L_DOWN ){

			if( ce->info[3] != 0 ){	//point to a target
			}
			else if((( ce->info[1] != destx && ce->info[1] != mx )
				|| ( ce->info[2] != desty && ce->info[2] != my ))
				&& IsInMaze( ce->info[1], ce->info[2] )
				&& !maze[ce->info[2]][ce->info[1]].occupied ){
				if( path.FindPath( sx, sy, ce->info[1], ce->info[2] ) != 0 ){
					asStack.Clear();
					if( saAction == saWalk ){
						destx = (WORD)ce->info[1];
						desty = (WORD)ce->info[2];
					}
					else{
						ActionInfo info;
						info.action = saWalk;
						info.destx = (WORD)ce->info[1];
						info.desty = (WORD)ce->info[2];
						info.dir = path.GetWayPoint();
						asStack.Push( info );
					}
				}
			}
		}
		else if( ce->info[0] & MOUSE_R_DOWN ){
			ActionInfo act;
			int f, x, y;
			x = ce->info[1] - sx;
			y = (ce->info[2] - sy)*10;
			if( x == 0 ){
				act.dir = ( y<0 )? 7 : 3;
			}
			else{
				if((f = ABS(y)/ABS(x)) < 4 ){
					act.dir = ( x < 0 )? 1 : 5;
				}
				else if( f > 26 ){
					act.dir = ( y < 0 )? 7 : 3;
				}
				else{
					if( x < 0 )
						act.dir = ( y<0 )? 0 : 2;
					else
						act.dir = ( y<0 )? 6 : 4;
				}
			}
			path.Clear();
			asStack.Clear();
			act.action = saFight;
			act.destx = 0;
			act.destx = 0;
			asStack.Push( act );
		}
		ce->info[0] = 0;
		clickDelay = 3;
	}
	if( clickDelay ) clickDelay --;
	if( saAction == saNothing ){
		ActionInfo *ainfo;
		ainfo = asStack.Pop();
		saAction = ainfo->action;
		if( saAction != saStand ){
			dir = ainfo->dir;
			destx = ainfo->destx;
			desty = ainfo->desty;
		}
	}
	switch( saAction ){
	case saStand:
		Stand( ce );
		break;
	case saWalk:
		Walk( ce );
		break;
	case saFight:
		Fight( ce );
		break;
	case saBeHit:
		BeHit( ce );
		break;
	}
}

void Hero::Update( )
{
	RleBitmapBlit( backScreen, WIN_WIDTH/2-80, WIN_HEIGHT/2-104, currentFrame );
}

void Hero::BeHit( ControlEvent *ce )
{
	scene.UpdateStatus( DIR_UNKNOWN );
	if( behit[dir]->GetNextFrame( &currentFrame ) == 0 )
		saAction = saNothing;
}

void Hero::Fight( ControlEvent *ce )
{
	int num;
	scene.UpdateStatus( DIR_UNKNOWN );
	if(( num = fight[dir]->GetNextFrame( &currentFrame )) == 0 )
		saAction = saNothing;
	else if( num == 10 ){
		ActionInfo *ainfo = asStack.GetTop();
		if( ainfo->action == saFight ){
			saAction = saNothing;
			fight[dir]->Restart();
		}
	}
}

void Hero::Stand( ControlEvent *ce )
{
	scene.UpdateStatus( DIR_UNKNOWN );
	if( timer & 1 )
		stand[dir]->GetNextFrame( &currentFrame );
	timer ++;
}

void Hero::Walk( ControlEvent *ce )
{
	scene.UpdateStatus( dir );
	if( walk[dir]->GetNextFrame( &currentFrame ) == 0 ){
		maze[my][mx].sprite = 0;
		mx += adjust[dir][0];
		my += adjust[dir][1];
		maze[my][mx].sprite = id;
		if( !path.IsEmpty() ) dir = path.GetWayPoint( );
		else saAction = saNothing;
	}
}

/*void Hero::Interact( )
{
}
*/

⌨️ 快捷键说明

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