enemy.cpp

来自「一个symbian 冒险游戏代码」· C++ 代码 · 共 1,167 行 · 第 1/4 页

CPP
1,167
字号
	setState( BODY_IDLE );
}

void Enemy::updateRun( Fix dt )
{
	const Fix speed = m_speed;

	FixVec2 dir = directionVector();
	FixVec2 delta = dir * ( dt * speed );
	delta.y *= m_map->blockDimensionsRatio();

	Surface& s = bodyAnim( NULL, NULL );
	s.setFrameRateModifier( Fix( speed.v >> 7 ) ); // speed 128 => frame rate modifier 1.0 => 100% frame rate

	if ( !m_map->testPointCollision( m_pos, delta, dir ) )
	{
		setPosition( position() + delta );
		if ( --m_collisionCount < 0 ) m_collisionCount = 0;
	}
	else
	{
		m_collisionCount += 2;
		restorePosition();
	}
}

void Enemy::updateBackUp( Fix dt )
{
	if ( m_backUpTime <= Fixf(0) ) return;
	m_backUpTime -= dt;

	const Fix speed = m_speed * Fixf(0.3);

	FixVec2 dir = -directionVector();
	FixVec2 delta = dir * ( dt * speed );
	delta.y *= m_map->blockDimensionsRatio();

	Surface& s = bodyAnim( NULL, NULL );
	s.setFrameRateModifier( Fix( speed.v >> 7 ) ); // speed 128 => frame rate modifier 1.0 => 100% frame rate

	if ( !m_map->testPointCollision( m_pos, delta, dir ) )
	{
		setPosition( position() + delta );
		if ( --m_collisionCount < 0 ) m_collisionCount = 0;
	}
	else
	{
		m_collisionCount += 2;
		restorePosition();
		m_backUpTime = Fixf(0);
	}
}

void Enemy::updateAttack( Fix dt )
{
	const Surface& s = bodyAnim( NULL, NULL );
	Fix damagetime = s.endTime()*Fixf(0.5);
	if ( m_time > damagetime && m_time <= damagetime+dt )
		tryAttack();

	if ( m_time > s.endTime() )
		stand();
}

void Enemy::updateDeath( Fix /*dt*/ )
{
	if ( animEnded() )
	{
		setState( BODY_DEAD, true );
	}
}

void Enemy::damage( Fix hp, MapObject* /*enemy*/ )
{
	m_hitpoints -= hp;

	if ( m_hitpoints.v <= 0 )
		die();
	else
		hit();
}

void Enemy::disturb( MapObject* /*enemy*/ )
{
}

void Enemy::tryAttack()
{
	MapObject* objlist[4];
	FixVec2 pos = position();
	int objs = getObjects( pos, m_attackRange, m_attackAngle, objlist, sizeof(objlist) / sizeof(objlist[0]) );

	bool attacked = false;
	for ( int i = 0 ; i < objs ; ++i )
	{
		if ( isSkillSuccess(m_attackSkill) )
		{
			objlist[i]->damage( m_attackDamage, this );
			attacked = true;
		}
		else
		{
			objlist[i]->disturb( this );
		}
	}
	
	m_attackCounter++;
	if ( attacked ) m_attackHitCounter++;
}

void Enemy::updateHit( Fix /*dt*/ )
{
	if ( animEnded() )
		stand();
}

void Enemy::updateWait( Fix dt )
{
	m_waitTime -= dt;
}

void Enemy::resetStatisticsCombat( bool combatGreen )
{
	m_attackTime = Fixf(0);
	m_backUpTime = Fixf(0);
	m_waitTime = Fixf(0);
	m_attackCounter = 0;
	m_attackHitCounter = 0;
	m_hitPointMarker = m_hitpoints.toInt();
	m_combatGreen = combatGreen;
}

void Enemy::resetStatisticsFlee()
{
	m_hitPointMarker = m_hitpoints.toInt();
}

bool Enemy::animEnded() const
{
	const Surface& s = bodyAnim( NULL, NULL );
	return m_time > s.endTime();
}

const char* Enemy::toString( Enemy::EnemyType type )
{
	return TYPE_NAMES[type];
}

Enemy::EnemyType Enemy::toEnemyType( const char* sz )
{
	for ( int i = 0 ; i < ENEMY_COUNT ; ++i )
		if ( !strcmp(sz,toString(EnemyType(i))) )
			return EnemyType(i);
	throwError( Exception(Format("enemy type {0} invalid", sz)) );
	return EnemyType(0);
}

bool Enemy::isInterruptable()
{
	return	m_state != BODY_HIT &&
			m_state != BODY_ATTACK &&
			m_state != BODY_DEATH &&
			m_state != BODY_DEAD;
}

void Enemy::initStatic()
{
	GameApp* app = GameApp::get();

	ImageResample* resampler = app->getImageResamplingEngine();
	bool halfRes = app->isHalfResolution();

	//Ghoul
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_0].loadCustom( expandPath("data/anims/ghoul/ghoul_idle_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_315].loadCustom( expandPath("data/anims/ghoul/ghoul_idle_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_270].loadCustom( expandPath("data/anims/ghoul/ghoul_idle_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_90].loadCustom( expandPath("data/anims/ghoul/ghoul_idle_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_45].loadCustom( expandPath("data/anims/ghoul/ghoul_idle_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_135] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_180] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_225] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_IDLE][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_0, 23, 71 );                 
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_315, 28, 71 );               
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_270, 30, 70 );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_90, 30, 63 );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_45, 28, 65 );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_225, 28, 71 );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_180, 23, 71 );
	app->setEnemyAnimationReferencePoint(ENEMY_GHOUL, ANIM_IDLE, DIR_135, 28, 65 );
	
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_0].loadCustom( expandPath("data/anims/ghoul/ghoul_death_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_315].loadCustom( expandPath("data/anims/ghoul/ghoul_death_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_270].loadCustom( expandPath("data/anims/ghoul/ghoul_death_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_90].loadCustom( expandPath("data/anims/ghoul/ghoul_death_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_45].loadCustom( expandPath("data/anims/ghoul/ghoul_death_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_135] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_180] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_225] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_DEATH][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_0, 78, 86 );                 
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_315, 81, 72 );               
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_270, 54, 67 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_90, 59, 79 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_45, 75, 75 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_225, 81, 72 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_180, 78, 86 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_DEATH, DIR_135, 75, 75 );

	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_0].loadCustom( expandPath("data/anims/ghoul/ghoul_walk_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_315].loadCustom( expandPath("data/anims/ghoul/ghoul_walk_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_270].loadCustom( expandPath("data/anims/ghoul/ghoul_walk_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_90].loadCustom( expandPath("data/anims/ghoul/ghoul_walk_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_45].loadCustom( expandPath("data/anims/ghoul/ghoul_walk_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_135] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_180] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_225] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_RUN][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_0, 27, 69 );                 
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_315, 27, 70 );               
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_270, 32, 71 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_90, 24, 68 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_45, 26, 67 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_225, 27, 70 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_180, 27, 69 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_RUN, DIR_135, 26, 67 );
	
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_0].loadCustom( expandPath("data/anims/ghoul/ghoul_hit_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_315].loadCustom( expandPath("data/anims/ghoul/ghoul_hit_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_270].loadCustom( expandPath("data/anims/ghoul/ghoul_hit_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_90].loadCustom( expandPath("data/anims/ghoul/ghoul_hit_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_45].loadCustom( expandPath("data/anims/ghoul/ghoul_hit_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_135] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_180] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_225] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_ATTACK][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_0, 42, 80 );                 
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_315, 27, 79 );               
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_270, 27, 75 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_90, 43, 97 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_45, 53, 80 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_225, 27, 79 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_180, 42, 80 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_ATTACK, DIR_135, 53, 80 );

	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_0].loadCustom( expandPath("data/anims/ghoul/ghoul_gethit_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_315].loadCustom( expandPath("data/anims/ghoul/ghoul_gethit_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_270].loadCustom( expandPath("data/anims/ghoul/ghoul_gethit_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_90].loadCustom( expandPath("data/anims/ghoul/ghoul_gethit_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_45].loadCustom( expandPath("data/anims/ghoul/ghoul_gethit_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_135] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_180] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_225] = Surface( app->enemyAnims[ENEMY_GHOUL][ANIM_HIT][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_0, 33, 80 );                 
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_315, 28, 75 );               
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_270, 35, 67 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_90, 33, 81 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_45, 35, 78 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_225, 28, 75 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_180, 33, 80 );
	app->setEnemyAnimationReferencePoint( ENEMY_GHOUL, ANIM_HIT, DIR_135, 35, 78 );

	//Ogre
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_0].loadCustom( expandPath("data/anims/ogre/ogre_idle_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_315].loadCustom( expandPath("data/anims/ogre/ogre_idle_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_270].loadCustom( expandPath("data/anims/ogre/ogre_idle_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_90].loadCustom( expandPath("data/anims/ogre/ogre_idle_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_45].loadCustom( expandPath("data/anims/ogre/ogre_idle_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_135] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_180] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_225] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_IDLE][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_0, 12, 83 );                 
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_315, 19, 83 );               
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_270, 27, 79 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_90, 29, 81 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_45, 21, 84 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_225, 19, 83 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_180, 12, 83 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_IDLE, DIR_135, 21, 84 );

	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_0].loadCustom( expandPath("data/anims/ogre/ogre_death_e.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_315].loadCustom( expandPath("data/anims/ogre/ogre_death_se.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_270].loadCustom( expandPath("data/anims/ogre/ogre_death_s.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_90].loadCustom( expandPath("data/anims/ogre/ogre_death_n.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_45].loadCustom( expandPath("data/anims/ogre/ogre_death_ne.nan"), resampler, halfRes );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_135] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_45], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_180] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_0], Surface::FLAG_MIRROR );
	app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_225] = Surface( app->enemyAnims[ENEMY_OGRE][ANIM_DEATH][DIR_315], Surface::FLAG_MIRROR );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_0, 132, 81 );                 
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_315, 106, 83 );               
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_270, 49, 81 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_90, 38, 127 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_45, 104, 94 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_225, 106, 83 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_180, 132, 81 );
	app->setEnemyAnimationReferencePoint(ENEMY_OGRE, ANIM_DEATH, DIR_135, 104, 94 );

⌨️ 快捷键说明

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