Using Python in the Blender Game Engine - Part 8: AI
안녕하소~! MazeCrawl 게임을 위한 8번째 문서로 적군의 AI를 다룬다. 우리는 이것에 대해서 많은 것을 다루지는 않을 것이다. -아주 간단하다.
우리는 적을 파괴하기 위해서 총알을 발사하는 Player를 가지고 있다. 그리고 Player가 적과 접촉하면 게임을 다시 시작한다. 이제, 적군을 보다 더 영리하게 만들어 보자!
우리는 적군이 Player를 위협하기위해서 그를 향해 이동하도록 코드를 변경할 것이다. 이렇게 하는 것은 실제로 전혀 어렵지 않다. 하지만 적군을 만드는 것을 어렵지 않다. 그는 많은 방법에서 재사용될 수 있는 약간의 훌륭한 개념을 설명할 것이다. 자! 이제 Enemy의 소스코드를 보도록 하자!
---------------------------------------------------------------------------------------------
from bge import logic
from bge import events
from math import *
from mathutils import *
def Enemy():
cont = logic.getCurrentController()
sce = logic.getCurrentScene()
obj = cont.owner
bulletcol = cont.sensors['BulletCol']
player = sce.objects['Player']
def Init():
if not 'init' in obj:
obj['init'] = 1
obj['hp'] = 3 # Set your HP at the beginning
obj['target'] = player # Set your target to default to the Player
obj['movespd'] = 0.1
def Update():
if bulletcol.positive:
obj['hp'] -= 1 # Decrement your HP one
bullet = bulletcol.hitObject # Get the bullet you collided with
bullet.endObject() # And destroy it
tp = obj['target'].position
op = obj.position
a = atan2(op.y - tp.y, op.x - tp.x) + (pi * 0.5)
# Get the angle between the enemy
# and the target (defaults to the player), and add half a rotation to it (line above)
# Create a simple Euler angle representing the rotation of the Enemy (line above)
o = Euler([0, 0, a])
obj.worldOrientation = o # And set the enemy's orientation to the angle (face the target; line above)
obj.applyMovement([0, obj['movespd'], 0], 1) # Move towards the Player
if obj['hp'] <= 0: # If you have 0 HP
obj.endObject() # Then destroy yourself
Init()
Update()
----------------------------------------------------------------------------------------
보시다 시피, 변한 것은 거의 없다. 첫 번째로, 우리는 mathutils와 math 모듈을 모두 import시켰다. 하지만, 이 방법은 너무 많이 사용하면 좋지 않다. 그 다음으로, 우리는 Enemy 함수 정의를 보게 된다.
player = sce.objects['Player']
이 다음으로, 우리는 참조 변수로써 player를 얻는다. 이 다음으로 Init() 함수에서, 우리는 적군의 타깃으로 Player를 설정했다. 또한, 우리는 새로운 movespd 변수를 정의했다. 이 변수는 적군이 얼마나 빠르게 Player를 향해 이동하는지를 나타낸다. 가장 큰 변화는 Update()함수의 아래와 같은 부분이다.:
tp = obj['target'].position
op = obj.position
a = atan2(op.y - tp.y, op.x - tp.x) + (pi * 0.5)
o = Euler([0, 0, a]) # Create a simple Euler angle
obj.worldOrientation = o # And set it to the angle
obj.applyMovement([0, obj['movespd'], 0], 1)
보시다 시피, 우리는 타깃의 위치와 Enemy 오브젝트의 위치를 구했다. 만약에 여러분이 고등학교의 geometry를 기억한다면, 전체 회전은 2 pi에 의해서 형성된다. 절반의 회전은 pi 이다. 또한, 하나의 point로부터 다른 point까지의 각도를 얻기 위해서, 우리는 arc tangent 함수( atan2() )를 사용한다. Enemy의 위치로부터 타깃(Player)의 위치를 빼기 함으로써, 우리는 적군과 Player의 각도를 얻게 된다. 그런 후에, 이동 방향과 회전 방향이 같도록 pi의 절반 정도 회전시킨다.
우리가 정확한 각도를 가지고 있다면, 우리는 Euler 함수를 사용해 새로운 각도를 만든다. -이것은 실제로 mathutils.Euler이다. 하지만 우리가 mathutils 모듈의 전부를 import시켰기 때문에 그 부분을 입력하지 않는다. 우리는 적군이 Player를 향하도록, Z축을 기준으로 회전하도록 설정한다. 마지막으로, 우리는 적군이 향하는 방향(Player 방향)으로 local 축을 기준으로 이동시켰다. 그게 다다! -적군은 이제 Player와 부딪칠 때까지 추적한다.:D
Anyway, that's it. Download Part 8 of the MazeCrawl source code here.
MazeCrawlPart8-AI.zip