I’ve not been keeping up with the state of pseudo-3D in Corona as much as I should, so today I wanted to solve a problem for myself - that of 3D platforms using distorted images via path manipulation.
It’s kinda tricky and there are changes that I’m sure I’ve made to this code which should not have had any effect at all, yet they did and with a really nice outcome. The result is a platform (actually, a brick: https://www.dropbox.com/s/sii4aropyv9wyd2/brick.png?dl=0 ) that can be moved around (drag on the screen) and have it’s perspective point moved (drag the blue dot.)
Please let me know what you think (especially if I missed the boat!)
-- 2.5D io.output():setvbuf('no') -- Remove me for production code function dump(t) print("==========") for k,v in pairs(t) do print(k,v) end end local brick local group = display.newGroup() group.x, group.y = display.contentCenterX, display.contentCenterY local centre = display.newCircle( group, 0, 0, 25 ) centre.fill = {.3,.3,1} local back, front = display.newGroup(), display.newGroup() group:insert( back ) group:insert( front ) back.xScale, back.yScale = .85, .85 back.content, front.content = display.newGroup(), display.newGroup() back:insert( back.content ) front:insert( front.content ) local bricks = display.newGroup() group:insert( bricks ) bricks.x, bricks.y = display.contentCenterX, display.contentCenterY front:toFront() function centre:touch(e) if (e.phase == "began") then display.currentStage:setFocus( e.target ) e.target.hasFocus = true e.target.prev = e return true elseif (e.target.hasFocus) then local prev = e.target.prev local x, y = e.x-prev.x, e.y-prev.y group.x, group.y = group.x+x, group.y+y back.content.x, back.content.y = back.content.x-x, back.content.y-y bricks.x, bricks.y = bricks.x-x, bricks.y-y front.content.x, front.content.y = front.content.x-x, front.content.y-y brick:updatePathControls() if (e.phase == "moved") then e.target.prev = e else display.currentStage:setFocus( nil ) e.target.hasFocus = nil e.target.prev = nil end return true end return false end centre:addEventListener( "touch", centre ) local factors = { {x=-1,y=-1}, {x=-1,y=1}, {x=1,y=1}, {x=1,y=-1} } local function initPathControls( self, ctrls ) self.controls = ctrls end brick = display.newImage( bricks, "brick.png" ) brick.alpha = 1 local w, h = brick.width/2, brick.height/2 local function updatePathControls( self ) for i=1, 4 do local x, y = self.controls[i]:localToContent( 0, 0 ) x, y = self:contentToLocal( x, y ) x = x - (factors[i].x \* w) y = y - (factors[i].y \* h) self.path["x"..i], self.path["y"..i] = x, y end end brick.initPathControls = initPathControls brick.updatePathControls = updatePathControls local ctls = {} for i=1, 4 do local parent, colour = back.content, {1,0,0} if (i == 2 or i == 3) then parent=front.content colour = {0,1,0} end ctls[i] = display.newCircle( parent, w\*factors[i].x, 0, 15 ) ctls[i].index = i ctls[i].fill = colour end brick:initPathControls( ctls ) brick:updatePathControls() local a = display.newRect( back.content, 0, 0, 250, 100 ) a.fill = {1,0,0} local b = display.newRect( front.content, 0, 0, 250, 100 ) b.fill = {0,1,0,.5} local prev = nil local function touch(e) if (e.phase == "began") then else local x, y = e.x-prev.x, e.y-prev.y back.content.x, back.content.y = back.content.x+x, back.content.y+y front.content.x, front.content.y = front.content.x+x, front.content.y+y brick:updatePathControls() end prev = e return true end Runtime:addEventListener( "touch", touch )