Display Group Issue

Hi,

Sorry for all the code, I’m not sure how to insert it so it formats correctly online…

I’m trying to get a brickbreaker game (tutorial) that I found online to work with the director class but I’m having issues with the display groups I think.

When I first tried to compile it I got the error ‘Module game1 must return a display.newGroup()’ so I made a new display group and returned it at the end but then nothing displayed. So I inserted the other two display groups in the game (bricks and alertScreen) but I still get the same error? What am I doing wrong? I’ve worked with the director class and display groups before but can’t see what’s going wrong here.

Thanks a lot for any help! :slight_smile:
module(…, package.seeall)

local physics = require ‘physics’
physics.start()
physics.setGravity(0, 0)

– Variables

local BRICK_W = 41
local BRICK_H = 21
local OFFSET = 23
local W_LEN = 8
local SCORE_CONST = 100
local score = 0
local bricks = display.newGroup()
local xSpeed = 5
local ySpeed = -5
local xDir = 1
local yDir = 1
local gameEvent = ‘’
local currentLevel = 1
local background = display.newImage(‘bg.png’)

– Game Screen

local paddle
local brick
local ball

– Score/Level Text

local scoreText
local scoreNum
local levelText
local levelNum

– AlertScreen

local alertScreen
local alertBg
local box
local titleTF
local msgTF

– Levels

local levels = {}

levels[1] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0},}

levels[2] = {{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,1,0,0,1,0,0},
{0,0,0,0,0,1,0,0},
{0,0,0,0,1,0,0,0},
{0,0,0,1,0,0,0,0},
{0,0,1,0,0,0,0,0},
{0,0,1,1,1,1,0,0},}

levels[3] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,1,0,0,0,0,1,0},
{0,1,1,1,1,1,1,0},
{0,1,0,1,1,0,1,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0},}

levels[4] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1},}

– Functions

local addMenuScreen = {}
local tweenMS = {}
local hideAbout = {}
local rmvAbout = {}
local addGameScreen = {}
local buildLevel = {}
local movePaddle = {}
local gameListeners = {}
local startGame = {}
local update = {}
local bounce = {}
local removeBrick = {}
local alert = {}
local restart = {}
local changeLevel = {}

function new()

localGroup = display.newGroup()
–localGroup:insert(alertScreen)
–localGroup:insert(bricks)

paddle = display.newImage(‘paddle.png’)
ball = display.newImage(‘ball.png’)

paddle.x = 160
paddle.y = 460
ball.x = 160
ball.y = 446

paddle.name = ‘paddle’
ball.name = ‘ball’

– Build Level Bricks

buildLevel(levels[1])

– Text

scoreText = display.newText(‘Score:’, 5, 2, ‘akashi’, 14)
scoreText:setTextColor(254, 203, 50)
scoreNum = display.newText(‘0’, 54, 2, ‘akashi’, 14)
scoreNum:setTextColor(254,203,50)

levelText = display.newText(‘Level:’, 260, 2, ‘akashi’, 14)
levelText:setTextColor(254, 203, 50)
levelNum = display.newText(‘1’, 307, 2, ‘akashi’, 14)
levelNum:setTextColor(254,203,50)

– Start Listener

background:addEventListener(‘tap’, startGame)

end

function movePaddle:accelerometer(e)

– Accelerometer Movement

paddle.x = display.contentCenterX + (display.contentCenterX * (e.xGravity*3))

– Borders

if((paddle.x - paddle.width * 0.5) < 0) then
paddle.x = paddle.width * 0.5
elseif((paddle.x + paddle.width * 0.5) > display.contentWidth) then
paddle.x = display.contentWidth - paddle.width * 0.5
end
end

function buildLevel(level)

– Level length, height

local len = table.maxn(level)
bricks:toFront()

for i = 1, len do
for j = 1, W_LEN do
if(level[i][j] == 1) then
local brick = display.newImage(‘brick.png’)
brick.name = ‘brick’
brick.x = BRICK_W * j - OFFSET
brick.y = BRICK_H * i
physics.addBody(brick, {density = 1, friction = 0, bounce = 0})
brick.bodyType = ‘static’
bricks.insert(bricks, brick)
end
end
end
end

function gameListeners(action)
if(action == ‘add’) then
Runtime:addEventListener(‘accelerometer’, movePaddle)
Runtime:addEventListener(‘enterFrame’, update)
paddle:addEventListener(‘collision’, bounce)
ball:addEventListener(‘collision’, removeBrick)
– Used to drag the paddle on the simulator
paddle:addEventListener(‘touch’, dragPaddle)

else
Runtime:removeEventListener(‘accelerometer’, movePaddle)
Runtime:removeEventListener(‘enterFrame’, update)
paddle:removeEventListener(‘collision’, bounce)
ball:removeEventListener(‘collision’, removeBrick)
– Used to drag the paddle on the simulator
paddle:removeEventListener(‘touch’, dragPaddle)

end
end

– Used to drag the paddle on the simulator

function dragPaddle(e)
if(e.phase == ‘began’) then
lastX = e.x - paddle.x
elseif(e.phase == ‘moved’) then
paddle.x = e.x - lastX
end
end

function startGame:tap(e)
background:removeEventListener(‘tap’, startGame)
gameListeners(‘add’)
– Physics
physics.addBody(paddle, {density = 1, friction = 0, bounce = 0})
physics.addBody(ball, {density = 1, friction = 0, bounce = 0})
paddle.bodyType = ‘static’
end

function bounce(e)
ySpeed = -5

– Paddle Collision, check the which side of the paddle the ball hits, left, right

if((ball.x + ball.width * 0.5) < paddle.x) then
xSpeed = -5
elseif((ball.x + ball.width * 0.5) >= paddle.x) then
xSpeed = 5
end
end

function removeBrick(e)

– Check the which side of the brick the ball hits, left, right

if(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) < (e.other.x + e.other.width * 0.5)) then
xSpeed = -5
elseif(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) >= (e.other.x + e.other.width * 0.5)) then
xSpeed = 5
end
– Bounce, Remove
if(e.other.name == ‘brick’) then
ySpeed = ySpeed * -1
e.other:removeSelf()
e.other = nil
bricks.numChildren = bricks.numChildren - 1
– Score
score = score + 1
scoreNum.text = score * SCORE_CONST
scoreNum:setReferencePoint(display.CenterLeftReferencePoint)
scoreNum.x = 54
end

– Check if all bricks are destroyed

if(bricks.numChildren < 0) then
alert(’ You Win!’, ’ Next Level ›’)
gameEvent = ‘win’
end
end

function update(e)

– Ball Movement

ball.x = ball.x + xSpeed
ball.y = ball.y + ySpeed

– Wall Collision

if(ball.x < 0) then ball.x = ball.x + 3 xSpeed = -xSpeed end–Left
if((ball.x + ball.width) > display.contentWidth) then ball.x = ball.x - 3 xSpeed = -xSpeed end–Right
if(ball.y < 0) then ySpeed = -ySpeed end–Up
if(ball.y + ball.height > paddle.y + paddle.height) then alert(’ You Lose’, ’ Play Again ›’) gameEvent = ‘lose’ end–down/lose
end

function alert(t, m)
gameListeners(‘remove’)

alertBg = display.newImage(‘alertBg.png’)
box = display.newImage(‘alertBox.png’, 90, 202)

transition.from(box, {time = 300, xScale = 0.5, yScale = 0.5, transition = easing.outExpo})

titleTF = display.newText(t, 0, 0, ‘akashi’, 19)
titleTF:setTextColor(254,203,50)
titleTF:setReferencePoint(display.CenterReferencePoint)
titleTF.x = display.contentCenterX
titleTF.y = display.contentCenterY - 15

msgTF = display.newText(m, 0, 0, ‘akashi’, 12)
msgTF:setTextColor(254,203,50)
msgTF:setReferencePoint(display.CenterReferencePoint)
msgTF.x = display.contentCenterX
msgTF.y = display.contentCenterY + 15

box:addEventListener(‘tap’, restart)

alertScreen = display.newGroup()
alertScreen:insert(alertBg)
alertScreen:insert(box)
alertScreen:insert(titleTF)
alertScreen:insert(msgTF)

end

function restart(e)
if(gameEvent == ‘win’ and table.maxn(levels) > currentLevel) then
currentLevel = currentLevel + 1
changeLevel(levels[currentLevel])–next level
levelNum.text = tostring(currentLevel)
elseif(gameEvent == ‘win’ and table.maxn(levels) <= currentLevel) then
box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil
alert(’ Game Over’, ’ Congratulations!’)
gameEvent = ‘finished’
elseif(gameEvent == ‘lose’) then
changeLevel(levels[currentLevel])–same level
elseif(gameEvent == ‘finished’) then
addMenuScreen()

transition.from(menuScreen, {time = 300, y = -menuScreen.height, transition = easing.outExpo})

box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil

currentLevel = 1

scoreText:removeSelf()
scoreText = nil
scoreNum:removeSelf()
scoreNum = nil
levelText:removeSelf()
levelText = nil
levelNum:removeSelf()
levelNum = nil
ball:removeSelf()
ball = nil
paddle:removeSelf()
paddle = nil

score = 0

end
end

function changeLevel(level)

– Clear Level Bricks

bricks:removeSelf()

bricks.numChildren = 0
bricks = display.newGroup()

– Remove Alert

box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil

– Reset Ball and Paddle position

ball.x = (display.contentWidth * 0.5) - (ball.width * 0.5)
ball.y = (paddle.y - paddle.height) - (ball.height * 0.5) -2

paddle.x = display.contentWidth * 0.5

– Redraw Bricks

buildLevel(level)

– Start

background:addEventListener(‘tap’, startGame)

return localGroup

end

[import]uid: 120751 topic_id: 29346 reply_id: 329346[/import]

Just an FYI…
To properly format code, you can put a < code > tag at the beginning and a < /code > at the end. That will make the code render better in the browser.

If it is LUA code, you could do < lua > and < /lua > instead.

(Remove the spaces in the tags - I had to do that so they wouldn’t actually do the formatting in my message.) [import]uid: 17827 topic_id: 29346 reply_id: 117969[/import]

Thanks for that. Will note down for future posts! [import]uid: 120751 topic_id: 29346 reply_id: 117991[/import]

You should be able to edit your original post and add the code tags. [import]uid: 19626 topic_id: 29346 reply_id: 118026[/import]

Nope, for some reason it won’t let me edit my original post, I can only edit my last post…Bit strange.

Lets try the code formatted then

[lua]module(…, package.seeall)

local physics = require ‘physics’
physics.start()
physics.setGravity(0, 0)

– Variables

local BRICK_W = 41
local BRICK_H = 21
local OFFSET = 23
local W_LEN = 8
local SCORE_CONST = 100
local score = 0
local bricks = display.newGroup()
local xSpeed = 5
local ySpeed = -5
local xDir = 1
local yDir = 1
local gameEvent = ‘’
local currentLevel = 1
local background = display.newImage(‘bg.png’)

– Game Screen

local paddle
local brick
local ball

– Score/Level Text

local scoreText
local scoreNum
local levelText
local levelNum

– AlertScreen

local alertScreen
local alertBg
local box
local titleTF
local msgTF

– Levels

local levels = {}

levels[1] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,0},
{0,0,0,1,1,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0},}

levels[2] = {{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,1,0,0,1,0,0},
{0,0,0,0,0,1,0,0},
{0,0,0,0,1,0,0,0},
{0,0,0,1,0,0,0,0},
{0,0,1,0,0,0,0,0},
{0,0,1,1,1,1,0,0},}

levels[3] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,1,0,0,0,0,1,0},
{0,1,1,1,1,1,1,0},
{0,1,0,1,1,0,1,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0},}

levels[4] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1},}

– Functions

local addMenuScreen = {}
local tweenMS = {}
local hideAbout = {}
local rmvAbout = {}
local addGameScreen = {}
local buildLevel = {}
local movePaddle = {}
local gameListeners = {}
local startGame = {}
local update = {}
local bounce = {}
local removeBrick = {}
local alert = {}
local restart = {}
local changeLevel = {}

function new()

localGroup = display.newGroup()
–localGroup:insert(alertScreen)
–localGroup:insert(bricks)

paddle = display.newImage(‘paddle.png’)
ball = display.newImage(‘ball.png’)

paddle.x = 160
paddle.y = 460
ball.x = 160
ball.y = 446

paddle.name = ‘paddle’
ball.name = ‘ball’

– Build Level Bricks

buildLevel(levels[1])

– Text

scoreText = display.newText(‘Score:’, 5, 2, ‘akashi’, 14)
scoreText:setTextColor(254, 203, 50)
scoreNum = display.newText(‘0’, 54, 2, ‘akashi’, 14)
scoreNum:setTextColor(254,203,50)

levelText = display.newText(‘Level:’, 260, 2, ‘akashi’, 14)
levelText:setTextColor(254, 203, 50)
levelNum = display.newText(‘1’, 307, 2, ‘akashi’, 14)
levelNum:setTextColor(254,203,50)

– Start Listener

background:addEventListener(‘tap’, startGame)

end

function movePaddle:accelerometer(e)

– Accelerometer Movement

paddle.x = display.contentCenterX + (display.contentCenterX * (e.xGravity*3))

– Borders

if((paddle.x - paddle.width * 0.5) < 0) then
paddle.x = paddle.width * 0.5
elseif((paddle.x + paddle.width * 0.5) > display.contentWidth) then
paddle.x = display.contentWidth - paddle.width * 0.5
end
end

function buildLevel(level)

– Level length, height

local len = table.maxn(level)
bricks:toFront()

for i = 1, len do
for j = 1, W_LEN do
if(level[i][j] == 1) then
local brick = display.newImage(‘brick.png’)
brick.name = ‘brick’
brick.x = BRICK_W * j - OFFSET
brick.y = BRICK_H * i
physics.addBody(brick, {density = 1, friction = 0, bounce = 0})
brick.bodyType = ‘static’
bricks.insert(bricks, brick)
end
end
end
end

function gameListeners(action)
if(action == ‘add’) then
Runtime:addEventListener(‘accelerometer’, movePaddle)
Runtime:addEventListener(‘enterFrame’, update)
paddle:addEventListener(‘collision’, bounce)
ball:addEventListener(‘collision’, removeBrick)
– Used to drag the paddle on the simulator
paddle:addEventListener(‘touch’, dragPaddle)

else
Runtime:removeEventListener(‘accelerometer’, movePaddle)
Runtime:removeEventListener(‘enterFrame’, update)
paddle:removeEventListener(‘collision’, bounce)
ball:removeEventListener(‘collision’, removeBrick)
– Used to drag the paddle on the simulator
paddle:removeEventListener(‘touch’, dragPaddle)

end
end

– Used to drag the paddle on the simulator

function dragPaddle(e)
if(e.phase == ‘began’) then
lastX = e.x - paddle.x
elseif(e.phase == ‘moved’) then
paddle.x = e.x - lastX
end
end

function startGame:tap(e)
background:removeEventListener(‘tap’, startGame)
gameListeners(‘add’)
– Physics
physics.addBody(paddle, {density = 1, friction = 0, bounce = 0})
physics.addBody(ball, {density = 1, friction = 0, bounce = 0})
paddle.bodyType = ‘static’
end

function bounce(e)
ySpeed = -5

– Paddle Collision, check the which side of the paddle the ball hits, left, right

if((ball.x + ball.width * 0.5) < paddle.x) then
xSpeed = -5
elseif((ball.x + ball.width * 0.5) >= paddle.x) then
xSpeed = 5
end
end

function removeBrick(e)

– Check the which side of the brick the ball hits, left, right

if(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) < (e.other.x + e.other.width * 0.5)) then
xSpeed = -5
elseif(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) >= (e.other.x + e.other.width * 0.5)) then
xSpeed = 5
end
– Bounce, Remove
if(e.other.name == ‘brick’) then
ySpeed = ySpeed * -1
e.other:removeSelf()
e.other = nil
bricks.numChildren = bricks.numChildren - 1
– Score
score = score + 1
scoreNum.text = score * SCORE_CONST
scoreNum:setReferencePoint(display.CenterLeftReferencePoint)
scoreNum.x = 54
end

– Check if all bricks are destroyed

if(bricks.numChildren < 0) then
alert(’ You Win!’, ’ Next Level ›’)
gameEvent = ‘win’
end
end

function update(e)

– Ball Movement

ball.x = ball.x + xSpeed
ball.y = ball.y + ySpeed

– Wall Collision

if(ball.x < 0) then ball.x = ball.x + 3 xSpeed = -xSpeed end–Left
if((ball.x + ball.width) > display.contentWidth) then ball.x = ball.x - 3 xSpeed = -xSpeed end–Right
if(ball.y < 0) then ySpeed = -ySpeed end–Up
if(ball.y + ball.height > paddle.y + paddle.height) then alert(’ You Lose’, ’ Play Again ›’) gameEvent = ‘lose’ end–down/lose
end

function alert(t, m)
gameListeners(‘remove’)

alertBg = display.newImage(‘alertBg.png’)
box = display.newImage(‘alertBox.png’, 90, 202)

transition.from(box, {time = 300, xScale = 0.5, yScale = 0.5, transition = easing.outExpo})

titleTF = display.newText(t, 0, 0, ‘akashi’, 19)
titleTF:setTextColor(254,203,50)
titleTF:setReferencePoint(display.CenterReferencePoint)
titleTF.x = display.contentCenterX
titleTF.y = display.contentCenterY - 15

msgTF = display.newText(m, 0, 0, ‘akashi’, 12)
msgTF:setTextColor(254,203,50)
msgTF:setReferencePoint(display.CenterReferencePoint)
msgTF.x = display.contentCenterX
msgTF.y = display.contentCenterY + 15

box:addEventListener(‘tap’, restart)

alertScreen = display.newGroup()
alertScreen:insert(alertBg)
alertScreen:insert(box)
alertScreen:insert(titleTF)
alertScreen:insert(msgTF)

end

function restart(e)
if(gameEvent == ‘win’ and table.maxn(levels) > currentLevel) then
currentLevel = currentLevel + 1
changeLevel(levels[currentLevel])–next level
levelNum.text = tostring(currentLevel)
elseif(gameEvent == ‘win’ and table.maxn(levels) <= currentLevel) then
box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil
alert(’ Game Over’, ’ Congratulations!’)
gameEvent = ‘finished’
elseif(gameEvent == ‘lose’) then
changeLevel(levels[currentLevel])–same level
elseif(gameEvent == ‘finished’) then
addMenuScreen()

transition.from(menuScreen, {time = 300, y = -menuScreen.height, transition = easing.outExpo})

box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil

currentLevel = 1

scoreText:removeSelf()
scoreText = nil
scoreNum:removeSelf()
scoreNum = nil
levelText:removeSelf()
levelText = nil
levelNum:removeSelf()
levelNum = nil
ball:removeSelf()
ball = nil
paddle:removeSelf()
paddle = nil

score = 0

end
end

function changeLevel(level)

– Clear Level Bricks

bricks:removeSelf()

bricks.numChildren = 0
bricks = display.newGroup()

– Remove Alert

box:removeEventListener(‘tap’, restart)
alertScreen:removeSelf()
alertScreen = nil

– Reset Ball and Paddle position

ball.x = (display.contentWidth * 0.5) - (ball.width * 0.5)
ball.y = (paddle.y - paddle.height) - (ball.height * 0.5) -2

paddle.x = display.contentWidth * 0.5

– Redraw Bricks

buildLevel(level)

– Start

background:addEventListener(‘tap’, startGame)

return localGroup

end[/lua] [import]uid: 120751 topic_id: 29346 reply_id: 118031[/import]

You have to actually put things in to localGroup.

Try taking your existing groups, like bricks, and display objects that are not part of any group, like scoreText and such and insert them into localGroup:
localGroup:insert(bricks)
localGroup:insert(scoreText)
etc.

Director probably can’t handle an empty display group since it has nothing to direct. [import]uid: 19626 topic_id: 29346 reply_id: 118037[/import]

Thanks but I tried that. If you look to line 108 you can see the localGroup is created and under that commented out is the other lines inserting the exciting groups into one.

The reason they are commented out, is the program runs fine after I click the director error box and plays ok, but if they are not commented out, I get the same director error box but no graphics show and I get 'table expected. If this is a function call you might have used ‘.’ instead of ‘:’ error which is caused by the grouping of the groups…

Thanks [import]uid: 120751 topic_id: 29346 reply_id: 118039[/import]

If you uncomment 109, it’s going to error because alertScreen, while the variable exists, does not contain a display object. It’s ether not been created as a display.newGroup() or any other display.* object.

If you fix that error, you might get past what ever error’s you were seeing.

I would move line’s 109 and 110 towards the end of the app, perhaps just before the return localGroup statement to make sure everything is defined and the groups have content before you put the group’s into localGroup.
[import]uid: 19626 topic_id: 29346 reply_id: 118053[/import]