Teleporter

Teleportation effect with Solar2D

Presentation

Here is (more or less) the code used to manage the teleportation effect in our game (you know when Mario enters a pipe and reappears a little further).
It should be noted that the SumBeams effect does not work on all phones.
My Samsung Galaxy J3 does not manage it anyway. So I'll have to make a degraded version for old phones.

To know if your mobile supports this effect, you will have to make a call to the system.getInfo (" gpuSupportsHighPrecisionFragmentShaders ") function

_G.frame = 0                                                                    -- Frame counter
_G.bTeleportRunning = false -- Does the teleporter work?
_G.teleportFrame = 0 -- The animation frame counter
_G.teleportPart = 0 -- The animation is in 3 parts.
_G.teleSpeed1 = 45
_G.teleSpeed2 = 45
_G.telePoint = {x = 0, y = 0}

local image1, image2 = "world1.jpg", "world2.jpg"
local oBack, oOver = nil, nil

local cntWidth = display.contentWidth -- virtual screen width
local cntHeight = display.contentHeight -- virtual screen height
local cntX = display.contentCenterX -- X and Y center of the virtual screen
local cntY = display.contentCenterY

local oSnapshot = display.newSnapshot(cntWidth, cntHeight) -- we create a Snapshot
oSnapshot.x, oSnapshot.y = cntX, cntY
oSnapshot.isVisible = false

local oBlackScreen = display.newRect(0, 0, cntWidth, cntHeight) -- we create a black rectangle
oBlackScreen:setFillColor( 0, 0, 0 )
oBlackScreen.isVisible = false
oSnapshot.group:insert(oBlackScreen) -- that we insert in the Snapshot

local oSB = display.newRect(0, 0, cntWidth, cntHeight) -- we create the sunBeams
oSB.fill.effect = "generator.sunbeams"
oSB.fill.effect.posX = 0.5
oSB.fill.effect.posY = 0.5
oSB.fill.effect.aspectRatio = ( oSB.width / oSB.height )
oSB.fill.effect.seed = 0
oSnapshot.group:insert(oSB) -- that we insert in the Snapshot (above the black rectangle)

local oMask = graphics.newMask("telemask.png") -- the useful mask for the second part of the teleporter

function loadImages()
if oBack then oBack:removeSelf() end
oBack = display.newImage(image1, cntWidth, cntHeight) -- we load image 1
oBack.x, oBack.y = cntX, cntY -- that we place in the center
oBack.isVisible = true
oBack:toBack()

if oOver then oOver:removeSelf() end
oOver = display.newImage(image2, cntWidth, cntHeight) -- we load image 2
oOver.x, oOver.y = cntX, cntY -- that we place in the center
oOver.isVisible = false
oOver:toFront()

image1, image2 = image2, image1 -- inversion of images
end

local fireBcl = function( event )
_G.frame = _G.frame + 1

if _G.bTeleportRunning then -- Mr Spock Teleportation
if _G.teleportPart == 0 then -- Part 1: whitewashing with the sunBeams
local deltaFrame = _G.frame - _G.teleportFrame
if deltaFrame == 1 then -- In order to make the screen black
oSB.x = _G.telePoint.x
oSB.y = _G.telePoint.y
oSB.xScale = 0.01
oSB.yScale = 0.01
end

oSnapshot:invalidate() -- We make the SunBeams bigger until its white part
local coef = deltaFrame / _G.teleSpeed1 -- covers the whole screen
coef = coef * coef + 0.0001
local scale = coef * 20
oSB.xScale = scale
oSB.yScale = scale
oSB.rotation = deltaFrame * 7
oOver.isVisible = false
oSnapshot.fill.effect = ""
oSnapshot.isVisible = true
if deltaFrame == _G.teleSpeed1 - 1 then
_G.teleportPart = 1 -- The screen is white we go to part 2!
_G.teleportFrame = _G.frame
end
elseif _G.teleportPart == 1 then -- Second part: negative of the sunbeams and transparent halo
local deltaFrame = _G.frame - _G.teleportFrame -- In this part, we will take the negative of SunBeams
if deltaFrame == 1 then -- In order to make the screen black
oBlackScreen.isVisible = true -- And at the same time we will hide the result to show
oBack.isVisible = false -- The second image.
oOver.isVisible = true
end

oSnapshot:invalidate()
local coef = deltaFrame / _G.teleSpeed2
coef = coef * coef * coef + 0.0001
local scale = coef * 50
oSB.xScale = scale
oSB.yScale = scale
oSB.rotation = deltaFrame * 7

oSnapshot.fill.effect = "filter.invert"
oSnapshot.isVisible = true

oOver:setMask(oMask)
oOver.maskX = _G.telePoint.x
oOver.maskY = _G.telePoint.y
oOver.maskScaleX = coef * 5
oOver.maskScaleY = coef * 5
if deltaFrame == _G.teleSpeed2 - 1 then
_G.teleportPart = 2
_G.teleportFrame = _G.frame
end
else -- End of animation
loadImages() -- We exchange the two images

_G.bTeleportRunning = false -- And we reset all states to zero!
oSnapshot.isVisible = false
oBlackScreen.isVisible = false
end
end
end


local fireStart = function(event) -- As soon as you touch the screen
if not _G.bTeleportRunning then -- If we're not already teleporting
_G.telePoint.x = event.x - display.contentCenterX
_G.telePoint.y = event.y - display.contentCenterY

_G.teleportFrame = _G.frame
_G.teleportPart = 0
_G.bTeleportRunning = true
end
end

loadImages()

Runtime:addEventListener( "tap", fireStart )
Runtime:addEventListener( "enterFrame", fireBcl )

Download

You can download the project archive running on Solar2D

Commentaires