
aze (./1705) :
Tu remplaces tes objets globaux par des pointeurs globaux et tu alloues les objets toi même une fois rentré dans le main.
Link (./1706) :
Vu que même en entourant le constructeur lui-même d'un try/catch (oui, c'est possible)
Folco (./1712) :
Pas mal, je n'y avais pas pensé, ça me semble le plur propre !
Brunni (./1713) :
Une bonne solution aussi c'est si possible de les créer localement et les passer plus loin à ceux qui en ont besoin, ça permet de mieux contrôler qui dépend de quoi.
Link (./1706) :
Vu que même en entourant le constructeur lui-même d'un try/catch (oui, c'est possible)
Folco (./1716) :Euh, mes souvenirs sont lointains, mais il me semble que tu es censer locker/délocker l'écran à chaque frame, et ne pas conserver le pointeur d'une frame à l'autre.
Pour l'adresse de l'écran (en terme TI) créé par SDL par exemple.
Link (./1717) :
1. C'est un "faux" catch de toute façon
Sasume (./1718) :L’héritage multiple du C++ est tout sauf élégant
Sasume (./1718) :
Sinon une solution pas trop contraignante pour éviter d’avoir à trimballer trop de paramètres à tes fonctions graphiques, c’est de les regrouper dans une structure que tu pourrais appeler un contexte graphique.
class Drawable
{
public:
Drawable (bool enabled = true);
void drawEnable ();
void drawDisable ();
void drawToggle ();
bool isDrawable ();
virtual void draw () = 0;
private:
bool m_Enabled;
};
Link (./1721) :
Globale ou non, le catch est faux quand même. Si je veux mettre un try quelque part, je le met autour de instanciation de l'objet (et peut-être son utilisation), ou à l'intérieur du constructeur, au moins là je sais l'exception ne sera pas relancée sans mon ordre.
Folco (./1720) :À moins que ce soit inversé par rapport à DirectDraw, il me semble que c'est le contraire : le pointeur n'est garanti valide que quand elle est lockée, justement. Faudrait que je vérifie ça...
Je comprends pas trop le coup des (un)LockSurface de la SDL, sachant qu'on ne peut rien écrire dans la surface quand elle est lockée. De toute façon, s'il bouge cette surface en mémoire, je ne vois pas comment la retrouver, je n'ai qu'un pointeur comme info sur la-dite surface
Folco (./1720) :
Question maintenant. J'ai un écrit une classe toute bête me permettant de regrouper mes objets à dessiner dans une liste par exemple, ce qui permet d'appeler dans une boucle toutes leurs fonctions de dessin, que chacun réimplémente à sa façon :class Drawable { public: Drawable (bool enabled = true); void drawEnable (); void drawDisable (); void drawToggle (); bool isDrawable (); virtual void draw () = 0; private: bool m_Enabled; };
Comme vous le voyez, une variable est prévue, permettant de désactiver l'affichage d'un objet. Je veux que sa fonction draw() voit ça et n'affiche pas son objet.
Comment faire pour éviter que chaque objet interroge sa partie Drawable pour savoir s'il doit se dessiner ? Pas que ce soit chiant à écrire (if (isDrawable()){....}), mais j'ai juste peur, dans l'implémentation d'un objet, d'oublier cette condition.
Je voudrais que ce soit transparent pour l'objet, en clair qu'il ne se dessine pas, même lorsqu'il essaye, si il a été désactivé, mais sans procéder à cette vérification lui-même.
Il y a un moyen ?
protected: virtual void drawImpl() = 0;
public: void draw() { if (isDrawable()) drawImpl(); }
Par exemple class DrawList
{
/* …bla bla bla… */
public: void execute() { for (i = 0; i < count; i++) if (drawables[i]->isDrawable()) drawables[i]->draw(); }
private:
Drawable* drawables;
i
(http://www.libsdl.org/docs/html/sdllocksurface.html)
SDL_LockSurface
(...)
SDL_LockSurface sets up a surface for directly accessing the pixels. Between calls to SDL_LockSurface and SDL_UnlockSurface, you can write to and read from surface->pixels, using the pixel format stored in surface->format. Once you are done accessing the surface, you should use SDL_UnlockSurface to release it.
Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates to 0, then you can read and write to the surface at any time, and the pixel format of the surface will not change.
(http://msdn.microsoft.com/en-us/library/aa918512.aspx)
IDirectDrawSurface::Lock
(...) This method obtains a pointer to the surface memory.
GoldenCrystal (./1724) :Ce pattern porte un nom : Template Method
Une autre méthode que j'aime bien mais que je n'appliquerais pas ici:
Tu déclares ta méthode draw() non virtuelle, et une méthode "drawImpl()" (par exemple) virtuelle.protected: virtual void drawImpl() = 0; public: void draw() { if (isDrawable()) drawImpl(); }
class A { public: void func_classique (); virtual void pure_virtual_func () = 0; }; class B { public: void pure_virtual_func (); };
if (spr == NULL) { err = "Could not load file: "; err += SDL_GetError(); throw err; }
Folco (./1739) :
C'est risqué de baser la synchronisation d'un jeu sur un framerate ?
SDL_gfx permet de fixer un fps constant (30 par défaut), ça ne devrait donc pas poser de problème ?Tu veux dire *limiter* le FPS, et pas fixer un FPS constant (PS: 60 FPS c'est toujours mieux que 30 ^^). Si la machine n'est capable que d'afficher 15 FPS, ça va plus bien marcher. En fait le mieux c'est de ne pas limiter le FPS, comme ça les graphismes sont mis à jour plus rapidement sur les machines qui en sont capables (Faut évidemment que ton jeu supporte d'afficher des graphismes fluides à 60 fps, car si tes sprites bougent à 30, l'intérêt est en effet limité)
Je veux juste éviter le phénomène de certains jeux oldies qui tournent à des vitesses hallucinantes parce que la synchro ne marche plusParce que ces jeux ne mesuraient pas le temps écoulé, ou bien ajustaient leur timings d'une manière kikoololesque. (Avec des boucles for vides par exemple
/* 120 Hz */ #define f 120d /* f = 1 / T <=> t = 1 / f */ #define T (1d / f) float Update(float delta); void Render(); int main() { long oldTime, newTime; double xTime = 0; /* Parce que sur x86 les float ça sert a rien :p */ Initialiser(); oldTime = GetTickCount(); /* Je prend un timer de référence (en millisecondes) */ while true { newTime = GetTickCount(); xTime = Update(xTime + (newTime - oldTime) / 1000d); Render(); oldTime = newTime(); } } double Update(double delta) { while (delta > T) { delta -= T; /* Faire les calculs sur une durée écoulée T */ } /* Il reste du temps non utilisé, on s'en servira la fois prochaine */ return delta; } void Render() { /* Dessiner ce qu'il faut ici */ }