Bonjour,
Mon jeu possede plusieurs ecrans differents deja en place, et j'aimerais faire un bel effet de transition avec Fade in & fade out.
L'appel de la transition se fait en dehors du thread de rendu graphique.
Voici la classe:
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 #ifndef FADE_H_INCLUDED #define FADE_H_INCLUDED /// Used for screen fading. #include <SFML/Graphics.hpp> class Fade { public: Fade() : m_fadein(false), m_fadeout(false), m_started(false), m_rect(sf::RectangleShape()), m_alpha(0), m_goal(0) { }; ~Fade() { } /// Called by the secondary thread void FadeOut() { /// Setting the flag to true, so the rendering thread knows that he has to fade out the screen /// Regular screen to full black screen. m_fadeout = true; m_alpha = 0; m_goal = 255; m_rect.setFillColor(sf::Color(0,0,0,0)); } /// Called by the secondary thread void FadeIn() { /// Setting the flag to true, so the rendering thread knows that he has to fade in the screen m_fadein = true; m_alpha = 255; m_goal = 0; //m_rect.setFillColor(sf::Color(0,0,0,255)); } /// Simply returns the shape for displaying inline sf::RectangleShape& getShape() { return m_rect; } /// Used by the main loop, if this returns true, the thread will draw it inline bool doFade() { if(m_fadein && (m_alpha > m_goal)) // black > screen { m_alpha--; m_rect.setFillColor(sf::Color(0,0,0,m_alpha)); return true; } else if(m_fadeout && (m_alpha < m_goal)) // screen > black { m_alpha++; m_rect.setFillColor(sf::Color(0,0,0,m_alpha)); return true; } else { return false; } } /// Used by the secondary thread, if this is true, it means the main thread is fading. Some sort of mutex :P inline bool Fading() const { return (m_started); } /// Used by the main thread to know if he has to perform a fade inline bool requestFade() const { return (m_fadein | m_fadeout); } /// Both used by the main thread to change the flags, so the secondary thread will know that he is fading. (cf: Fading()) void startFading() { m_started = true; } void doneFading() { m_started = false; m_fadein = false; m_fadeout = false; } inline static const unsigned int fadingTime() { return fading_time; } private: /// Flag: Fade in action bool m_fadein; /// Flag: Fade out action bool m_fadeout; /// Flag: if theres a fade processing bool m_started; /// SFML's shape sf::RectangleShape m_rect; /// Current alpha. unsigned int m_alpha; /// Alpha to reach unsigned int m_goal; static const unsigned int fading_time = 10; // in ms }; #endif // FADE_H_INCLUDED
Quand je veux faire un fade, de mon thread secondaire, je fais ceci:
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 m_gameui.getRenderer().getFader().FadeOut(); // Appel a fade out : ecran > ecran noir nextScreen(); // Simple routine qui permet a l'ecran de se mettre a jour sous l'ecran noir while(m_gameui.getRenderer().getFader().Fading()) {} // On attend pendant que le fade se termine (donc ecran noir m_gameui.getRenderer().getFader().FadeIn(); // Et hop on retourne au nouvel ecran
Et mon thread principal:
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 short LoginScreen::Run() { m_desktop.GetEngine().LoadThemeFromFile("Data/css/login.css"); /// Add the UI to the window m_desktop.Add(getScreen()); /// Rendering loop while(m_game.getRenderer().getApp().isOpen() && m_game.isRunning()) { /// Clearing the window m_game.getRenderer().getApp().clear(); sf::Event event; while(m_game.getRenderer().getApp().pollEvent(event)) { /// Event handling /// SFGUI m_desktop.HandleEvent(event); /// SFML if(event.type == sf::Event::Closed) { /// This will automatically terminate the networker thread & nicely exit the game m_game.crash(); } } m_game.getRenderer().getApp().resetGLStates(); /// Drawings (SFGUI) /// UI if(changeScreen()) { oldScreen()->Show(false); m_desktop.Remove(oldScreen()); getScreen()->Show(true); m_desktop.Add(getScreen()); } /// Fading out (screen to black) if(m_game.getRenderer().getFader().requestFade()) { m_game.getRenderer().getFader().startFading(); } if(m_game.getRenderer().getFader().Fading()) { if(m_game.getRenderer().getFader().doFade()) { m_game.getRenderer().getApp().draw(m_game.getRenderer().getFader().getShape()); } else { m_game.getRenderer().getFader().doneFading(); } } /// Displayings m_desktop.Update(0.f); m_game.getRenderer().display(m_game.getRenderer().getApp()); m_game.getRenderer().getApp().display(); } return -1; }
Le probleme ?
L'ecran devient tout noir d'un coup, et j'ai acces a l'ecran caché derriere ce noir.
Comment faire pour avoir une belle transition ?
Merci d'avance,
nico
Partager