transition2: A customizable extension to the transition library

Never mind, got it working. Just a problem with the file path.

It is unclear on how I missed this awesome library, but kudos to you.  This is a fine piece of work Markus.

I especially love the fact that you have made this standalone.

PS - Awe-Factor +10

Good job! Will definitely have a look at this!

Wow, just stumbled upon your library and it looks amazing. Thank you very much for not only putting all your efforts in, but also sharing it here. Will definitely remember transition2 the next time I consider transitioning an object :slight_smile:

Hi Markus,

Again, thank you for a great lib. 

I ran into an issue while testing a few of the cool transitions you have, it might be just how it works or it might be an issue. :slight_smile:

When trying the waterBalloon transition I notice that if I start the transition at a point after the scene has started, it flickers just before it starts. Looking into the code I think I see why, the start value yScale is not equal to the original yScale

getStartValue = function(displayObject, params) return { xScale = params.originalXScale, yScale = params.originalYScale + (getValidIntensity(params.intensity) \* SCALE\_FACTOR \* params.originalYScale), } end,

Possible to fix? I assume that this also affect other transitions. 

I fixed this locally. 

Great. I’ll try to fix this in the github repo as soon as I have a little time. Do you mind sharing the code for your local fix?

Yeah, sure. I forked corona-transition2 and issued a pull request to you. 

https://github.com/rannerboy/corona-transition2/pull/1

I haven’t tried to solve the issue yet, but I suspect the leaf routine has a memory leak. 

When I add the following code… 

local monitorMem = function() collectgarbage("collect") print( "\nMemUsage: " .. collectgarbage("count") ) local textMem = system.getInfo( "textureMemoryUsed" ) / 1000000 print( "TexMem: " .. textMem ) end local memTimer = timer.performWithDelay(1000, monitorMem, -1)

I add this to the bottom of the code, and when I run the leaf function, it rapidly increases memory. When I comment out the leaf function it does not increase texture memory.

Jan 08 09:57:38.397: TexMem: 69.949348

Jan 08 09:57:39.404: ** MemUsage: 538.185546875**

Jan 08 09:57:39.405: TexMem: 69.949348

Jan 08 09:57:40.412: ** MemUsage: 561.837890625**

… after a couple of minutes…

Jan 08 09:59:13.163: TexMem: 69.948804

Jan 08 09:59:14.172: ** MemUsage: 15183.090820312**

Jan 08 09:59:14.172: TexMem: 69.949348

Jan 08 09:59:15.180: ** MemUsage: 15365.926757812**

 

I’m using the routine you posted here, although I’m using 5 loops, not 100. I also have a 

timer.performWithDelay( 1000, leaves ,-1 ) So yes, I am calling it every second, but to drop 5 leaves. With the life of the leaf, it does remove itself. So memory should level out.

The basic issue is that it runs fine on Apple TV, but after about an hour, the app silently quits. I suspect its a memory leak. If I took out the leaf routine, it didn’t quit.

I’ll see if I can find anything, but thought I’d mention it in case you had a better idea of where to look.

If there area any thoughts, let me know :slight_smile:

New convenience function fallingLeaf() just added. Example usage:

Thanks for reporting this! I don’t have time to investigate right now, but I’ll take notes and look in to it later. Let me know if you find out anything more.

Markus, I’ve just been re-reading this topic and spotted that you’ve added the “hideBackside” param to the zRotate transition. In my current project I’d already hacked together similar functionality.

It would be great if the transition could automatically handle which side should be shown, based on the current “z rotate” value. I was just wondering, how difficult do you think it would be to add a second display object representing the back of the object as an additional param?    

So instead of this:

local coinFront = display.newImageRect("coin-front.png", 29, 29) local coinBack = display.newImageRect("coin-back.png", 29, 29) coinBack.isVisible = false params = { degrees = -540, iterations = 0, time = 2000, horizontal = true, transition = easing.inOutSine, reverse = true, transitionReverse = easing.inOutQuad, shading = true, shadingDarknessIntensity = 0.75, shadingBrightnessIntensity = 0.25, hideBackside = true, } transition.zRotate(coinFront, params) -- Use the same params, but start with the backside rotated away from the display params.startDegrees = 180 transition.zRotate(coinBack, params)

it would be like this:

local coinFront = display.newImageRect("coin-front.png", 29, 29) local coinBack = display.newImageRect("coin-back.png", 29, 29) params = { degrees = -540, iterations = 0, time = 2000, horizontal = true, transition = easing.inOutSine, reverse = true, transitionReverse = easing.inOutQuad, shading = true, shadingDarknessIntensity = 0.75, shadingBrightnessIntensity = 0.25, backObject = coinBack, } transition.zRotate(coinFront, params)

What actually made me think of this was the falling leaf transition, as at the moment both sides of the leaf will always be identical (afaik). I might try and hack something like this together soon, but wanted to see what you thought about it (maybe you’ve already tried and it was a real can of worms).

Hi Alan, I actually haven’t tried that yet but it should be possible without opening a giant can of worms. :slight_smile:

Passing a second display object as param to the zRotate transition is probably not the best way though. The main transition algorithm assumes a single display object/group to work with and I’d prefer to not change that unless necessary.

Instead I’d likely go for an approach with a convenience function “zRotateWithBackside” which just encapsulates the code from my example with two separate zRotate transitions, one for each of the two sides. That way, I wouldn’t have to touch either the main algorithm nor the zRotate implementation. That’s the same idea as for the fallingLeaf() function, which is also basically just a sequence of different transitions grouped into the same convenience function.

I might try to add this if a can find a little time some time soon. Otherwise, feel free to hack it together by yourself. :slight_smile:

Well done! It’s impressive

If I had your transition for my previous game, I had won many hour (I don’t know which time I need to use for this sentence…)

Do you include something to do transition on blur ? I had difficulties to make transition of blur on large image. I was forced to use 2 different images, one on full scale and the other one in the quarter of the size.

Thank you!  :slight_smile:

Haven’t done anything at all with blur so far, so I’m afraid I can’t help you with that right now.

This is amazing. Thanks so much! Using it as a slight animated hologram effect in my game :slight_smile:

I’ve dug into the memory leak problem now and found a nasty little bug that prevented cancelled transitions from getting cleaned up properly. Reason: I forgot to actually call the removeTransition() function… :wacko: This affected all transitions, not only fallingLeaf().

The fix for this silly mistake is a simple one-liner which has been pushed to the master branch of the Git repo. But if you don’t want to pull a new version you can just make the following change yourself in transition2-main.lua (at the bottom):

local function cleanUpTransition(transitionRef) if (transitionRef) then -- Immediately flag transition as cancelled so that it won't be processed anymore by the enter frame listner transitionRef.isCancelled = true -- Then wait for lock to be available before actually doing the cleaning up local removeTransition removeTransition = function() if (not locked) then locked = true -- Unset cross reference from target-\>transitionRef if (transitionRef.target and transitionRef.target.transitionRefs) then transitionRef.target.transitionRefs[transitionRef] = nil end -- Unset reference in table indexed by tag if (transitionsByTag[transitionRef.tag]) then transitionsByTag[transitionRef.tag][transitionRef] = nil end -- Note! Removal from the transitions array is done by the enter frame listener when it traverses the array and finds cancelled transitions -- Can't do it here without looping through the array which would be inefficient. locked = false else -- Try again shortly... timer.performWithDelay(20, removeTransition) end end -- ADD THIS LINE! -- removeTransition() end end

Added an onValue  callback function that can be used with any transitions. May come in handy if context or target object needs to be updated depending on transition state.

Example use with the color transition:

transition.color(displayObject, { startColor = {0, 0, 0, 1}, endColor = {1, 1, 1, 1}, time = 500, reverse = true, iterations = 0, onValue = function(target, value) local R,G,B = value[1], value[2], value[3] if (R \> 0.8 and G \> 0.8 and B \> 0.8) then print("This color is pretty bright!") end end, })

Also made use of the onValue function in zRotate by implementing a convenience param hideBackside.Setting this to true will hide the target object when rotated away from the display. This makes it easy to combine two separate objects and make them appear as a single two-sided object while rotating. Like this example with a coin from Ice Trap:

local coinFront = display.newImageRect("coin-front.png", 29, 29) local coinBack = display.newImageRect("coin-back.png", 29, 29) coinBack.isVisible = false params = { degrees = -540, iterations = 0, time = 2000, horizontal = true, transition = easing.inOutSine, reverse = true, transitionReverse = easing.inOutQuad, shading = true, shadingDarknessIntensity = 0.75, shadingBrightnessIntensity = 0.25, hideBackside = true, } transition.zRotate(coinFront, params) -- Use the same params, but start with the backside rotated away from the display params.startDegrees = 180 transition.zRotate(coinBack, params)

p7HumsR.gif

Only just stumbling on to this. In one of your earlier comments you mentioned having to do absolute paths in your require() calls. In case this makes life easier, this is what I do to use relative paths:

require ((…):match("(.-)[^%.]+$") … “foobah”)

Assuming foobah.lua exists in the same location as the calling file.

Hi, I’m having difficulty getting my head round a concept that I’m trying to implement and was wondering if anyone could help.

I have an object that I want to move backwards and forwards across the screen.

Say the object starts at x=20 and moves to a point somewhere to the right, once it gets there I would like it to move back to a random point on the left followed by a random point to the right etc.

I knowhow to set a new destination using the onRepeat and recalculateOnIteration functions but can’t figure out how to make sure the new destination is in the correct direction.

​Then, just when it was complicated enough, I’d like the object to be moving at a constant speed which I guess could be calculated using the following function that I found on the forums from a few years back…

local function distanceBetween( point1, point2 ) local xfactor = point2.x-point1.x local yfactor = point2.y-point1.y local distanceBetween = math.sqrt((xfactor\*xfactor) + (yfactor\*yfactor)) return distanceBetween end local speed = 0.1 times = 1 \* distanceBetween(A,B) / speed transition.to(A, {time=times,x=B.x, y=B.y})

I hope all of this makes some kind of sense :slight_smile:

If I understand your question correctly, I believe that you can solve this a lot easier easier without using iterations, with a single transition function calling itself onComplete. Using recalculateOnIteration in combination with for example onRepeat should work for changing direction and target position. But, because you need the object to move at constant speed this solution won’t work since it’s not possible to change the transition time between iterations.

Here’s an example with a single transition function calling itself and setting a property on the target object to keep track of which direction it is currently moving. Just dry coding from memory here without test running anything, but hopefully you’ll get the picture.  :slight_smile:

-- Declare the move variable before initializing it to be able to reference it from onComplete local move move = function(target) -- Store direction on target object, and alternate between left/right target.direction = (target.direction == "right") and "left" or "right" -- Then calculate new target position... local newTargetX = calculateNewTargetX(target.x, target.direction) -- ...and also calculate time for new transition now that you know the distance the object will travel at a constant speed. local timeMs = calculateTimeForConstantSpeed(target.x, newTargetX) transition.to(target, { x = newTargetX, time = timeMs, onComplete = move }) end move(yourObject)