Custom screen transition -- am I modeling correctly?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
benreed
Prole
Posts: 6
Joined: Fri Oct 21, 2016 3:07 pm

Custom screen transition -- am I modeling correctly?

Post by benreed »

Hey guys,

I have a little prototype right now where I have a main menu and two crude little gamestates (via HUMP.gamestate) which I can transition between (menu -> "game"). You can see what I have so far in the .love file attached to this post.

Before I go much further on defining the other gamestates, I want to learn how to make a neater ("juicier", I guess) transition between the two states I have. The transition effects I want to mimic are based on one of my favorite games of all time, The King of Fighters '98. You can see examples of the effects I want to implement in the first 5 seconds of this video:
https://www.youtube.com/watch?v=dbemtYemrFA

I dunno the proper animation terms to describe them, but there's a quick fade to white, and then what I guess is a "convergent wipe"(?) as two black rectangles quickly converge on the vertical center of the screen, blacking it out. Those are the two effects I want to implement and combine for my transition.

My forum search regarding screen transitions obviously brought up Chroteus' Venus library, but it doesn't look like Venus offers quite the transition effects I'm looking for. (Venus's fade only goes to black, and I dunno if I can combine multiple Venus wipes to get my desired "convergent blackout".) So I want to roll my own transitions, which I don't think looks very difficult to do. (I could very well be wrong.)

And so instead of asking you guys to write it for me, I'm gonna explain my naiive interpretation of how I'd do it, and you guys can clear up what's wrong with my interpretation, suggest stuff I should read to better understand my problem/solutions(that I'm not already Googling as I wait on replies), etc. I'll start just by thinking about the fade to white, since it seems the simpler of the two:

Fade to white:
On current state exit...
Non-looped, performed once initially:
Initialize a variable "alpha" to 0, to represent the opacity of a rectangle that will serve to fade out the screen contents.
Set the LOVE primitive drawing color (love.graphics.setColor()) to (255, 255, 255, opacity). This will make the fade rect be completely invisible (transparent) when first drawn.
Looped every frame, until alpha reaches 255:
If "alpha" is less than 255, then add some value to "alpha". (This rate of change has got to be tied to dt somehow, but I can't identify the exact logical relationship yet.)
Draw a filled LOVE rectangle primitive (love.graphics.rectangle()) at 0,0 across the whole width and height of the screen. As the loop turns over and the rect gets redrawn, it'll get more and more opaque until it's completely white.
Once "alpha" reaches 255, I want to end the transition and enter the next game state.

These are the major questions I'm asking myself right now:
  • Do transitions merit their own HUMP gamestate? If so, do I want to push & pop them, or would it be more appropriate to enter & leave them? (e.g.: menu -> transition (-> another transition) -> gameplay) My gut says enter & leave might be most appropriate, because then I can use update & draw inside the transition to loop my opacity changes, and then switch to the desired next state (passed in as a param somewhere) upon achieving the exit condition. Am I on the right track?
  • How must dt affect the rate at which I change the opacity? I'm almost positive it must be incorporated, because otherwise the amount of time taken to reach alpha=255 -- and thus end the transition -- will not be constant across different hardware. (If you have recommended readings on the different applications of dt in gamedev, I'm certainly not above stopping to read them. My math is crap & I'm trying to improve it.) Maybe I need to start a timer upon entering the transition and exit only when a certain amount of time has passed? But if so, I still need to relate the alpha change to dt, so that I'm not "spinning my wheels" if some machines reach full white faster than others simply by looping faster while adding a constant amount.
  • Do I have a more efficient alternative to change the fade rect alpha than spamming setColor()? Does it matter for something this simple?
Any help you can provide is greatly appreciated. Thank you for taking the time to read this.
Attachments
benreed_game.love
(45.3 KiB) Downloaded 141 times
User avatar
D0NM
Party member
Posts: 250
Joined: Mon Feb 08, 2016 10:35 am
Location: Zabuyaki
Contact:

Re: Custom screen transition -- am I modeling correctly?

Post by D0NM »

So you want "a static image - to a static image" transition.
Right?

Just take a screenshot of the current state
put it into some variable and got to your next hump.state
where you can add some effects to the taken screenie
and mix it with your current BG.
Our LÖVE Gamedev blog Zabuyaki (an open source retro beat 'em up game). Twitter: @Zabuyaki.
:joker: LÖVE & Lua Video Lessons in Russian / Видео уроки по LÖVE и Lua :joker:
benreed
Prole
Posts: 6
Joined: Fri Oct 21, 2016 3:07 pm

Re: Custom screen transition -- am I modeling correctly?

Post by benreed »

Now that you mention it, taking a screenshot sounds like it would be at least part of the solution. It just occurred to me that I'd almost certainly want to (effectively) freeze the drawing state as the transition begins (so that moving objects stop moving on screen, etc), so I'd probably want to re-draw that static screenshot repeatedly while the fade is working. Although I think in the KOF98 example transition, the "outgoing" elements (portraits and such) are still visibly moving on-screen when the fade begins. But I still have time to think about whether or not I want that.

I'm rethinking whether or not transitions merit a whole gamestate simply because Googling StackExchange threads brought up the issue of how much of the previous state the "middleman" (transition) state would be expected to pass along to the end state. Doing that with my crude little menu right now is just cute, because right now the only state value I need to remember is the lightweight value of "where am I going after the transition?" (a name). But what if I needed to remember a bunch of physical state from a gameplay state or something? Deltas, coordinates, points in animations, the works? (Or worse, more expensive assets to load like image/sound resources?) I may want to avoid all that by making the states themselves handle their own transitions. But I'm still thinking/reading about it right now.

EDIT: Reading about hump.timer now and it sounds like it might be a big part of the solution. So I'm reading thru the hump.timer docs right now.

EDIT 10/26/16: I have a working, naiive solution in place, but I'm busy cleaning it up. I'll post it once I've neatened it up a bit.
Last edited by benreed on Wed Oct 26, 2016 4:41 pm, edited 1 time in total.
User avatar
D0NM
Party member
Posts: 250
Joined: Mon Feb 08, 2016 10:35 am
Location: Zabuyaki
Contact:

Re: Custom screen transition -- am I modeling correctly?

Post by D0NM »

do u know how to take a screenie?
i wonder if there is a nicer way to do it )))
If you draw all your stuff on some canvases, you can manipulate with them.
Also. You can use that hump timer to ANIMATE the canvas during the transition.
So you could make a transition "from an animated screen to another animated screen" like in your Vid.

Code: Select all

SCREENSHOT = love.graphics.newImage(love.graphics.newScreenshot(false))
I'm into coding our free fighting game now..
so I use the first thing that works
then polish up it later.

e.g. I take a screenie then go to the PAUSE mode
having the darkened screenie as a BG for the pause state.
Our LÖVE Gamedev blog Zabuyaki (an open source retro beat 'em up game). Twitter: @Zabuyaki.
:joker: LÖVE & Lua Video Lessons in Russian / Видео уроки по LÖVE и Lua :joker:
User avatar
pgimeno
Party member
Posts: 3657
Joined: Sun Oct 18, 2015 2:58 pm

Re: Custom screen transition -- am I modeling correctly?

Post by pgimeno »

I wouldn't think it merits a new state or pausing everything. On the contrary, letting things continue while the effect is being applied makes it look more dynamic. It's all about drawing a rectangle, it's easy.

The task of changing opacity and moving the rectangles is best left up to a tweening library. I think that hump.timer includes one. That will also address your concern about how to use dt.
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Custom screen transition -- am I modeling correctly?

Post by Beelz »

I did a crude version of a transition a while back that uses a 'transition state'. Keep in mind I didn't use 3rd party libraries on this project.

This was my state switching function:

Code: Select all

local nxt = nil
function _changeState(new, useTrans)
	states[active]:onLeave()
	states[new]:onEnter()
	
	if useTrans then 
		active = 'transition'
		nxt = new
		states[active]:onEnter(new)
	else
		active = new
		nxt = nil
	end
end


Then to draw:

Code: Select all

function love.draw()
	if active == 'transition' then
		states[nxt]:draw()
	end
	states[active]:draw()
end
To tie it together I did basically what was mentioned above. Here's the transition state:

Code: Select all

local state = require 'req.state_base'
local transition = state:extend()

local timer, alpha, img, nextState

function transition:onEnter(next)
	timer = 0
	alpha = 255
	nextState = next
	img = love.graphics.newImage(love.graphics.newScreenshot(true))
end

function transition:onLeave()
    img = nil
end

function transition:update(dt)	
	timer = timer + dt
	if timer > 2 then
		_changeState(nextState)
	else
		alpha = alpha - (255/2)*dt
	end
end

function transition:draw()
	LG.setColor(255,255,255, alpha)
	LG.draw(img, 0, 0)
end

return transition, transition:init()

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Semrush [Bot] and 2 guests