Search code examples
vb.netvectorxnatrigonometry

Steering behaviour in XNA not working as expected


I'm reading the following page about steering AI:

http://rocketmandevelopment.com/blog/steering-behaviors-wander/

At the bottom is some code which I'm trying to covert for use in VB.NET + XNA

My code looks like this:

Sub AI()
Dim circleRadius As Single = 6.0F
Dim wanderAngle As Single = 0.0F
Dim wanderChange As Single = 1.0F
Dim enemySpeed As Single = 0.3F
Dim enemyPosistion As Vector2 = (1,1)
Dim circleMiddle As Vector2 = enemyPosistion
circleMiddle.Normalize()

circleMiddle = Vector2.Multiply(circleMiddle, circleRadius)

Dim wanderForce As New Vector2
wanderForce = Vector2.Normalize(wanderForce) * 3 ' Set length of vector
wanderForce = AngleToVector(wanderAngle)
Randomize()
wanderAngle += Rnd() * wanderChange - wanderChange * 0.5
Dim force As New Vector2
force = Vector2.Add(circleMiddle, wanderForce)
enemyPosistion += force * enemySpeed
End Sub

Private Function AngleToVector(angle As Single) As Vector2
    Return New Vector2(CSng(Math.Sin(angle)), -CSng(Math.Cos(angle)))
End Function

I realised I made a simple mistake by setting enemyPosistion to Vector2.Zero, instead I set it to (1,1) and it makes the enemy fly up and to the right. I have included a video:

https://www.youtube.com/watch?v=UZubNaEA9W0

This is more along the lines of what it should do:

https://www.youtube.com/watch?v=1wfgPCMdW2U

Can anybody tell me what I'm doing wrong?


Solution

  • You need to preserve some state across frames. At least the wanderAngle and a velocity vector. Call Randomize() only once at the beginning of the game. circleMiddle should be velocity * circleRadius. velocity should be updated at the end with circleMiddle + wanderForce and enemyPosition += velocity * enemySpeed. Honestly, this whole code looks a bit strange, mixing up some physical concepts. Forces affect a body's acceleration (together with mass), acceleration affects its velocity (together with a time step) and the velocity affects its position (together with a time step). - Nico Schertler