From fd2dda06f4003f413f34728d5550be24b07fa549 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 6 Feb 2001 17:15:28 +0000 Subject: [PATCH] --- source/game/game.cpp | 1 + source/level/level.h | 5 +- source/player/player.cpp | 123 ++++++++++++++++++++++++++++++++++---- source/player/player.h | 12 +++- source/player/pmodes.cpp | 8 ++- source/player/psidle.cpp | 98 +++++++++++++++++++++++------- source/player/psidle.h | 20 ++++++- source/player/pstates.cpp | 36 ++++++----- source/player/pstates.h | 3 + 9 files changed, 250 insertions(+), 56 deletions(-) diff --git a/source/game/game.cpp b/source/game/game.cpp index fc0ec9355..f5bda7e55 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -85,6 +85,7 @@ void CGameScene::init() m_player=new ("player") CPlayer(); m_player->init(); + m_player->setLayerCollision(Level.getCollisionLayer()); CAnimDB::LoadAnims(); diff --git a/source/level/level.h b/source/level/level.h index 4fbbe08e5..14d1b59ac 100644 --- a/source/level/level.h +++ b/source/level/level.h @@ -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(); diff --git a/source/player/player.cpp b/source/player/player.cpp index fd3412e50..6d9ccfa42 100644 --- a/source/player/player.cpp +++ b/source/player/player.cpp @@ -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;iGet(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; } diff --git a/source/player/player.h b/source/player/player.h index fa297b261..fa2e96a75 100644 --- a/source/player/player.h +++ b/source/player/player.h @@ -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; }; diff --git a/source/player/pmodes.cpp b/source/player/pmodes.cpp index 395ef7724..67148ef15 100644 --- a/source/player/pmodes.cpp +++ b/source/player/pmodes.cpp @@ -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 diff --git a/source/player/psidle.cpp b/source/player/psidle.cpp index 031103e35..f27656df4 100644 --- a/source/player/psidle.cpp +++ b/source/player/psidle.cpp @@ -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); - } } diff --git a/source/player/psidle.h b/source/player/psidle.h index a066b7472..b09117af5 100644 --- a/source/player/psidle.h +++ b/source/player/psidle.h @@ -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); diff --git a/source/player/pstates.cpp b/source/player/pstates.cpp index a62bd6261..11564341c 100644 --- a/source/player/pstates.cpp +++ b/source/player/pstates.cpp @@ -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(); diff --git a/source/player/pstates.h b/source/player/pstates.h index 46769b685..bd344a06a 100644 --- a/source/player/pstates.h +++ b/source/player/pstates.h @@ -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);