simple(?) AI question

Hi all,
I’m new to all this and I’m fairly certain what I want to do is really easy with some fairly basic maths, I just don’t know where to start.

What I have is a little critter that wanders around the screen looking for food. When the user taps the screen an item (food) is created at that spot and the critter should then turn and head directly towards it.
The problem I have is not knowing the maths to get it to travel in a direct path rather than just the regular 8 directions.
Any help with this would be greatfully received.

Cheers
[import]uid: 7841 topic_id: 10137 reply_id: 310137[/import]

You will want to change the code to better fit your needs but this should hopefully help:

[code]

local angleBetween = function( pos1, pos2 )

local distance = { x = pos2.x - pos1.x, y = pos2.y - pos1.y }

if distance then

local angleBetween = math.atan( distance.y / distance.x )

if ( pos1.x < pos2.x ) then
angleBetween = angleBetween + math.rad( 90 )
else
angleBetween = angleBetween + math.rad( 270 )
end

if angleBetween == math.pi or angleBetween == ( math.pi * math.pi ) then
angleBetween = angleBetween - math.rad( 180 )
end

angleBetween = math.deg( angleBetween )

return angleBetween

end

return nil

end

local critter = display.newRect( 0, 0, 15, 15 )
critter:setFillColor( 255, 0, 0 )
critter.x = display.contentCenterX
critter.y = display.contentCenterY

local onTap = function( event )

if not critter.turnTransition and not critter.moveTransition then

local food = display.newCircle( 0, 0, 5 )
food:setFillColor( 0, 255, 0 )
food.x = event.x
food.y = event.y
food:toBack()

critter.currentFood = food

local onMoveComplete = function()
critter.moveTransition = nil
if critter.currentFood and critter.currentFood[“removeSelf”] then
critter.currentFood:removeSelf()
critter.currentFood = nil
end
end

local onTurnComplete = function()
critter.moveTransition = transition.to( critter, { time = 1000, x = event.x, y = event.y, onComplete = onMoveComplete } )
critter.turnTransition = nil
end

– Turn the critter to face the food
local angle = angleBetween( critter, event )
critter.turnTransition = transition.to( critter, { time = 500, rotation = angle, onComplete = onTurnComplete } )
end

end
Runtime:addEventListener( “tap”, onTap )

[/code] [import]uid: 5833 topic_id: 10137 reply_id: 36981[/import]

Excellent!! Cheers for that Graham.

One more quick question for now…
To start with I have a graphic in the centre of the screen that the user has to tap to start the game.
When it is tapped I want it to call a function to initialise the game, and remove the graphic.
How do I do this?? I’m sorry to ask such basic questions but it’s years since I did any kind of programming and then it wasn’t OO stuff like this. I’m still trying to get my head around it all.

Many thanks. [import]uid: 7841 topic_id: 10137 reply_id: 37025[/import]

Hope this helps…

[code]

local initialiseGame = function()
– do init stuff here
end

local onTap = function( event )
event.target:removeSelf()
event.target = nil

initialiseGame()
end

local startingImage = display.newImage( “image.png” )
startingImage.x = display.contentCenterX
startingImage.y = display.contentCenterY
startingImage:addEventListener( “tap”, onTap )

[/code] [import]uid: 5833 topic_id: 10137 reply_id: 37030[/import]

Hey Appletreeman,

I’ve just started here so maybe take this with a pinch of salt but i’ve noticed the Air Hockey example and the Ghosts Vs Monsters example both do this. You can find them in the code exchange. They use something called a Directors Class, which was created by a user here. You can also find this in the code exchange. However i don’t think the Air Hockey game uses the Class for the transition and that menu transition for that looks like this:

[code]
function setUpTitleScreen()

titleScreenGroup = display.newGroup()

local graphic = display.newRect( 0, 0, display.contentWidth, display.contentHeight )
graphic:setFillColor(0, 0, 0, 50)
titleScreenGroup:insert(graphic)

graphic = display.newImageRect( “titleSplash.png”, 530, 196 )
graphic.x = display.contentWidth / 2
graphic.y = display.contentHeight / 4
titleScreenGroup:insert(graphic)

graphic = display.newImageRect( “playButton.png”, 568, 224 )
graphic.x = display.contentWidth / 2
graphic.y = display.contentHeight - display.contentHeight / 4
titleScreenGroup:insert(graphic)

display.getCurrentStage():insert(titleScreenGroup)

graphic:addEventListener(“touch”, startGame)

end

function startGame(event)

titleScreenGroup:removeSelf()

resetScore() – in the case that this is a rematch
placePlayerOnePaddle()
placePlayerTwoPaddle()
placePuck(puckAvalLocation.center)
Runtime:addEventListener( “postCollision”, onPostCollision )
Runtime:addEventListener( “collision”, onCollision )
end

[code]

Hope that helped [import]uid: 26289 topic_id: 10137 reply_id: 37031[/import]

Many thanks to both of you for your invaluable help.
@Graham - I ended up working out the angle using atan2 and adjusting the critters position accordingly as I wanted it to move at the same pace regardless of distance.

Anyway… My new problem is this. When the critter reaches the food I want it to increase the score and then move the food to a new (random location).

Here is my code s far, the code for checking if the food has been eaten has been commented out as when I leave it in i get a “THEN expected near =” error, and I can’t for the life of me figure it out.

[lua]local background = display.newImage(“gfx/bg.png”)
local tapstart = display.newImage(“gfx/start.png”)
display.setStatusBar(display.HiddenStatusBar)
tapstart.x=display.contentCenterX
tapstart.y=display.contentCenterY

local onTapStart = function( event )
event.target:removeSelf()
event.target = nil
initGame()
end

function initGame()
score=0
critterSpeed=1
enemyspeed=1.5
critter = display.newCircle(display.contentCenterX, display.contentCenterY, 10)
critter:setFillColor( 150, 255, 150 )
speed=1
local foodx=(math.random (10, display.contentWidth-10))
local foody=(math.random (10, display.contentHeight-10))
food=display.newCircle(foodx, foody, 7)
food:setFillColor(150,150,0)
gameplaying=true
end

tapstart:addEventListener(“touch”, onTapStart)

function gameLoop()
if (gameplaying) then
local angle = math.atan2(food.y-critter.y ,food.x-critter.x)
critter.x = critter.x + (math.cos(angle) * speed)
critter.y = critter.y + (math.sin(angle) * speed)

–> Check to see if critter has eaten food
– if critter.x=food.x and critter.y=food.y then
– score=score+10
– food.x=(math.random (10, display.contentWidth-10))
– food.y=(math.random (10, display.contentHeight-10))
– end
end
end

Runtime:addEventListener(“enterFrame”, gameLoop)[/lua]

I also must say that I’m amazed at the fast responses and friendly atmosphere here. This place rocks. :slight_smile: [import]uid: 7841 topic_id: 10137 reply_id: 37145[/import]

Hey, sorry for the delayed response.

The problem with this line:

if critter.x=food.x and critter.y=food.y then  

Is that both of those statements will always return true ( or they would in other languages, I guess in Lua they might just crap-out with an error ) as you are using the “assignment” symbol rather than the “is equal to” symbol.

local variable = 10 -- This sets "variable" to 10  
  
if variable == 10 then -- This checks if "variable" equals 10. Note the double equals sign.  
  
end  

Give that a go and see if it works. [import]uid: 5833 topic_id: 10137 reply_id: 37606[/import]

Cheers Graham, yeah a mate at work put me right on that one. Never heard of == before.
[import]uid: 7841 topic_id: 10137 reply_id: 37802[/import]