📄 hero.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( ¤tFrame ) == 0 )
saAction = saNothing;
}
void Hero::Fight( ControlEvent *ce )
{
int num;
scene.UpdateStatus( DIR_UNKNOWN );
if(( num = fight[dir]->GetNextFrame( ¤tFrame )) == 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( ¤tFrame );
timer ++;
}
void Hero::Walk( ControlEvent *ce )
{
scene.UpdateStatus( dir );
if( walk[dir]->GetNextFrame( ¤tFrame ) == 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 + -