Notice:本贴参加CSDN活动,帖子分数为100分,请大家多多支持,谢谢。
人工智能算法在游戏中演示
人工智能是一个非常具有潜力的分支,顾名思义,它可以通过计算机指令模拟人的行为,在游戏中的人工智能就非常地多样了。对于FPS、TAB、RPG、STG、ADV等游戏,有着不同的人工智能,但都基于几种理论:有限状态机、遗传算法、神经网络等。下面我就采用游戏中最基础也是最常用的人工智能算法来进行演示。
我的开发环境是:
Windows: WindowsXP(SP3) + MinGW4.4/MinGW4.7 + Qt4.8.3/Qt5.0.1 + QtCreator2.6/QtCreator2.7
Linux: Ubuntu12.10 + gcc4.7 + Qt4.8.1/Qt4.8.4/Qt5.0.1 + QtCreator2.6/QtCreator2.7
演示程序下载地址:这里
源代码下载地址:这里
注意:由于Qt5.0.1中一个未知的Bug,编译运行后角色无法移动,所以请使用Qt4.6+来进行编译。
程序截图如下所示:
通过子窗口的控制选项,我们可以设置我们的初音ミク、镜音リン和镜音レン的控制方法,可以选择人工控制也可以选择AI控制。如果选择人工控制,那么可以通过按下“上下左右”键控制角色的移动,如果选择AI控制,那么角色会沿着场景作顺时针移动。
整个项目的代码量较多,我将选择有关人工智能的内容进行讲解,也希望大家沿着我的思路思考下去。
首先如何让角色沿着窗口作顺时针旋转?一个简单的想法就是:当角色将要达到窗口顶端那么角色将往右移动;角色将要到达窗口右端那么角色将往下移动,以此类推。按照这样的思路,我写了这样的AI代码:
if ( m_pCharacter->pos( ).y( ) > 20.0 )
{
qDebug( "AI go Up." );
m_pCharacter->SetAnimation( Character::_Up_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).x( ) < 608.0 )
{
qDebug( "AI go Right." );
m_pCharacter->SetAnimation( Character::_Right_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).y( ) < 340.0 )
{
qDebug( "AI go Down." );
m_pCharacter->SetAnimation( Character::_Down_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).x( ) > 0.0 )
{
qDebug( "AI go Left." );
m_pCharacter->SetAnimation( Character::_Left_ );
emit TriggerTransition( );
}
这也是我AI的第一个版本,但是正如QtMikuSnake7_ver_1应用程序截图中所示,它并不能达到应有的效果,角色一直在右上角打转。看来第一个版本有问题。问题在哪儿呢?这是由于我们将向上的判定优先于向下的判定,导致了角色在右上角处转至下后又转回了右上角。了解了这个问题之后第一个想法就是为向上判定添加约束条件,使其能够在右上角处正确地转至向下判定而不会折返。下面是AI的第二个版本:
if ( m_pCharacter->pos( ).y( ) > 20.0 &&
m_pCharacter->m_Direction != Character::_Down_ )
{
qDebug( "AI go Up." );
m_pCharacter->SetAnimation( Character::_Up_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).x( ) < 608.0 &&
m_pCharacter->m_Direction != Character::_Left_ )
{
qDebug( "AI go Right." );
m_pCharacter->SetAnimation( Character::_Right_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).y( ) < 340.0 &&
m_pCharacter->m_Direction != Character::_Up_ )
{
qDebug( "AI go Down." );
m_pCharacter->SetAnimation( Character::_Down_ );
emit TriggerTransition( );
}
else if ( m_pCharacter->pos( ).x( ) > 0.0 &&
m_pCharacter->m_Direction != Character::_Right_ )