Pong Game computer controlled paddle

Hi there,

I know the ‘pong’ type of game has been done to death but I am just starting out with Corona/Lua I thought its an easy game to get started with? I’ve managed to code most of the game from other tutorials but I am stuck on two things:

1: My onPostCollision function throws the following error:
main.lua:94: attempt to index local ‘e’ (a nil value)

But the game runs and scores are updated

2: I want the ‘topPaddle’ to be controlled by the game but I don’t know how-to code the AI for this

Here’s my code:

[code]
H = display.contentHeight
W = display.contentWidth
display.setStatusBar(display.HiddenStatusBar)

require(“physics”)
physics.start()
physics.setGravity(0, 0)
score1text = display.newText(“0”, W/4, H/2 - 20, “Arial”, 40)
score1text:setTextColor(0,200,0)
score2text = display.newText(“0”, W/4*3, H/2 - 20, “Arial”, 40)
score2text:setTextColor(0,200,0)
local score1 = 0
local score2 = 0

function main()
createPaddles()
createBall()
createWalls()
startGame()
onPostCollision()
end

function createPaddles()
local bottomPaddleWidth = 120
local bottomPaddleHeight = 20
local topPaddleWidth = 120
local topPaddleHeight = 20
local topPaddle = display.newRect(display.contentWidth /2 - topPaddleWidth /2, display.contentHeight - 995, topPaddleWidth, topPaddleHeight)
physics.addBody(topPaddle, “static”, {bounce = 1, friction})

local moveTopPaddle = function(event)
topPaddle.x = event.x
end
local bottomPaddle = display.newRect(display.contentWidth /2 - bottomPaddleWidth /2, display.contentHeight - 50, bottomPaddleWidth, bottomPaddleHeight)
physics.addBody(bottomPaddle, “static”, {bounce = 1, friction =1})

local moveBottomPaddle = function(event)
bottomPaddle.x = event.x
end

Runtime:addEventListener(“touch”, moveBottomPaddle)
Runtime:addEventListener(“touch”, moveTopPaddle)

end

function createBall()
local ballRadius = 15

ball = display.newCircle(display.contentWidth /2, display.contentHeight / 2, ballRadius )
physics.addBody(ball, “dynamic”, {friction = 0, bounce = 1.3, radius=ballRadius})

ball.collision = function(self,event)
if(event.phase == “ended”) then
if(event.other.type == “destructible”) then
event.other:removeSelf( )
self = nil
end
if(event.other.type == “bottomWall” or (event.other.type == “topWall”)) then
self:removeSelf( )
self = nil
local onTimerComplete = function(event)
createBall( )
startGame()
end
timer.performWithDelay( 500, onTimerComplete, 1 )
end
end
end
ball:addEventListener( “collision”, ball)
ball:addEventListener(“postCollision”, onPostCollision)

end

function onPostCollision(e)
if (e.other.type == “topWall”) then
score2 = score2 + 1
score2text.text = score2
elseif (e.other.type == “bottomWall”) then
score1 = score1 + 1
score1text.text = score1

end
end

function startGame()
ball:setLinearVelocity( 75, 150 )
end

function createWalls()
local wallThickness = 10
– left wall
local leftWall = display.newRect(0,0, wallThickness, display.contentHeight)
physics.addBody(leftWall,“static”, {friction = 0, bounce = 1} )
– top wall
topWall = display.newRect(0,0, display.contentWidth, wallThickness)
physics.addBody(topWall,“static”, {friction = 0, bounce = 0})
– right wall
local rightWall = display.newRect(display.contentWidth - wallThickness, 0, wallThickness, display.contentHeight )
physics.addBody(rightWall, “static”, {friction = 0 , bounce = 1})
– bottom wall
bottomWall = display.newRect(0, display.contentHeight - wallThickness, display.contentWidth, wallThickness)
physics.addBody(bottomWall, “static”, {friction = 0, bounce = 0})
bottomWall.type = “bottomWall”
topWall.type = “topWall”
end
main()

Any help will be greatly appreciated.

[import]uid: 167310 topic_id: 30029 reply_id: 330029[/import]

I just want to give my thoughts about a simple AI idea for your game.

Make a function where the AI paddle tries to get AI.paddle.x = Ball.x , but add in some kind of acceleration term and max speed to the AI.paddle, so it has trouble converging to AI.paddle.x = Ball.x as it has a low movement speed at first.

Additionally you could try to make calculations on where the ball will move after hitting the side walls and let AI move towards this location - this could improve your AI a lot, maybe to much :wink:
[import]uid: 162464 topic_id: 30029 reply_id: 120260[/import]

Hi,

I actually have created a pong style game with AI.

See:
Android: https://play.google.com/store/apps/details?id=com.razmobi.footballpingpongworldcup
IOS: http://itunes.apple.com/us/app/football-ping-pong-soccer/id531605539?ls=1&mt=8

As Zwonkie said, Basically at runtime, get the balls x value, and get the paddles x value. then apply x movement to the paddle through the runtime listener based on below.

If the X value of the ball < paddle, move the paddles x to a minus value to whatever speed value you want the paddle to move.
and visa versa.

Hope that helps.

Chris. [import]uid: 59172 topic_id: 30029 reply_id: 120268[/import]

Thanks Zwonkie and Chris for the information I’ll give it a go and see how I get on.

Lloyd [import]uid: 167310 topic_id: 30029 reply_id: 120287[/import]

Hi there,

I think I’ve written the function correctly for the cpu paddle?

function aiPaddle()  
  
local paddleSpeed = 3  
if(topPaddle.x \< ball.x - 10) then  
 topPaddle.x = topPaddle.x + paddleSpeed  
elseif(topPaddle.x \> ball.x + 10) then  
topPaddle.x + topPaddle.x - paddleSpeed  
end  
  
Runtime:addEvenListener("move", aiPaddle)  

However, the topPaddle doesn’t move when the code is run what I am doing wrong?

Thanks [import]uid: 167310 topic_id: 30029 reply_id: 120460[/import]

Try to change to this instead:

[code]
Runtime:addEvenListener(“move”, aiPaddle)

– TO:

Runtime:addEvenListener(“enterFrame”, aiPaddle)

[/code] [import]uid: 162464 topic_id: 30029 reply_id: 120471[/import]

Yep that worked there’s a slight typo in my code

  
Runtime:addEvenListener("enterFrame", aiPaddle)  

should be:

Runtime:addEventListener("enterFrame", aiPaddle)  

Also I needed to make the topPaddle a global variable instead of a local variable for the aiPaddle function to work. [import]uid: 167310 topic_id: 30029 reply_id: 120476[/import]

Cool, is it working sufficiently? or is the AI to “smart”? [import]uid: 162464 topic_id: 30029 reply_id: 120478[/import]

No it’s working fine AI isn’t too smart!! I’ve made so the ball bounce increases with each hit so gives me a chance to win sometimes. I may refine the AI a little more as I gain more experience with Corona/Lua but for now I am happy with what I have. [import]uid: 167310 topic_id: 30029 reply_id: 120485[/import]

I just want to give my thoughts about a simple AI idea for your game.

Make a function where the AI paddle tries to get AI.paddle.x = Ball.x , but add in some kind of acceleration term and max speed to the AI.paddle, so it has trouble converging to AI.paddle.x = Ball.x as it has a low movement speed at first.

Additionally you could try to make calculations on where the ball will move after hitting the side walls and let AI move towards this location - this could improve your AI a lot, maybe to much :wink:
[import]uid: 162464 topic_id: 30029 reply_id: 120260[/import]

Hi,

I actually have created a pong style game with AI.

See:
Android: https://play.google.com/store/apps/details?id=com.razmobi.footballpingpongworldcup
IOS: http://itunes.apple.com/us/app/football-ping-pong-soccer/id531605539?ls=1&mt=8

As Zwonkie said, Basically at runtime, get the balls x value, and get the paddles x value. then apply x movement to the paddle through the runtime listener based on below.

If the X value of the ball < paddle, move the paddles x to a minus value to whatever speed value you want the paddle to move.
and visa versa.

Hope that helps.

Chris. [import]uid: 59172 topic_id: 30029 reply_id: 120268[/import]

Thanks Zwonkie and Chris for the information I’ll give it a go and see how I get on.

Lloyd [import]uid: 167310 topic_id: 30029 reply_id: 120287[/import]

Hi there,

I think I’ve written the function correctly for the cpu paddle?

function aiPaddle()  
  
local paddleSpeed = 3  
if(topPaddle.x \< ball.x - 10) then  
 topPaddle.x = topPaddle.x + paddleSpeed  
elseif(topPaddle.x \> ball.x + 10) then  
topPaddle.x + topPaddle.x - paddleSpeed  
end  
  
Runtime:addEvenListener("move", aiPaddle)  

However, the topPaddle doesn’t move when the code is run what I am doing wrong?

Thanks [import]uid: 167310 topic_id: 30029 reply_id: 120460[/import]

Try to change to this instead:

[code]
Runtime:addEvenListener(“move”, aiPaddle)

– TO:

Runtime:addEvenListener(“enterFrame”, aiPaddle)

[/code] [import]uid: 162464 topic_id: 30029 reply_id: 120471[/import]

Yep that worked there’s a slight typo in my code

  
Runtime:addEvenListener("enterFrame", aiPaddle)  

should be:

Runtime:addEventListener("enterFrame", aiPaddle)  

Also I needed to make the topPaddle a global variable instead of a local variable for the aiPaddle function to work. [import]uid: 167310 topic_id: 30029 reply_id: 120476[/import]

Cool, is it working sufficiently? or is the AI to “smart”? [import]uid: 162464 topic_id: 30029 reply_id: 120478[/import]

No it’s working fine AI isn’t too smart!! I’ve made so the ball bounce increases with each hit so gives me a chance to win sometimes. I may refine the AI a little more as I gain more experience with Corona/Lua but for now I am happy with what I have. [import]uid: 167310 topic_id: 30029 reply_id: 120485[/import]