wolf wrote: ↑Thu Jan 26, 2023 6:31 amVery nice, smaller in lines of code than my approach. Nice use of canvas (probably a better idea than the screenshot capture I did here). And in your example GameState is decoupled from the Transition class itself, whereas in my example it's kinda coupled.Bigfoot71 wrote: ↑Tue Jan 24, 2023 2:29 pmHere is a very simplistic approach, you can optimize it and add shaders if you want.wolf wrote: ↑Mon Jan 23, 2023 10:57 am I know this is a very old topic, but I wanted to add something that people might find useful.
For my own project I use hump as well and I wanted to have a crossfade animation between scenes (e.g. from menu to loading to game). Here's my approach using the SceneBase base class and Transition object.
As can be seen this code relies on `hump.timer` and `hump.gamestate`. The "class" is simply used as such:Code: Select all
-- base class for scenes SceneBase = Class { } function SceneBase:init() end function SceneBase:enter(previous, ...) end function SceneBase:update(dt) end function SceneBase:draw() end function SceneBase:onStartTransition() end function SceneBase:onFinishTransition() end -- class that performs crossfade transitions Transition = {} -- duration of fade animation local FADE_DURATION = 0.5 -- a flag to check whether initial Gamestate is set local is_initialized = false -- a list of pending transitions local transitions = {} -- validate a scene by ensuring all methods from SceneBase are included local function assertScene(scene) assert(scene ~= nil, 'scene should be defined') for k, v in pairs(SceneBase) do -- ensure property is defined assert(scene[k] ~= nil, 'scene should inherit from SceneBase') -- ensure property type of scene is equal to property type of SceneBase assert(type(scene[k]) == type(v), 'scene should inherit from SceneBase') end end -- this callback is invoked when screenshot capture is completed local function startTransition(imageData) -- create an image from original scene local image = love.graphics.newImage(imageData) -- remove transition from pending transitions list local fade = table.remove(transitions, 1) -- notify next scene we are starting the transition fade.to_scene:onStartTransition() -- store drawing function for next scene in local variable local to_scene_draw = fade.to_scene.draw -- for next scene, replace drawing function with custom implementation fade.to_scene.draw = function() -- first draw next scene love.graphics.setColor(1.0, 1.0, 1.0, 1.0) to_scene_draw(fade.to_scene) -- now draw an image of previous scene, but use alpha value for fade love.graphics.setColor(1.0, 1.0, 1.0, fade.alpha) love.graphics.draw(image) end -- tween fade alpha value Timer.tween(FADE_DURATION, fade, { alpha = 0.0 }, 'in-out-quad', function() -- restore original draw function when fade is completed fade.to_scene.draw = to_scene_draw -- ensure colors are drawn normally on subsequent draw calls love.graphics.setColor(1.0, 1.0, 1.0, 1.0) -- notify next scene the transition is completed fade.to_scene.onFinishTransition(fade.to_scene) end) -- start switch to next scene Gamestate.switch(fade.to_scene, unpack(fade.to_args)) end -- the initialize function should be called to load initial scene Transition.init = function(to, ...) -- create a black dummy scene for fade in animation local DummyScene = Class { __includes = SceneBase } DummyScene.draw = function() love.graphics.setColor(0.0, 0.0, 0.0, 1.0) local window_w, window_h = love.window.getMode() love.graphics.rectangle('fill', 0, 0, window_w, window_h) end -- initialize Gamestate with the black dummy scene Gamestate.switch(DummyScene) is_initialized = true -- start a cross fade animation to target scene Transition.crossfade(DummyScene, to, ...) end -- perform a crossfade transition between scenes with optional arguments Transition.crossfade = function(from, to, ...) assert(is_initialized, 'Transitions not initialized, ensure init is called first') assertScene(from) assertScene(to) -- add transition to pending transitions list transitions[#transitions + 1] = { from_scene = from, to_scene = to, to_args = {...}, alpha = 1.0, } -- capture a screenshot of the current scene, callback is invoked on image captured love.graphics.captureScreenshot(startTransition) end
In this case I assume self is a scene (e.g. Loading) and Game is another scene.Code: Select all
Transition.crossfade(self, Game)
Hump & transition image effects
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Hump & transition image effects
Re: Hump & transition image effects
And as I said the approach is very simplistic but what will allow you to adapt it to your tastes, by using the metatables you can even couple it as you say to your gamestates and avoid the use in the function `love.draw`, and many other customizations such as different transitions between states (even if for readability I preferred to keep it simple if it's a simple crossfade)
Edit: I realized then that what I was saying was not very clear, here is an example:
And that with only this in the main.lua:
Code: Select all
TransState = require("lib.tState")
Gamestate = require("lib.gamestate")
function love.load()
State_1 = TransState("states.state_1")
State_2 = TransState("states.state_2")
State_3 = TransState("states.state_3")
Gamestate.switch(State_1)
end
function love.keyreleased(k)
Gamestate.keyreleased(k)
end
function love.update(dt)
Gamestate:update(dt)
end
function love.draw()
Gamestate.draw()
love.graphics.print("Press \"SPACE\" to switch")
end
Note: In my example I am loading the contents of the `State_X` files, so it cannot be used as is in a compressed file, but you can also define the "state" table as a parameter of `TransState`. There are certainly solutions but I just noticed it and I don't have time to look into it anymore
- Attachments
-
- transition.zip
- (4.73 KiB) Downloaded 80 times
Re: Hump & transition image effects
Am I right that these methods freeze the screen during the transition? Depending on whether the screen moves, that might be noticeable.
Re: Hump & transition image effects
I'm not sure I understand but no the display is not frozen, I think this impression (if I understand correctly) comes from the fact that the transition time is one second each in my example, but from the moment that the animation to start the new state is indeed updated and displayed accordingly. Is that what you meant?
Re: Hump & transition image effects
I think he means that in my example I made a screenshot (hence no animation for duration of transition). In your example you draw at the start of the transition on a canvas (again, since canvas is not updated, no animation of say menu or game state is shown during transition.Bigfoot71 wrote: ↑Thu Jan 26, 2023 10:34 pmI'm not sure I understand but no the display is not frozen, I think this impression (if I understand correctly) comes from the fact that the transition time is one second each in my example, but from the moment that the animation to start the new state is indeed updated and displayed accordingly. Is that what you meant?
I guess your example could be easily adapted to update the canvas with e.g. game state while transition is happening. Could one could supply the old state to the transition 'class' and drawing old state on the canvas on each update call. My example would likely be problematic as I believe taking screenshots is a bit slow.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 11 guests