How do you implement a state chart with smooth transitions or fade in/out?

Started by
7 comments, last by riruilo 14 years, 5 months ago
Hi dudes! I need your help! I'd like to know how you implement this. Let's say, when my game starts, it shows a publisher screen and after that, a company screen or logo. I implemented this using just 2 states: SHOWING_PUBLISHER SHOWING_COMPANY But transitions between them is a bit abrupt. I'd like to implement a fade in/out effect between them, in this way, this is the sequence I want time in ms 0..250 fade in publisher (250 ms) 250..2250 publisher at full intensity (2000 ms) 2250..2500 fade out publisher (250 ms) 2500..2750 fade in company (250 ms) 2750..4750 company at full intensity (2000 ms) 4750..5000 fade out company (250 ms) How should I implement this? Perhaps adding new states like: FADING_IN_PUBLISHER SHOWING_PUBLISHER FADING_OUT_PUBLISHER FADING_IN_COMPANY SHOWING_COMPANY FADING_OUT_COMPANY Instead of just 2 states: SHOWING_PUBLISHER SHOWING_COMPANY The problem is that I'd like to implement similar behaviour in my main menu and in game menu, so adding more states perhaps is a problem in a large state chart. Should I use something like nested state charts? Is there any other solution? What do you think? I'm really interested solving this problem from a software engineering point of view, rather than from a hacking point of view. I could solve this problem using some variables, but I want the best and correct way. Do you understand me? Thanks a lot for your time, I appreciate it a lot.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Advertisement
Hi

this should give you the right way althouth its XNA, but it helped me back when i did one in OpenGL

Game State Management in XNA


Greetings


-----"Master! Apprentice! Heartborne, 7th Seeker Warrior! Disciple! In me the Wishmaster..." Wishmaster - Nightwish
It's an interesting question. I suppose the "good" answer will vary according to the way your code has been implemented.

I'm just posting random thoughts here, sorry if they aren't good for you.

My idea is at first you have to decide who is responsible of the updates. I can think of two possible solutions:
- the "states" are self-defined
- a class defines the "states"

Solution number one is to implement a base state class, then you derive publisher/company states. In theory those classes should handle the fading.

When a new state is "set", before discarding the old one (unless the old one is 0), you call a method, i.e. endstate(time), until that method returns 1 (the state is over), then the next frame you can set the new one and start calling updatestate(time), which internally will handle the fade in part.

In this case you need a very simple state manager.

Another solution is to write a timeline class and to manually add commands/events there. In this case there is no "state" class, but the timeline is responsible of the update process.

If you want you can mix the two, a state manager with states controlled by a timeline via events.

Just my 2 cents, hope this helps.
The fading out state would just be a sub-state of the current state, probably based on time since the state was created. You'd change the whole state at the end of the fade operation. Fading in would be even easier since you don't need to do anything after the fade-in has completed.
Quote:Original post by Kylotan
The fading out state would just be a sub-state of the current state, probably based on time since the state was created. You'd change the whole state at the end of the fade operation. Fading in would be even easier since you don't need to do anything after the fade-in has completed.


I was thinking the same in order to keep a clean design, but, is that a nested finite state machine?

BTW, thanks.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Yes, it is implicitly a nested finite state machine, but in the case where your FSM is always A -> B -> C with no conditionals and no looping, you don't need the complexity of a formal FSM structure. Your transitions are predictable and the data is the same across all three substates.

However, feel free to use one if you like. You could have a RenderingState object within your top-level SHOWING_PUBLISHER or SHOWING_COMPANY states. These would handle drawing the image correctly, and you explicitly swap the RenderingState objects one after the other. One would fade in the image, one would display the image, and one would fade it out.
Quote:Original post by ricardo_ruiz_lopez
I'm really interested solving this problem from a software engineering point of view, rather than from a hacking point of view. I could solve this problem using some variables, but I want the best and correct way. Do you understand me?

the point of view of software engineers

In your case, the fading functionality seems pretty orthogonal to the state machine you've set up. Why not just trigger a fade-out -- not as a separate state, just as something that's going on -- which triggers a state transition when it's done? Similarly, set up a fade-in when you enter a state, but don't otherwise link it to the state machine.
Quote:I'm really interested solving this problem from a software engineering point of view


Software Engineering point of view has nothing to do with code, just a lot of metrics that ensure that lowest bidder developers cannot hurt your bottom line by causing your faulty code to result in lawsuits or refunds.

Quote:time in ms
0..250 fade in publisher (250 ms)
250..2250 publisher at full intensity (2000 ms)
2250..2500 fade out publisher (250 ms)
2500..2750 fade in company (250 ms)
2750..4750 company at full intensity (2000 ms)
4750..5000 fade out company (250 ms)


There are objects.
"Fade" implies alpha (transparency).
It depends on time.

Conclusion: for each object: Alpha = f(t)

Implementation:
start = currentTime();while (running) {  time = currentTime();  for (every object o) {    alpha = o.getAlphaAtTimeT(time-start);    render(o, alpha);  }};


To make alpha changes smooth, use some sort of interpolation.

Quote:I was thinking the same in order to keep a clean design, but, is that a nested finite state machine?


You can keep your design. It has nothing to do with the animation problem. Animation is performed separately, and independently.

As a matter of fact, your state machine would need to add animation controls to the animator. For example, on transition from A to B, you would tell renderer to display some object from alpha=1.0, time=0 to alpha=0.0, time=500.
Quote:Original post by Kylotan
Yes, it is implicitly a nested finite state machine, but in the case where your FSM is always A -> B -> C with no conditionals and no looping, you don't need the complexity of a formal FSM structure. Your transitions are predictable and the data is the same across all three substates.

However, feel free to use one if you like. You could have a RenderingState object within your top-level SHOWING_PUBLISHER or SHOWING_COMPANY states. These would handle drawing the image correctly, and you explicitly swap the RenderingState objects one after the other. One would fade in the image, one would display the image, and one would fade it out.


Thanks.
Yes, you are right, these states are predictable. I think perhaps 2 more nested machines is too much for just a fading effect.
I guess I will do what you said, something like a implicit nested FSM using some variables.

Thanks for help to everyone.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.

This topic is closed to new replies.

Advertisement