player.cpp
来自「一个symbian 冒险游戏代码」· C++ 代码 · 共 1,095 行 · 第 1/3 页
CPP
1,095 行
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SPEAR, DIR_135, 20, 78 );
//Change weapon, shotgun
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_0].loadCustom( expandPath("data/anims/hero/hero_changew_shotgun_e.nan"), resampler, halfRes );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_315].loadCustom( expandPath("data/anims/hero/hero_changew_shotgun_se.nan"), resampler, halfRes );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_270].loadCustom( expandPath("data/anims/hero/hero_changew_shotgun_s.nan"), resampler, halfRes );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_90].loadCustom( expandPath("data/anims/hero/hero_changew_shotgun_n.nan"), resampler, halfRes );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_45].loadCustom( expandPath("data/anims/hero/hero_changew_shotgun_ne.nan"), resampler, halfRes );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_135] = Surface( app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_45], Surface::FLAG_MIRROR );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_180] = Surface( app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_0], Surface::FLAG_MIRROR );
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_225] = Surface( app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][DIR_315], Surface::FLAG_MIRROR );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_0, 17, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_315, 22, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_270, 24, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_90, 24, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_45, 20, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_225, 22, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_180, 17, 78 );
app->setPlayerAnimationReferencePoint( ANIM_CHANGEWEAPON_SHOTGUN, DIR_135, 20, 78 );
for ( int k = 0 ; k < DIR_COUNT ; ++k )
{
app->playerAnims[ANIM_ATTACK_SWORD][k].setEndBehaviorStop();
app->playerAnims[ANIM_ATTACK_SPEAR][k].setEndBehaviorStop();
app->playerAnims[ANIM_ATTACK_SHOTGUN][k].setEndBehaviorStop();
app->playerAnims[ANIM_DRINK][k].setEndBehaviorStop();
app->playerAnims[ANIM_DEATH][k].setEndBehaviorStop();
app->playerAnims[ANIM_CHANGEWEAPON_SWORD][k].setEndBehaviorStop();
app->playerAnims[ANIM_CHANGEWEAPON_SPEAR][k].setEndBehaviorStop();
app->playerAnims[ANIM_CHANGEWEAPON_SHOTGUN][k].setEndBehaviorStop();
}
}
void Player::deinitStatic()
{
GameApp* app = GameApp::get();
for ( int i = 0 ; i < Player::BODY_COUNT ; ++i )
{
app->playerAnims[i][MapObject::DIR_0].destroy();
app->playerAnims[i][MapObject::DIR_45].destroy();
app->playerAnims[i][MapObject::DIR_90].destroy();
app->playerAnims[i][MapObject::DIR_270].destroy();
app->playerAnims[i][MapObject::DIR_315].destroy();
}
}
void Player::update( Fix dt )
{
const Fix idleThresholdTime = Fixf(1.5);
m_time += dt;
if ( m_time < Fixf(0) ) m_time = Fixf(0);
if ( m_time > Fixf(32000) ) m_time -= Fixf(32000);
m_speedModifyTime -= dt;
if ( m_speedModifyTime <= Fixf(0) )
{
m_speedModifyTime = Fixf(0);
m_speedModifier = Fixf(0);
}
switch ( state() )
{
case BODY_IDLE:
if ( m_virtualState == BODY_STILL )
{
if ( m_time > idleThresholdTime )
{
if ( m_weaponInHand )
{
setVirtualState( BODY_PUT_WEAPON );
Surface& s = bodyAnim( NULL, NULL );
s.setReversed( false );
}
else
{
clearVirtualState();
}
}
}
if ( m_virtualState == BODY_PUT_WEAPON )
{
if ( animEnded() )
{
clearVirtualState();
m_weaponInHand = false;
}
}
break;
case BODY_WALK_WOUNDED:
case BODY_WALK:
if ( m_virtualState == BODY_TAKE_WEAPON )
{
if ( animEnded() )
{
clearVirtualState();
m_weaponInHand = true;
}
}
if ( m_virtualState != BODY_TAKE_WEAPON )
{
if ( !m_weaponInHand )
{
setVirtualState( BODY_TAKE_WEAPON );
Surface& s = bodyAnim( NULL, NULL );
s.setReversed( true );
}
else
{
updateWalk( dt, ( m_state == BODY_WALK_WOUNDED ) );
}
}
break;
case BODY_ATTACK:
updateAttack( dt, getWeaponSkill(), getWeaponDamage(), getWeaponRange(), getWeaponAngle() );
break;
case BODY_DRINK:
if ( m_virtualState == BODY_PUT_WEAPON )
{
if ( animEnded() )
{
clearVirtualState();
m_weaponInHand = false;
}
}
if ( m_virtualState != BODY_PUT_WEAPON )
{
if ( m_weaponInHand )
{
setVirtualState( BODY_PUT_WEAPON );
Surface& s = bodyAnim( NULL, NULL );
s.setReversed( false );
}
else
{
updateDrink( dt );
}
}
break;
case BODY_DEATH:
updateDeath( dt );
break;
case BODY_TAKE_WEAPON:
if ( m_virtualState == BODY_PUT_WEAPON )
{
if ( animEnded() )
{
clearVirtualState();
m_weaponInHand = false;
}
}
if ( m_virtualState != BODY_PUT_WEAPON )
{
if ( m_weaponInHand )
{
setVirtualState( BODY_PUT_WEAPON );
Surface& s = bodyAnim( NULL, NULL );
s.setReversed( false );
}
else
{
if ( m_nextWeapon >= 0 )
{
assert( m_nextWeapon < WEAPON_COUNT );
m_currentWeapon = m_nextWeapon;
m_nextWeapon = -1;
Surface& s = bodyAnim( NULL, NULL );
s.setReversed( true );
}
if ( animEnded() )
{
setState( BODY_WALK );
m_weaponInHand = true;
}
}
}
break;
case BODY_COUNT:
assert( false );
break;
default:
break;
}
}
Fix Player::getWeaponSkill()
{
return m_weaponSkills[ m_currentWeapon ];
}
Fix Player::getWeaponDamage()
{
return m_weaponDamages[ m_currentWeapon ];
}
Fix Player::getWeaponRange()
{
return m_weaponRanges[ m_currentWeapon ];
}
Fix Player::getWeaponAngle()
{
return m_weaponAngles[ m_currentWeapon ];
}
Fix Player::getWeaponDelay()
{
return m_weaponDelays[ m_currentWeapon ];
}
Fix Player::getWeaponSlowdownFactor()
{
return m_weaponSlowdownFactors[ m_currentWeapon ];
}
void Player::setWeapon( char* name, Fix skill, Fix damage, Fix range, Fix angle, Fix delay, Fix slowdownFactor )
{
int weapon = -1;
for ( int i = 0; i < WEAPON_COUNT; i++ )
{
if ( strcmp( name, WEAPON_NAMES[ i ] ) == 0 )
{
weapon = i;
break;
}
}
if ( ( weapon >= 0 ) && ( weapon < WEAPON_COUNT ) )
{
m_weaponSkills[weapon] = skill;
m_weaponDamages[weapon] = damage;
m_weaponRanges[weapon] = range;
m_weaponAngles[weapon] = angle;
m_weaponDelays[weapon] = delay;
m_weaponSlowdownFactors[weapon] = slowdownFactor;
}
}
void Player::draw( Surface& dst )
{
const bool halfResolution = GameApp::get()->isHalfResolution();
int refX, refY;
const Surface& anim = bodyAnim( &refX, &refY );
m_previousAnim = (Surface*) &anim;
m_previousRefX = refX;
m_previousRefY = refY;
if ( anim.mirror() ) refX = -refX;
int x0 = position().x.toInt() - refX;
int y0 = position().y.toInt() - refY;
if ( halfResolution )
{
x0 >>= 1;
y0 >>= 1;
}
x0 += anim.mirror() ? ( -anim.offsetX() - anim.frameWidth() ) : anim.offsetX();
y0 += anim.offsetY();
Surface sf = anim.clipFrame( anim.getFrame( !m_freezeAnim ? m_time : Fixf(0) ) );
dst.blt( x0, y0, sf, Surface::BLEND_ALPHA1B );
//dst.blt( x0, y0, sf, Surface::BLEND_ALPHA );
m_isDrawn = true;
}
void Player::damage( Fix hp, MapObject* enemy )
{
GameApp::get()->playSound( "hero_get_hit", SoundContext::CHANNEL_OTHER );
m_hitpoints -= hp;
// 75% speed loss, duration 2 seconds
if ( m_speedModifier >= Fixf(-0.75) )
{
m_speedModifier = Fixf(-0.75);
m_speedModifyTime = Fixf(2);
}
if ( m_hitpoints.v <= 0 )
die( enemy );
else
hit();
}
void Player::disturb( MapObject* /*enemy*/ )
{
// 50% speed loss, duration 1.5 seconds
if ( m_speedModifier >= Fixf(-0.5) )
{
m_speedModifier = Fixf(-0.5);
m_speedModifyTime = Fixf(1.5);
}
}
FixVec2 Player::center() const
{
return position() - FixVec2( Fix(0), Fix::fromInt(32) );
}
Surface& Player::bodyAnim( int* refX, int* refY )
{
GameApp* app = GameApp::get();
int dir = direction();
int state = ( m_virtualState == BODY_NONE ) ? m_state : m_virtualState;
assert( m_state >= 0 && m_state < BODY_COUNT );
assert( dir >= 0 && dir < DIR_COUNT );
int animation = m_animationSwitchBoard[ state ];
if ( ( animation & ANIM_WEAPON_DEPENDENT ) != 0 )
{
int weapon = m_currentWeapon;
animation = ( ( weapon >= 0 ) && ( weapon <= WEAPON_COUNT ) ) ?
( animation & ~ANIM_WEAPON_DEPENDENT ) + weapon :
ANIM_DEFAULT;
}
assert( ( animation >= ANIM_NONE ) && ( animation < ANIM_COUNT ) );
if ( ( animation == ANIM_NONE ) && !m_previousAnim ) animation = ANIM_DEFAULT;
m_freezeAnim = false;
Surface* a = 0;
int rX = 0;
int rY = 0;
if ( animation != ANIM_NONE )
{
rX = app->playerAnimRefPoints[animation][dir][0];
rY = app->playerAnimRefPoints[animation][dir][1];
a = &app->playerAnims[animation][dir];
}
else
{
assert( m_previousAnim );
rX = m_previousRefX;
rY = m_previousRefY;
a = m_previousAnim;
m_freezeAnim = true;
}
if ( refX ) *refX = rX;
if ( refY ) *refY = rY;
assert( a->frames() > 0 );
return *a;
}
const Surface& Player::bodyAnim( int* refX, int* refY ) const
{
return const_cast<Player*>(this)->bodyAnim( refX, refY );
}
void Player::setState( BodyState state, bool endTime )
{
if ( state != m_state && m_state != BODY_DEAD )
{
int virtualState = BODY_NONE;
switch ( state )
{
case BODY_IDLE:
virtualState = BODY_STILL;
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?