I have noticed that several games made with Corona SDK have a Level selection menu with a tile type interface. How exactly do I go about making this sort of thing? There isn’t much documentation about that kind of thing. Any suggestions? [import]uid: 104852 topic_id: 21095 reply_id: 321095[/import]
I’m not sure if I understand what you mean by tile type interface, but our game has a level select screen where the user can select from 20 levels per page. If this is what you are talking about then I can post some sample code. [import]uid: 16734 topic_id: 21095 reply_id: 83476[/import]
Hi,
I would appreciate it if you shared your sample code.
As for a tiled type of menu this is what I am looking for:
http://www.angrybirds-game-online.com/wp-content/uploads/2011/07/angry-birds-christmas-2.png
-Chandler Mayo [import]uid: 104852 topic_id: 21095 reply_id: 83531[/import]
Hi KenRogoway ,
Yes, I also need level selection/unlock level kind thing, please share some sample code.
Thank you in advance.
[import]uid: 83418 topic_id: 21095 reply_id: 83549[/import]
Doesn’t seem like anything too hard, just use iterators to build the level buttons and storyboard to flip pages?
[code]
local maxLevel = 20 – if you had a table of levels you could use #levels
local xPos = 20
local yPos = 40
local buttonGroup = display.newGroup() – holds all of the buttons
– Iterator time
for i = 1, maxLevel do
– Make the button. This is a fictional function but it would be very easy to make it
local button = makeButton(i)
– Set its position
button.x = xPos
button.y = yPos
– Add it to the display group
buttonGroup:insert(button)
– Increment the xPosition
if i == 5 or i == 10 or i = 15 then
– If it’s a new row, you gotta update xPos and yPos
xPos = 20
yPos = yPos + button.height + 16
else
– Just update xPos
xPos = xPos + button.width + 16
end
end[/code]
Obviously you’d have to fine tune a lot of it, but that’s a fairly simple way to build that sort of visual array. [import]uid: 41884 topic_id: 21095 reply_id: 83550[/import]
Your missing an = sign,
[lua]if (i == 5 or i == 10 or i = 15) then [/lua]
It should be,
[lua]if (i == 5 or i == 10 or i == 15) then [/lua]
-Chandler Mayo [import]uid: 104852 topic_id: 21095 reply_id: 83555[/import]
What can I do with [lua]makeButton(i)[/lua]? I am having some issues getting something to work without an error. [import]uid: 104852 topic_id: 21095 reply_id: 83557[/import]
@KenRogoway I plugged this in and after sorting through a ton of errors I am stumped by this:
Runtime error: /Users/Chandler/Desktop/gfg/main.lua:33: attempt to index global ‘cSceneLevelSelect’ (a nil value)
Its pointing to:
function cSceneLevelSelect:new()
It there a sample project I can download? [import]uid: 104852 topic_id: 21095 reply_id: 83568[/import]
Here is a fully functional Level Select scene for use with Director:
[lua]–***********************************************************************************************–
– cSceneLevelSelect
module(…, package.seeall)
– The max number of levels to show on the screen at a time
NUM_LEVELS_ON_PAGE = 20
local WhatPage = 0
– Main function - MUST return a display.newGroup()
function cSceneLevelSelect:new()
local levelSelectGroup = display.newGroup()
local updateButtons
local menuBtn
local ui = ui
– For check mark to show level is completed
local checkImages = {}
– BACKGROUND IMAGE
local backgroundImage = display.newImageRect( IMAGE_DIR…“SelectLevel.jpg”, display.contentWidth, display.contentHeight )
backgroundImage.x = display.contentCenterX
backgroundImage.y = display.contentCenterY
levelSelectGroup:insert( backgroundImage )
– Go back to the main game menu
local onMenuTouch = function( event )
if event.phase == “release” and menuBtn.isActive then
director:changeScene( “cSceneMainMenu”, “fade” )
end
return true
end
menuBtn = ui.newButton{
defaultSrc = IMAGE_DIR…“menu_menu_up.png”,
defaultX = ScaleX(200),
defaultY = ScaleY(80),
overSrc = IMAGE_DIR…“menu_menu_down.png”,
overX = ScaleX(200),
overY = ScaleY(80),
onEvent = onMenuTouch,
id = “MenuButton”,
text = “”,
font = “Helvetica”,
textColor = { 255, 255, 255, 255 },
size = 16,
emboss = false
}
menuBtn:setReferencePoint( display.CenterReferencePoint )
menuBtn.x = display.contentCenterX
menuBtn.y = display.contentHeight - ScaleY(88)
levelSelectGroup:insert( menuBtn )
local prevBtn
local onPrevTouch = function( event )
if event.phase == “release” and prevBtn.isActive then
if ( WhatPage > 0 ) then
WhatPage = WhatPage - 1
updateButtons()
end
end
return true
end
prevBtn = ui.newButton{
defaultSrc = IMAGE_DIR…“help_arrow_left_up.png”,
defaultX = ScaleX(180),
defaultY = ScaleY(150),
overSrc = IMAGE_DIR…“help_arrow_left_down.png”,
overX = ScaleX(180),
overY = ScaleY(150),
onEvent = onPrevTouch,
id = “PrevButton”,
text = “”,
font = “Helvetica”,
textColor = { 255, 255, 255, 255 },
size = 16,
emboss = false
}
prevBtn:setReferencePoint( display.CenterReferencePoint )
prevBtn.x = ScaleX(136)
prevBtn.y = ScaleY(688)
prevBtn.isVisible = false
levelSelectGroup:insert( prevBtn )
local nextBtn
local onNextTouch = function( event )
if event.phase == “release” and nextBtn.isActive then
WhatPage = WhatPage + 1
updateButtons()
end
return true
end
nextBtn = ui.newButton{
defaultSrc = IMAGE_DIR…“help_arrow_right_up.png”,
defaultX = ScaleX(180),
defaultY = ScaleY(150),
overSrc = IMAGE_DIR…“help_arrow_right_down.png”,
overX = ScaleX(180),
overY = ScaleY(150),
onEvent = onNextTouch,
id = “NextButton”,
text = “”,
font = “Helvetica”,
textColor = { 255, 255, 255, 255 },
size = 16,
emboss = false
}
nextBtn:setReferencePoint( display.CenterReferencePoint )
nextBtn.x = ScaleX(890)
nextBtn.y = ScaleY(688)
levelSelectGroup:insert( nextBtn )
local function onTapTouchGobbler( event )
return true
end
local levelPickBtn = {}
local onLevelPickedTouch = function( event )
if event.phase == “release” then
local levelNum = tonumber(event.id)
if ( levelNum <= MAX_LEVELS ) then
– print( “level “…levelNum…” was selected” )
– You need to set a global here with the level that was picked!
– Reset the count for our ads
director:changeScene( “cSceneGame”, “crossFade” )
end
end
end
for i=1,NUM_LEVELS_ON_PAGE do
levelPickBtn[i] = ui.newButton{
defaultSrc = IMAGE_DIR…“button_level_up.png”,
defaultX = ScaleX( 180 ),
defaultY = ScaleY( 130 ),
overSrc = IMAGE_DIR…“button_level_down.png”,
overX = ScaleX( 180 ),
overY = ScaleY( 130 ),
onEvent = onLevelPickedTouch,
id = string.format( “%d”, i+NUM_LEVELS_ON_PAGE*WhatPage ),
text = string.format( “%d”, i+NUM_LEVELS_ON_PAGE*WhatPage ),
font = “Helvetica”,
textColor = { 0, 0, 0, 255 },
size = ScaleY( 32 ),
emboss = true
}
– If you change NUM_LEVELS_ON_PAGE then you will need to change the next two statements
local nX = 39+191*((i-1)%5)
local nY = 96+130*math.floor((i-1)/5)
levelPickBtn[i]:setReferencePoint( display.TopLeftReferencePoint )
levelPickBtn[i].x = ScaleX( nX )
levelPickBtn[i].y = ScaleY( nY )
levelSelectGroup:insert( levelPickBtn[i] )
checkImages[i] = display.newImageRect( IMAGE_DIR…“CheckMarkYellow.png”, ScaleX(80), ScaleY(80) )
checkImages[i].x = ScaleX( nX + 48 )
checkImages[i].y = ScaleY( nY + 48 )
levelSelectGroup:insert( checkImages[i] )
if ( gWS.bLevelComplete[i] ) then
checkImages[i].isVisible = true
else
checkImages[i].isVisible = false
end
end
function updateButtons()
if ( WhatPage > 0 ) then
prevBtn.isVisible = true
else
prevBtn.isVisible = false
end
if ( ((WhatPage+1)*NUM_LEVELS_ON_PAGE) < MAX_LEVELS ) then
nextBtn.isVisible = true
else
nextBtn.isVisible = false
end
for i=1,NUM_LEVELS_ON_PAGE do
if ( (NUM_LEVELS_ON_PAGE*WhatPage+i) <= MAX_LEVELS ) then
levelPickBtn[i].isVisible = true
levelPickBtn[i]:setText( string.format( “%d”, i+NUM_LEVELS_ON_PAGE*WhatPage ) )
levelPickBtn[i]._id = i+NUM_LEVELS_ON_PAGE*WhatPage
if ( gWS.bLevelComplete[(NUM_LEVELS_ON_PAGE*WhatPage+i)] ) then
checkImages[i].isVisible = true
else
checkImages[i].isVisible = false
end
else
checkImages[i].isVisible = false
levelPickBtn[i].isVisible = false
end
end
end
updateButtons()
clean = function()
end
return levelSelectGroup
end[/lua] [import]uid: 16734 topic_id: 21095 reply_id: 83559[/import]
I’ll put together a sample app. I had just stripped out some items from my actual shipping title. Sorry if there were any errors.
[EDIT]
Here is a fully functional (and tested!) app showing how to do this:
http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLevelSelect_v1_00.zip [import]uid: 16734 topic_id: 21095 reply_id: 83570[/import]
Thanks,
I can’t test it right now but later today I will let you know if it works for me. [import]uid: 104852 topic_id: 21095 reply_id: 83578[/import]
Minor revision to display the level selected here:
http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLevelSelect_v1_01.zip [import]uid: 16734 topic_id: 21095 reply_id: 83583[/import]
Sounds like Ken has you covered. TBH I’m interested in the bits there myself
makeButton(i) was merely a fictional function; you could theoretically have something like this
[code]local makeButton = function(text)
local button = display.newGroup()
local box = display.newRect(0,0,128,128)
local title = display.newText(text, 0, 0, nil, 20)
title:setReferencePoint(display.CenterReferencePoint)
title.x, title.y = box.x, box.y
button:insert(box)
button:insert(title)
return button
end[/code]
By giving it “i” (which ends up being 1-20) each button gets a title of 1, 2, 3, 4, etc. [import]uid: 41884 topic_id: 21095 reply_id: 83585[/import]
@KenRogoway
Do you know about anyway to make it unlock levels or change the way the images look after their completion? [import]uid: 104852 topic_id: 21095 reply_id: 83610[/import]
Sorry Double Post. [import]uid: 104852 topic_id: 21095 reply_id: 83611[/import]
this is totally untested off the top of my head!
local levelsPerRow = 6
local maxLevels = 30
local gridX = 1
local gridY = 1
local iconHeight = 32
local iconWidth = 32
local iconPadding = 16
local levelButtons = {}
local currentUnlockedLevel = 5
local gridGroup = display.newGroup()
local lockedLevel = display.newImageRect("lock.png",iconWidth,iconHeight)
local function gotoLevel(event)
local lvl = event.target.name
storyboard.gotoScene(string.format("level%02d",lvl))
-- director.changeScene(string.format("level%02d",lvl))
return true
end
for i = 1, maxLevels
if i \> currentUnlockedLevel then
levelButtons[i] = lockedLevel
else
levelButtons[i] = display.newImageRect(iconImages[i]
levelButtons[i].name = i
levelButtons[i]:addEventListener("tap",gotoLevel)
end
levelButtons[i].x = (gridX - 1) \* (iconWidth + iconPadding) + (iconWidth /2 ) -- assuming center reference point
levelButtons[i].y = (gridY - 1) \* (iconHeight + iconPadding) + (iconHeight / 2)
if i % 6 == 0 then -- end of a row
gridX = 1
gridY = gridY + 1
else
gridX = gridX + 1
end
gridGroup:insert(levelButtons[i])
end
gridGroup.x = display.contentWidth / 2
gridGroup.y = display.contentHeight / 2
-- for storyboard
group:insert(gridGroup)
-- or for director
-- localGroup:insert(gridGroup)
this assumes you have an array of image filenames called iconImages that hold the icons for different levels and an image for your locked out levels.
[import]uid: 19626 topic_id: 21095 reply_id: 83636[/import]
Hi KenRogoway ,
Thank you so much for the Level Select code.
Can I use your code in my Game?
Thanks again.
Mila
[import]uid: 83418 topic_id: 21095 reply_id: 83639[/import]
Here is a version that shows “locks” on levels. Every time you enter a level it unlocks the next one. Go back to the level select and you will see it has been unlocked.
http://www.homebrewsoftware.com/Download/CoronaSDK/HomebrewLevelSelect_v1_10.zip
Yes, you can use the code in any of your projects. You cannot use the images, as they are just sample images taken from the web. [import]uid: 16734 topic_id: 21095 reply_id: 83647[/import]
Hi KenRogoway ,
Thank you so much for your sample code and kindness.
I have to bother you a question:
I want to do as below:
When Level 1 is selected, the to goto gamelevel1.lua (gamelevel1 is my game for level1), if level 2 is selected, then goto gamelevel2.lua, and so on, how can I do this with your sample code?
Thanks again.
Mila
[import]uid: 83418 topic_id: 21095 reply_id: 84649[/import]
Try this:
[lua] local onLevelPickedTouch = function( event )
if event.phase == “release” then
local levelNum = tonumber(event.id)
if ( levelNum <= MAX_LEVELS and not gWS.bLevelLocked[levelNum] ) then
print( “level “…levelNum…” was selected” )
local whatScene = string.format( “gamelevel%d”, levelNum )
– Reset the count for our ads
director:changeScene( whatScene, “crossFade” )
end
end
end[/lua] [import]uid: 16734 topic_id: 21095 reply_id: 84652[/import]