confused by positioning of buttons

I downloaded the Simon memory game tutorial and found if very helpful with one exception. Can anyone explain how the buttons are arranged since each is not given its own x and y value? I understand (roughly) how they make it to the screen, but I can’t figure out how Corona knows to evenly space them all in a row. My goal is to use MUCH bigger buttons positioned in a 2x2 pattern.

Happy New Year Everyone!

psi

[lua]–
– Project: Simon Test

– Version: 1.0
– Managed with http://CoronaProjectManager.com

– Copyright 2011 J. A. Whye. All Rights Reserved.

– Use the following code for whatever you like.
– However, the graphic assets in this sample project
– should NOT be used for anything other than this sample code.

crawlspaceLib = require(“crawlspaceLib”)

display.setStatusBar ( display.HiddenStatusBar )
math.randomseed( os.time() )

local colorBalls = {“Blue”, “Green”, “Red”, “Yellow”}
local newSeq = {}
local mainBalls = {}
local numBalls = 6 – how many in the sequence?
local sequenceIdx = 1

local BOOP_PAUSE = 1000
local GAME_STATE = “waiting”

local LoserSound = audio.loadSound(“audio/Loser.aiff”)
local WinnerSound = audio.loadSound(“audio/Winner.aiff”)

local resetGame – forward reference for a function below

– display the option to start the game or reset after a win/loss
local function showReset(obj)
local function resetTouched(e)
if e.phase == “ended” then
if obj ~= nil then
obj:fadeOut(500, true)
end
e.target:removeEventListener ( “touch”, resetTouched )
e.target:removeSelf()
resetGame()
end
end
local resetText = display.newText( “Start Game”, 0, 0, “Helvetica”, 42 )
resetText.x = centerX
resetText.y = centerY + 400
resetText:addEventListener ( “touch”, resetTouched )
end

– make the chosen ball expand/contract and brighten/dim
local function popBall(b)
local function unPop(b)
transition.to ( b, { time=100, xScale = 1, yScale = 1, alpha = .9 } )
end
transition.to ( b, { time=100, xScale = 1.2, yScale = 1.2, alpha = 1, onComplete=unPop} )
audio.play ( b.sound )
end

– for the computer’s turn, walk through newSeq one at a time
local function playSequence()

popBall(mainBalls[newSeq[sequenceIdx]])

if sequenceIdx < #newSeq then
timer.performWithDelay( BOOP_PAUSE, playSequence )
else
GAME_STATE = “playing”
sequenceIdx = 0 – reset the idx so we can see if the player does it right
local yourTurn = display.newText( “Your Turn…”, centerX, centerY, “Helvetica”, 36 )
yourTurn:fadeIn(2000, function() yourTurn:fadeOut(4000, true) end)
end

sequenceIdx = sequenceIdx + 1

end

– create a new random sequence for each new game.
local function createSequence(numColors)
local sequence = {}
for i = 1, numColors do
sequence[#sequence+1] = colorBalls[math.random(1, #colorBalls)]
end
return sequence
end

– after a win or loss we need to reset some things to play again.
function resetGame()
sequenceIdx = 1
newSeq = createSequence(numBalls)
timer.performWithDelay( 200, playSequence )
end

– for the user’s turn we watch for win/loss conditions when user touches a ball
local function ballTouched(e)
if e.phase == “ended” then

– if we’re not in “playing” mode just ignore the touches
if GAME_STATE ~= “playing” then
return
end

popBall(e.target)

– see if the color we touched is the same as the next color in the sequence
if newSeq[sequenceIdx] == e.target.color then
local star = display.newImage(“images/Star.png”)
star.x = e.target.x
star.y = e.target.y - e.target.height
star:fadeOut(1000, true)
sequenceIdx = sequenceIdx + 1
– check and see if we’re done here with a win
if sequenceIdx > #newSeq then
GAME_STATE = “won”
audio.play ( WinnerSound )
local youWon = display.newText( “You Won!”, centerX, centerY, “Helvetica”, 36 )
showReset(youWon)
end
else
local ex = display.newImage(“images/X.png”)
ex.x = e.target.x
ex.y = e.target.y - e.target.height
ex:fadeOut(4000, true)
GAME_STATE = “lost”
audio.play ( LoserSound )
local youLost = display.newText( “You Lost! :(”, centerX, centerY, “Helvetica”, 36 )
showReset(youLost)
end

end
end

– display the four balls on the screen and tweak their parameters
local function setUpBalls()
for i=1, 4 do
local idx = colorBalls[i]
mainBalls[idx] = display.newImage(“images/” … colorBalls[i] … “.png” )
mainBalls[idx].x = 60 * i + -10
mainBalls[idx].y = 260
mainBalls[idx].alpha = .9
mainBalls[idx].color = colorBalls[i]
mainBalls[idx].sound = audio.loadSound(“audio/” … colorBalls[i] … “.aiff”)
mainBalls[idx]:addEventListener ( “touch”, ballTouched )
end
end

– create/display the balls for cheating purposes (to show the sequence on the screen)
local function displaySequence()
for i=1, #newSeq do
print (newSeq[i])
local text = display.newText( newSeq[i], 30, 150 + (20 * i), “Helvetica”, 18 )
end
end

– uncomment to cheat!
–displaySequence()

setUpBalls()

showReset(nil)
[import]uid: 39859 topic_id: 34444 reply_id: 334444[/import]

The balls are positioned on lines 137 and 137:

mainBalls[idx].x = 60 \* i + -10 mainBalls[idx].y = 260 [import]uid: 199310 topic_id: 34444 reply_id: 136937[/import]

Yes. Those lines position all the balls as a group. I can’t figure out how to position each ball in a different spot individually. :frowning: [import]uid: 39859 topic_id: 34444 reply_id: 136953[/import]

Since you are only dealing with 4 buttons, you can just manually place them. Assuming your screen is 320 px wide and 480 high and you want them near the center and your buttons are going to be as big as you can make them and they are going to fit into a square image (Not rectangle). Even if your buttons are circles, they will still be square images.

Your screen is 320 wide, divide in half, gives you a max button size of 160px wide. So you’re likely going to be dealing with 160x160 images. You will have to change the math if they are smaller.

Since Corona SDK’s default is to set the X and Y of an image at it’s center (Center Reference Point) then the center of those images will be 80px. So you can this:

button1.x = display.contentCenterX - 80  
button1.y = display.contentCenterY - 80  
button2.x = display.contentCenterX + 80  
button2.y = display.contentCenterY - 80  
button3.x = display.contentCenterX - 80  
button3.y = display.contentCenterY + 80  
button4.x = display.contentCenterX + 80  
button4.y = display.contentCenterY + 80  

assuming your buttons are named button1, button2, etc.
[import]uid: 199310 topic_id: 34444 reply_id: 136955[/import]

The balls are positioned on lines 137 and 137:

mainBalls[idx].x = 60 \* i + -10 mainBalls[idx].y = 260 [import]uid: 199310 topic_id: 34444 reply_id: 136937[/import]

Yes. Those lines position all the balls as a group. I can’t figure out how to position each ball in a different spot individually. :frowning: [import]uid: 39859 topic_id: 34444 reply_id: 136953[/import]

For the example a for loop is used, you probably know what a for loop does. It itterates through the set numbers.

In this case 1 to 4, so the loop will go 4 times giving you the numbers 1,2,3,4

For each loop the variable idx changes to the value at the position i in the list of balls “colorBalls”

then sets the position of the ball based on that, If you would want to set the position individually you should remove:

mainBalls[idx].x = 60 \* i + -10  
mainBalls[idx].y = 260  

from the loop and to it for each ball.

like this:

mainBalls[colorBalls[1]].x = 60 \* i + -10  
mainBalls[colorBalls[1]].y = 260  
  
mainBalls[colorBalls[2]].x = 60 \* i + -10  
mainBalls[colorBalls[2]].y = 360  
  
mainBalls[colorBalls[3]].x = 60 \* i + -10  
mainBalls[colorBalls[3]].y = 460  
  
mainBalls[colorBalls[4]].x = 60 \* i + -10  
mainBalls[colorBalls[4]].y = 560  

for i=1, 4 do local idx = colorBalls[i] mainBalls[idx] = display.newImage("images/" .. colorBalls[i] .. ".png" ) mainBalls[idx].x = 60 \* i + -10 mainBalls[idx].y = 260 mainBalls[idx].alpha = .9 mainBalls[idx].color = colorBalls[i] mainBalls[idx].sound = audio.loadSound("audio/" .. colorBalls[i] .. ".aiff") mainBalls[idx]:addEventListener ( "touch", ballTouched ) end

or you could simply do as Rob explained [import]uid: 134049 topic_id: 34444 reply_id: 137349[/import]

Since you are only dealing with 4 buttons, you can just manually place them. Assuming your screen is 320 px wide and 480 high and you want them near the center and your buttons are going to be as big as you can make them and they are going to fit into a square image (Not rectangle). Even if your buttons are circles, they will still be square images.

Your screen is 320 wide, divide in half, gives you a max button size of 160px wide. So you’re likely going to be dealing with 160x160 images. You will have to change the math if they are smaller.

Since Corona SDK’s default is to set the X and Y of an image at it’s center (Center Reference Point) then the center of those images will be 80px. So you can this:

button1.x = display.contentCenterX - 80  
button1.y = display.contentCenterY - 80  
button2.x = display.contentCenterX + 80  
button2.y = display.contentCenterY - 80  
button3.x = display.contentCenterX - 80  
button3.y = display.contentCenterY + 80  
button4.x = display.contentCenterX + 80  
button4.y = display.contentCenterY + 80  

assuming your buttons are named button1, button2, etc.
[import]uid: 199310 topic_id: 34444 reply_id: 136955[/import]

Hi Anakta. Thanks for the response. Is this what you meant? If so, I did not implement it correctly. Here is the complete code with the two lines commented out and the addition of 8 lines of code you suggested on lines 144 ff. I thought I put them in the correct place for the looping, but I obviously screwed up somehow.

Thanks again!

Jerry

[code]

– Project: Simon Test

– Version: 1.0
– Managed with http://CoronaProjectManager.com

– Copyright 2011 J. A. Whye. All Rights Reserved.

– Use the following code for whatever you like.
– However, the graphic assets in this sample project
– should NOT be used for anything other than this sample code.

crawlspaceLib = require(“crawlspaceLib”)

display.setStatusBar ( display.HiddenStatusBar )
math.randomseed( os.time() )

local colorBalls = {“Blue”, “Green”, “Red”, “Yellow”}
local newSeq = {}
local mainBalls = {}

local numBalls = 6 – how many in the sequence?
local sequenceIdx = 1

local BOOP_PAUSE = 1000
local GAME_STATE = “waiting”

local LoserSound = audio.loadSound(“audio/Loser.aiff”)
local WinnerSound = audio.loadSound(“audio/Winner.aiff”)

local resetGame – forward reference for a function below

– display the option to start the game or reset after a win/loss
local function showReset(obj)
local function resetTouched(e)
if e.phase == “ended” then
if obj ~= nil then
obj:fadeOut(500, true)
end
e.target:removeEventListener ( “touch”, resetTouched )
e.target:removeSelf()
resetGame()
end
end
local resetText = display.newText( “Start Game”, 0, 0, “Helvetica”, 42 )
resetText.x = centerX
resetText.y = centerY + 100
resetText:addEventListener ( “touch”, resetTouched )
end

– make the chosen ball expand/contract and brighten/dim
local function popBall(b)
local function unPop(b)
transition.to ( b, { time=100, xScale = 1, yScale = 1, alpha = .9 } )
end
transition.to ( b, { time=100, xScale = 1.2, yScale = 1.2, alpha = 1, onComplete=unPop} )
audio.play ( b.sound )
end

– for the computer’s turn, walk through newSeq one at a time
local function playSequence()

popBall(mainBalls[newSeq[sequenceIdx]])

if sequenceIdx < #newSeq then
timer.performWithDelay( BOOP_PAUSE, playSequence )
else
GAME_STATE = “playing”
sequenceIdx = 0 – reset the idx so we can see if the player does it right
local yourTurn = display.newText( “Your Turn…”, centerX, centerY, “Helvetica”, 36 )
yourTurn:fadeIn(2000, function() yourTurn:fadeOut(4000, true) end)
end

sequenceIdx = sequenceIdx + 1

end

– create a new random sequence for each new game.
local function createSequence(numColors)
local sequence = {}
for i = 1, numColors do
sequence[#sequence+1] = colorBalls[math.random(1, #colorBalls)]
end
return sequence
end

– after a win or loss we need to reset some things to play again.
function resetGame()
sequenceIdx = 1
newSeq = createSequence(numBalls)
timer.performWithDelay( 200, playSequence )
end

– for the user’s turn we watch for win/loss conditions when user touches a ball
local function ballTouched(e)
if e.phase == “ended” then

– if we’re not in “playing” mode just ignore the touches
if GAME_STATE ~= “playing” then
return
end

popBall(e.target)

– see if the color we touched is the same as the next color in the sequence
if newSeq[sequenceIdx] == e.target.color then
local star = display.newImage(“images/Star.png”)
star.x = e.target.x
star.y = e.target.y - e.target.height
star:fadeOut(1000, true)
sequenceIdx = sequenceIdx + 1
– check and see if we’re done here with a win
if sequenceIdx > #newSeq then
GAME_STATE = “won”
audio.play ( WinnerSound )
local youWon = display.newText( “You Won!”, centerX, centerY, “Helvetica”, 36 )
showReset(youWon)
end
else
local ex = display.newImage(“images/X.png”)
ex.x = e.target.x
ex.y = e.target.y - e.target.height
ex:fadeOut(4000, true)
GAME_STATE = “lost”
audio.play ( LoserSound )
local youLost = display.newText( “You Lost! :(”, centerX, centerY, “Helvetica”, 36 )
showReset(youLost)
end

end
end

– display the four balls on the screen and tweak their parameters
local function setUpBalls()
for i=1, 4 do
local idx = colorBalls[i]
mainBalls[idx] = display.newImage(“images/” … colorBalls[i] … “.png” )
–mainBalls[idx].x = 60 * i + 10
–mainBalls[idx].y = 90
mainBalls[idx].alpha = .9
mainBalls[idx].color = colorBalls[i]
mainBalls[idx].sound = audio.loadSound(“audio/” … colorBalls[i] … “.aiff”)
mainBalls[idx]:addEventListener ( “touch”, ballTouched )
end
mainBalls[colorBalls[1]].x = 60 * i + -10
mainBalls[colorBalls[1]].y = 260

mainBalls[colorBalls[2]].x = 60 * i + -10
mainBalls[colorBalls[2]].y = 360

mainBalls[colorBalls[3]].x = 60 * i + -10
mainBalls[colorBalls[3]].y = 460

mainBalls[colorBalls[4]].x = 60 * i + -10
mainBalls[colorBalls[4]].y = 560
end

– create/display the balls for cheating purposes (to show the sequence on the screen)
local function displaySequence()
for i=1, #newSeq do
print (newSeq[i])
local text = display.newText( newSeq[i], 30, 150 + (20 * i), “Helvetica”, 18 )
end
end

– uncomment to cheat!
– displaySequence()

setUpBalls()

showReset(nil)
[import]uid: 39859 topic_id: 34444 reply_id: 137425[/import]

For the example a for loop is used, you probably know what a for loop does. It itterates through the set numbers.

In this case 1 to 4, so the loop will go 4 times giving you the numbers 1,2,3,4

For each loop the variable idx changes to the value at the position i in the list of balls “colorBalls”

then sets the position of the ball based on that, If you would want to set the position individually you should remove:

mainBalls[idx].x = 60 \* i + -10  
mainBalls[idx].y = 260  

from the loop and to it for each ball.

like this:

mainBalls[colorBalls[1]].x = 60 \* i + -10  
mainBalls[colorBalls[1]].y = 260  
  
mainBalls[colorBalls[2]].x = 60 \* i + -10  
mainBalls[colorBalls[2]].y = 360  
  
mainBalls[colorBalls[3]].x = 60 \* i + -10  
mainBalls[colorBalls[3]].y = 460  
  
mainBalls[colorBalls[4]].x = 60 \* i + -10  
mainBalls[colorBalls[4]].y = 560  

for i=1, 4 do local idx = colorBalls[i] mainBalls[idx] = display.newImage("images/" .. colorBalls[i] .. ".png" ) mainBalls[idx].x = 60 \* i + -10 mainBalls[idx].y = 260 mainBalls[idx].alpha = .9 mainBalls[idx].color = colorBalls[i] mainBalls[idx].sound = audio.loadSound("audio/" .. colorBalls[i] .. ".aiff") mainBalls[idx]:addEventListener ( "touch", ballTouched ) end

or you could simply do as Rob explained [import]uid: 134049 topic_id: 34444 reply_id: 137349[/import]

Hi Anakta. Thanks for the response. Is this what you meant? If so, I did not implement it correctly. Here is the complete code with the two lines commented out and the addition of 8 lines of code you suggested on lines 144 ff. I thought I put them in the correct place for the looping, but I obviously screwed up somehow.

Thanks again!

Jerry

[code]

– Project: Simon Test

– Version: 1.0
– Managed with http://CoronaProjectManager.com

– Copyright 2011 J. A. Whye. All Rights Reserved.

– Use the following code for whatever you like.
– However, the graphic assets in this sample project
– should NOT be used for anything other than this sample code.

crawlspaceLib = require(“crawlspaceLib”)

display.setStatusBar ( display.HiddenStatusBar )
math.randomseed( os.time() )

local colorBalls = {“Blue”, “Green”, “Red”, “Yellow”}
local newSeq = {}
local mainBalls = {}

local numBalls = 6 – how many in the sequence?
local sequenceIdx = 1

local BOOP_PAUSE = 1000
local GAME_STATE = “waiting”

local LoserSound = audio.loadSound(“audio/Loser.aiff”)
local WinnerSound = audio.loadSound(“audio/Winner.aiff”)

local resetGame – forward reference for a function below

– display the option to start the game or reset after a win/loss
local function showReset(obj)
local function resetTouched(e)
if e.phase == “ended” then
if obj ~= nil then
obj:fadeOut(500, true)
end
e.target:removeEventListener ( “touch”, resetTouched )
e.target:removeSelf()
resetGame()
end
end
local resetText = display.newText( “Start Game”, 0, 0, “Helvetica”, 42 )
resetText.x = centerX
resetText.y = centerY + 100
resetText:addEventListener ( “touch”, resetTouched )
end

– make the chosen ball expand/contract and brighten/dim
local function popBall(b)
local function unPop(b)
transition.to ( b, { time=100, xScale = 1, yScale = 1, alpha = .9 } )
end
transition.to ( b, { time=100, xScale = 1.2, yScale = 1.2, alpha = 1, onComplete=unPop} )
audio.play ( b.sound )
end

– for the computer’s turn, walk through newSeq one at a time
local function playSequence()

popBall(mainBalls[newSeq[sequenceIdx]])

if sequenceIdx < #newSeq then
timer.performWithDelay( BOOP_PAUSE, playSequence )
else
GAME_STATE = “playing”
sequenceIdx = 0 – reset the idx so we can see if the player does it right
local yourTurn = display.newText( “Your Turn…”, centerX, centerY, “Helvetica”, 36 )
yourTurn:fadeIn(2000, function() yourTurn:fadeOut(4000, true) end)
end

sequenceIdx = sequenceIdx + 1

end

– create a new random sequence for each new game.
local function createSequence(numColors)
local sequence = {}
for i = 1, numColors do
sequence[#sequence+1] = colorBalls[math.random(1, #colorBalls)]
end
return sequence
end

– after a win or loss we need to reset some things to play again.
function resetGame()
sequenceIdx = 1
newSeq = createSequence(numBalls)
timer.performWithDelay( 200, playSequence )
end

– for the user’s turn we watch for win/loss conditions when user touches a ball
local function ballTouched(e)
if e.phase == “ended” then

– if we’re not in “playing” mode just ignore the touches
if GAME_STATE ~= “playing” then
return
end

popBall(e.target)

– see if the color we touched is the same as the next color in the sequence
if newSeq[sequenceIdx] == e.target.color then
local star = display.newImage(“images/Star.png”)
star.x = e.target.x
star.y = e.target.y - e.target.height
star:fadeOut(1000, true)
sequenceIdx = sequenceIdx + 1
– check and see if we’re done here with a win
if sequenceIdx > #newSeq then
GAME_STATE = “won”
audio.play ( WinnerSound )
local youWon = display.newText( “You Won!”, centerX, centerY, “Helvetica”, 36 )
showReset(youWon)
end
else
local ex = display.newImage(“images/X.png”)
ex.x = e.target.x
ex.y = e.target.y - e.target.height
ex:fadeOut(4000, true)
GAME_STATE = “lost”
audio.play ( LoserSound )
local youLost = display.newText( “You Lost! :(”, centerX, centerY, “Helvetica”, 36 )
showReset(youLost)
end

end
end

– display the four balls on the screen and tweak their parameters
local function setUpBalls()
for i=1, 4 do
local idx = colorBalls[i]
mainBalls[idx] = display.newImage(“images/” … colorBalls[i] … “.png” )
–mainBalls[idx].x = 60 * i + 10
–mainBalls[idx].y = 90
mainBalls[idx].alpha = .9
mainBalls[idx].color = colorBalls[i]
mainBalls[idx].sound = audio.loadSound(“audio/” … colorBalls[i] … “.aiff”)
mainBalls[idx]:addEventListener ( “touch”, ballTouched )
end
mainBalls[colorBalls[1]].x = 60 * i + -10
mainBalls[colorBalls[1]].y = 260

mainBalls[colorBalls[2]].x = 60 * i + -10
mainBalls[colorBalls[2]].y = 360

mainBalls[colorBalls[3]].x = 60 * i + -10
mainBalls[colorBalls[3]].y = 460

mainBalls[colorBalls[4]].x = 60 * i + -10
mainBalls[colorBalls[4]].y = 560
end

– create/display the balls for cheating purposes (to show the sequence on the screen)
local function displaySequence()
for i=1, #newSeq do
print (newSeq[i])
local text = display.newText( newSeq[i], 30, 150 + (20 * i), “Helvetica”, 18 )
end
end

– uncomment to cheat!
– displaySequence()

setUpBalls()

showReset(nil)
[import]uid: 39859 topic_id: 34444 reply_id: 137425[/import]