Simple Objects

Hi @86lemonade68

I had tried to use your code before (I’ve re-written my controller class several times!). I can call the test method now, but as soon as I hover my mouse over the joystick control in the simulator - it crashes and says:

“Corona Runtime Error - attempt to call a nil value Do you want to relaunch the project”

What is causing this? I am doing nothing else aside from moving the mouse over the circle.

EDIT:

if I change my controller class to use joystick = {} rather than joystick = display.newGroup() then I don’t get an error. I have to use table.insert(joystick,joystick.border) and table.insert(joystick,joystick.thumb) to add display objects into the joystick table.

The only problem now is that if I set an event listener on joystick.thumb, I cannot use event.target.parent in the onTouch function.

@paulscottrobson

I created a simple test control class using your code, and it still gives me the same issue. I cannot call any of my own methods on the joystick object “Corona - attempt to call method ‘someMethod’ (a nil value)”

The controls show up fine but I’m obviously missing something important.

Difficult to say because I don’t know how you are using it - the module works, but without seeing your version of it I can’t tell you

Hi Paul, This is my demo code

main.lua

display.setStatusBar(display.HiddenStatusBar) \_G.screenWidth = display.contentWidth - (display.screenOriginX\*2) \_G.screenHeight = display.contentHeight - (display.screenOriginY\*2) \_G.screenTop = 0 + display.screenOriginY \_G.screenRight = display.contentWidth - display.screenOriginX \_G.screenBottom = display.contentHeight - display.screenOriginY \_G.screenLeft = 0 + display.screenOriginX \_G.screenCenterX = display.contentWidth/2 \_G.screenCenterY = display.contentHeight/2 local Controls = require("controls") local joystickMove, joystickShoot local player = display.newGroup() local head = display.newRect(0,-20,10,10) local body = display.newRect(0,0,50,50) head:setFillColor(1,0,0) body:setFillColor(0,1,0) player:insert(body) player:insert(head) player.x = screenCenterX player.y = screenCenterY joystickMove = Controls:newJoystick({name="movement",x=screenLeft+60, y=screenBottom-60}) joystickShoot = Controls:newJoystick({name="shoot",x=screenRight-60,y=screenBottom-60}) local function doStuff(event) if(joystickMove.isActive) then print("Angle",joystickMove:getAngle()) -- THIS THROWS THE ERROR end end Runtime:addEventListener("enterFrame",doStuff)

And this is my controls.lua

\_G.Base =  \_G.Base or { new = function(s,...) local o = { } setmetatable(o,s) s.\_\_index = s o:initialise(...) return o end, initialise = function() end } local Controls = Base:new() function Controls:initialise(options) -- I have tried to move my newJoystick code into here - same problem end function Controls:newJoystick(options) local joystick = display.newGroup() -- Properties joystick.name = options.name joystick.maxDist = 50 joystick.snapBackSpeed = 0.7 joystick.x = options.x joystick.y = options.y -- Create the container joystick.border = display.newCircle(0,0,48) joystick.border:setFillColor  (0.6,0.6,1.0,0.18) joystick.border:setStrokeColor(0.6,0.6,1.0,1) -- Create the thumb control joystick.thumb = display.newCircle(0,0,30) joystick.thumb:setFillColor  (0.6,0.6,1.0,0.38) joystick.thumb:setStrokeColor(0.6,0.6,1.0,1) joystick.thumb.x0 = 0 joystick.thumb.y0 = 0 -- Event listeners joystick.thumb:addEventListener("touch",Controls) -- Insert parts joystick:insert(joystick.border) joystick:insert(joystick.thumb) return joystick end function Controls:touch(event) local phase = event.phase local target = event.target local parent = target.parent local ex = event.x - target.x0 local ey = event.y - target.y0 if(phase=="began") then display.getCurrentStage():setFocus(target,event.id) target.isFocus = true target.x0 = ex - target.x target.y0 = ey - target.y parent.isActive = true transition.cancel(target) elseif target.isFocus then if(phase == "moved") then parent.distance = math.sqrt (ex\*ex + ey\*ey) if parent.distance \> parent.maxDist then  parent.distance = parent.maxDist end parent.angle = ((math.atan2( ex-0,ey-0 )\*180 / math.pi) - 180 ) \* -1 parent.percent = parent.distance / parent.maxDist target.x = math.cos( math.rad(parent.angle-90) ) \* (parent.maxDist \* parent.percent)  target.y = math.sin( math.rad(parent.angle-90) ) \* (parent.maxDist \* parent.percent) elseif(phase=="ended" or phase=="cancelled") then target.x0 = 0 target.y0 = 0 target.isFocus = false display.getCurrentStage():setFocus(nil,event.id) parent.isActive = false transition.to(target,{ delay = 0, time = 200, x = 0, y = 0 }) end end end function Controls:getAngle() print("Calling getAngle") end return Controls

What have I missed?

lua OOP doesn’t work like that - it works a bit like Python’s, using the self keyword.

I’ve rewritten it at https://github.com/autismuk/Executive/blob/master/utils/d44.lua - you probably need to read through it in conjunction with this. http://www.lua.org/pil/16.html 

Fundamentally, don’t tinker with Corona objects - treat them as things you manipulate in an object.