This commit is contained in:
Paul 2001-02-06 17:15:28 +00:00
parent 41a25767d9
commit fd2dda06f4
9 changed files with 250 additions and 56 deletions

View File

@ -85,6 +85,7 @@ void CGameScene::init()
m_player=new ("player") CPlayer();
m_player->init();
m_player->setLayerCollision(Level.getCollisionLayer());
CAnimDB::LoadAnims();

View File

@ -23,8 +23,9 @@ public:
void render();
void think(int _frames);
void setCameraCentre(DVECTOR _pos) {MapPos=_pos;}
static DVECTOR getCameraPos() {return MapPos;}
void setCameraCentre(DVECTOR _pos) {MapPos=_pos;}
static DVECTOR getCameraPos() {return MapPos;}
CLayerCollision *getCollisionLayer() {return CollisionLayer;}
private:
void initLayers();

View File

@ -33,6 +33,10 @@
#include "game\game.h"
#endif
#ifndef __LAYER_COLLISION_H__
#include "level\collision.h"
#endif
// to be removed
#include "gfx\tpage.h"
@ -73,6 +77,8 @@
void CPlayer::init()
{
CThing::init();
m_layerCollision=NULL;
sActor3dHdr *Hdr=m_skel.Load(ACTORS_SPONGEBOB_A3D);
m_skel.Init(Hdr);
@ -93,7 +99,7 @@ m_animFrame=0;
#ifdef __USER_paul__
Pos.vx=23*16;
Pos.vy=23*16;
Pos.vy=10*16;
#else
Pos.vx=10;
Pos.vy=10;
@ -127,13 +133,11 @@ void CPlayer::shutdown()
Returns:
---------------------------------------------------------------------- */
#ifdef __USER_paul__
DVECTOR ofs={-240,-134}; // nearly -256,-128 ;)
DVECTOR ofs={-248,-136}; // nearly -256,-128 ;)
int newmode=-1;
#else
DVECTOR ofs={0,0}; //temporary
#endif
int psize=0;
int newmode=-1;
void CPlayer::think(int _frames)
{
int i;
@ -141,11 +145,18 @@ void CPlayer::think(int _frames)
CThing::think(_frames);
#ifdef __USER_paul__
if(PadGetHeld(0)&PAD_L1&&PadGetHeld(0)&PAD_L2)
{
Pos.vx=23*16;
Pos.vy=10*16;
}
if(newmode!=-1)
{
setMode((PLAYER_MODE)newmode);
newmode=-1;
}
#endif
#ifndef __USER_paul__
int padInput=PadGetHeld(0);
@ -169,25 +180,59 @@ if(newmode!=-1)
updatePadInput();
m_currentStateClass->think(this);
// Horizontal movement
Pos.vx+=m_moveVel.vx>>VELOCITY_SHIFT;
if(Pos.vx<350)
if(m_layerCollision->Get((Pos.vx+(m_moveVel.vx>>VELOCITY_SHIFT))>>4,(Pos.vy-1)>>4))
{
// Move flush with the edge of the obstruction
int dir,vx,cx,y,i;
if(m_moveVel.vx<0)
{
dir=-1;
vx=-m_moveVel.vx;
}
else
{
dir=+1;
vx=m_moveVel.vx;
}
cx=Pos.vx;
y=(Pos.vy-1)>>4;
for(i=0;i<vx;i++)
{
if(m_layerCollision->Get(cx>>4,y))
{
break;
}
cx+=dir;
}
Pos.vx=cx-dir;
// If running then idle, otherwise leave in same state
if(m_currentState==STATE_RUN)
{
setState(STATE_IDLE);
// setAnimNo(ANIM_PLAYER_ANIM_RUNSTOP);
}
Pos.vx=350;
m_moveVel.vx=0;
}
else
{
Pos.vx+=m_moveVel.vx>>VELOCITY_SHIFT;
}
if(m_currentState==STATE_IDLE&&isOnEdge())
{
setState(STATE_IDLETEETER);
}
// Vertical movement
Pos.vy+=m_moveVel.vy>>VELOCITY_SHIFT;
if(isOnSolidGround())
{
//stick to ground (PKG)
Pos.vy=23*16+1;//16*15;
//Pos.vy=23*16+1;//16*15;
int colHeight=16;
Pos.vy=((Pos.vy-16)&0xfffffff0)+colHeight;
if(m_moveVel.vy)
{
@ -199,6 +244,7 @@ Pos.vy=23*16+1;//16*15;
else if(m_currentState==STATE_FALLFAR)
{
setState(STATE_IDLE);
m_moveVel.vx=0;
}
else if(m_moveVel.vx)
{
@ -210,15 +256,20 @@ Pos.vy=23*16+1;//16*15;
setState(STATE_IDLE);
setAnimNo(ANIM_PLAYER_ANIM_JUMPEND);
}
m_moveVel.vy=0;
// m_moveVel.vy=0;
m_fallFrames=0;
}
m_moveVel.vy=0;
}
else
{
if(m_currentState!=STATE_JUMP&&m_currentState!=STATE_BUTTBOUNCE)
{
// Fall
if(m_currentState!=STATE_FALL&&m_currentState!=STATE_BUTTFALL)
{
setState(STATE_FALL);
}
const PlayerMetrics *metrics;
metrics=getPlayerMetrics();
m_moveVel.vy+=PLAYER_GRAVITY;
@ -335,7 +386,7 @@ m_cameraOffset=ofs;
Returns:
---------------------------------------------------------------------- */
int panim=-1;
DVECTOR ppos={0,1024};
DVECTOR ppos={0,500};
#ifdef __USER_paul__
int mouth=-1,eyes=-1;
#endif
@ -547,6 +598,7 @@ int CPlayer::getPadInputDown()
return m_padInputDown;
}
/*----------------------------------------------------------------------
Function:
Purpose:
@ -555,7 +607,52 @@ int CPlayer::getPadInputDown()
---------------------------------------------------------------------- */
int CPlayer::isOnSolidGround()
{
return Pos.vy>23*16;//16*15;
ASSERT(m_layerCollision);
return m_layerCollision->Get(Pos.vx>>4,Pos.vy>>4);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns: FACING_LEFT if left half of player is hanging, FACING_RIGHT
if right half of player is hanging or 0 if no part of the
player is hanging
---------------------------------------------------------------------- */
int csize=20;
int CPlayer::isOnEdge()
{
int ret=0;
ASSERT(m_layerCollision);
if(!m_layerCollision->Get((Pos.vx-csize)>>4,Pos.vy>>4))
{
ret=FACING_LEFT;
}
else if(!m_layerCollision->Get((Pos.vx+csize)>>4,Pos.vy>>4))
{
ret=FACING_RIGHT;
}
return ret;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayer::canMoveLeft()
{
ASSERT(m_layerCollision);
return m_layerCollision->Get((Pos.vx-1)>>4,(Pos.vy-1)>>4)==0;
}
int CPlayer::canMoveRight()
{
ASSERT(m_layerCollision);
return m_layerCollision->Get((Pos.vx+1)>>4,(Pos.vy-1)>>4)==0;
}

View File

@ -49,6 +49,7 @@
typedef enum
{
STATE_IDLE,
STATE_IDLETEETER,
STATE_JUMP,
STATE_RUN,
STATE_FALL,
@ -120,11 +121,13 @@ public:
DVECTOR getCameraPos();
void setLayerCollision(class CLayerCollision *_layer) {m_layerCollision=_layer;}
protected:
enum
{
DEFAULT_PLAYER_JUMP_VELOCITY=8,
DEFAULT_PLAYER_MAX_JUMP_FRAMES=10,
DEFAULT_PLAYER_JUMP_VELOCITY=4,
DEFAULT_PLAYER_MAX_JUMP_FRAMES=12,
DEFAULT_PLAYER_MAX_SAFE_FALL_FRAMES=20,
DEFAULT_PLAYER_MAX_RUN_VELOCITY=8,
DEFAULT_PLAYER_RUN_SPEEDUP=4,
@ -153,6 +156,9 @@ protected:
// Collision
int isOnSolidGround();
int isOnEdge();
int canMoveLeft();
int canMoveRight();
// Movement
void moveLeft();
@ -224,6 +230,8 @@ private:
int m_lastPadInput; // Last frames controls
int m_padInputDown; // Controls that were pressed this frame
// Pointer to the collision layer for the current layer
class CLayerCollision *m_layerCollision;
};

View File

@ -68,8 +68,9 @@
Vars
---- */
CPlayerStateUnarmedIdle stateUnarmedIdle;
CPlayerStateCoralBlowerIdle stateCoralBlowerIdle;
CPlayerStateUnarmedIdle stateUnarmedIdle;
CPlayerStateCoralBlowerIdle stateCoralBlowerIdle;
CPlayerStateTeeterIdle stateTeeterIdle;
CPlayerStateJump stateJump;
CPlayerStateRun stateRun;
CPlayerStateFall stateFall;
@ -109,6 +110,7 @@ CPlayer::PlayerMode CPlayer::s_modes[NUM_PLAYERMODES]=
} },
{
&stateUnarmedIdle, // STATE_IDLE
&stateTeeterIdle, // STATE_IDLETEETER
&stateJump, // STATE_JUMP
&stateRun, // STATE_RUN
&stateFall, // STATE_FALL
@ -140,6 +142,7 @@ CPlayer::PlayerMode CPlayer::s_modes[NUM_PLAYERMODES]=
} },
{
&stateUnarmedIdle, // STATE_IDLE
&stateTeeterIdle, // STATE_IDLETEETER
&stateJump, // STATE_JUMP
&stateRun, // STATE_RUN
&stateFall, // STATE_FALL
@ -171,6 +174,7 @@ CPlayer::PlayerMode CPlayer::s_modes[NUM_PLAYERMODES]=
} },
{
&stateCoralBlowerIdle, // STATE_IDLE
&stateTeeterIdle, // STATE_IDLETEETER
&stateJump, // STATE_JUMP
&stateRun, // STATE_RUN
&stateFall, // STATE_FALL

View File

@ -58,6 +58,83 @@
Vars
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayerStateBaseIdle::thinkControl(CPlayer *_player)
{
int controlDown,controlHeld;
controlDown=getPadInputDown(_player);
controlHeld=getPadInputHeld(_player);
if(controlDown&CPadConfig::getButton(CPadConfig::PAD_CFG_JUMP))
{
setState(_player,STATE_JUMP);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_LEFT))
{
if(canMoveLeft(_player))
setState(_player,STATE_RUN);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_RIGHT))
{
if(canMoveRight(_player))
setState(_player,STATE_RUN);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_ACTION))
{
setState(_player,STATE_ATTACK);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_DOWN))
{
setState(_player,STATE_DUCK);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayerStateTeeterIdle::enter(CPlayer *_player)
{
int edgeType,dir;
int anim;
edgeType=isOnEdge(_player);
dir=getFacing(_player);
if(edgeType==FACING_LEFT)
{
anim=dir==FACING_LEFT?ANIM_PLAYER_ANIM_TEETERFRONT:ANIM_PLAYER_ANIM_TEETERBACK;
}
else
{
anim=dir==FACING_RIGHT?ANIM_PLAYER_ANIM_TEETERFRONT:ANIM_PLAYER_ANIM_TEETERBACK;
}
setAnimNo(_player,anim);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayerStateTeeterIdle::think(CPlayer *_player)
{
advanceAnimFrameAndCheckForEndOfAnim(_player);
thinkControl(_player);
}
/*----------------------------------------------------------------------
Function:
Purpose:
@ -82,31 +159,12 @@ void CPlayerStateIdle::enter(CPlayer *_player)
---------------------------------------------------------------------- */
void CPlayerStateIdle::think(CPlayer *_player)
{
int controlDown,controlHeld;
controlDown=getPadInputDown(_player);
controlHeld=getPadInputHeld(_player);
thinkControl(_player);
if(advanceAnimFrameAndCheckForEndOfAnim(_player))
{
setNextIdleAnim(_player);
}
if(controlDown&CPadConfig::getButton(CPadConfig::PAD_CFG_JUMP))
{
setState(_player,STATE_JUMP);
}
else if(controlHeld&(CPadConfig::getButton(CPadConfig::PAD_CFG_LEFT)|CPadConfig::getButton(CPadConfig::PAD_CFG_RIGHT)))
{
setState(_player,STATE_RUN);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_ACTION))
{
setState(_player,STATE_ATTACK);
}
else if(controlHeld&CPadConfig::getButton(CPadConfig::PAD_CFG_DOWN))
{
setState(_player,STATE_DUCK);
}
}

View File

@ -32,6 +32,24 @@
Structure defintions
-------------------- */
////
class CPlayerStateBaseIdle : public CPlayerState
{
public:
void thinkControl(class CPlayer *_player);
};
////
class CPlayerStateTeeterIdle : public CPlayerStateBaseIdle
{
public:
virtual void enter(class CPlayer *_player);
virtual void think(class CPlayer *_player);
};
////
typedef struct
{
int m_startFrame; // Or -1 for none
@ -41,7 +59,7 @@ typedef struct
} IdleAnims;
class CPlayerStateIdle : public CPlayerState
class CPlayerStateIdle : public CPlayerStateBaseIdle
{
public:
virtual void enter(class CPlayer *_player);

View File

@ -244,6 +244,26 @@ int CPlayerState::isOnSolidGround(CPlayer *_player)
{
return _player->isOnSolidGround();
}
int CPlayerState::isOnEdge(class CPlayer *_player)
{
return _player->isOnEdge();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int CPlayerState::canMoveLeft(class CPlayer *_player)
{
return _player->canMoveLeft();
}
int CPlayerState::canMoveRight(class CPlayer *_player)
{
return _player->canMoveRight();
}
/*----------------------------------------------------------------------
@ -256,26 +276,10 @@ void CPlayerState::moveLeft(CPlayer *_player)
{
_player->moveLeft();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayerState::moveRight(CPlayer *_player)
{
_player->moveRight();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void CPlayerState::slowdown(CPlayer *_player)
{
_player->slowdown();

View File

@ -58,6 +58,9 @@ protected:
int getPadInputDown(class CPlayer *_player);
int isOnSolidGround(class CPlayer *_player);
int isOnEdge(class CPlayer *_player);
int canMoveLeft(class CPlayer *_player);
int canMoveRight(class CPlayer *_player);
void moveLeft(class CPlayer *_player);
void moveRight(class CPlayer *_player);