[Republier cette question à partir de stackoverflow, car il a été souligné qu'elle s'adapte mieux ici.]
Je porte actuellement mon moteur de jeu 2D sur Java. J'ai regardé certaines des bibliothèques de jeux pointées ici sur stackoverflow. Cependant, ceux que j'ai examinés étaient plutôt simplistes et ne précisaient même pas s'ils prenaient en charge des éléments tels que la transparence alpha, j'ai donc décidé de porter mon rendu C ++ pour lequel j'avais déjà écrit la logique.
Ce moteur de rendu est un moteur de rendu purement logiciel qui utilise la mosaïque pour éviter un nouveau rendu inutile. J'ai optimisé ses performances de défilement en créant un "tampon hors écran" un peu plus grand que mon volet de sortie, et en plaçant ce tampon hors écran sur ma sortie à chaque image. De cette façon, je pouvais éviter de redessiner inutilement les carreaux simplement parce que je faisais défiler un pixel sur la carte.
J'ai utilisé l'AWT de Java pour l'implémenter, en utilisant une grande BufferedImage pour le tampon hors écran. L'utilisation du processeur est correcte (environ deux fois ce que j'avais en C ++), mais il y a un problème étrange avec le défilement continu, où toutes les secondes environ, le moteur de rendu restera en attente pendant environ 0,2 seconde.
Puisqu'il n'y a rien dans mon propre code qui se produirait pendant ces périodes, et puisque les pics disparaissent si je ne dessine pas mon tampon hors écran sur la vue principale, je peux seulement conclure que Java fait sa propre optimisation interne. Cependant, je ne suis pas sûr de ce qu'il fait, et je ne sais pas laquelle de mes propres optimisations je devrais supprimer pour me débarrasser des pointes. En outre, il se peut que java AWT n'ait pas été conçu avec un défilement FPS continu et élevé, et c'est entièrement inutilisable à cette fin.
Y a-t-il un moyen pour moi de me débarrasser de ces pointes?
Réponses:
Bien que je ne puisse pas être sûr sans regarder votre code, il semble que votre problème soit le garbage collector. En Java, vous avez de temps en temps des collectes de déchets majeures et mineures. Le mineur utilise une partie de votre processeur mais ne vous embête pas trop. Les principales collections peuvent être un vrai problème pour les applications en temps réel telles que les jeux, car elles suspendent tout pendant qu'elles fonctionnent.
Il existe deux options pour résoudre ce problème. Vous pouvez d'abord modifier la JVM pour vous assurer que moins de collections importantes ont lieu. Deuxièmement (et recommandé), vous pouvez vous assurer de ne pas laisser trop de déchets. Vérifiez simplement où dans votre application vous créez beaucoup d'objets (dans mes jeux, ce sont généralement les classes vector3) et assurez-vous de les réutiliser autant que possible (en particulier dans les boucles internes, etc.).
la source
Oui.
Pour les jeux basés sur des sprites 2D, AWT peut être utilisé pour gérer le rendu avec grand effet. Il peut même être accéléré matériellement , selon le matériel disponible.
Sans code ni extraits de profilage détaillés, il est difficile de dire quel est le problème. Le mieux que je puisse faire est d'offrir quelques conseils de base pour travailler avec Java et AWT lors de la création de jeux.
Travailler avec le garbage collector
Le GC en Java est quelque chose que nous devons vraiment garder à l'esprit lorsque nous construisons nos jeux. Il s'exécutera périodiquement et recherchera les objets qui n'y ont aucune référence, et les supprimera de la mémoire. Ce processus de suppression est lent et est probablement la cause de l'attelage que vous rencontrez.
Ma suggestion est d'éviter de créer des références d'objet qui ne seront pas conservées pendant la durée de vie de l'exécution (ou du moins autant que possible). L'objectif idéal est de s'assurer que le GC n'a rien à faire à chaque fois qu'il s'exécute.
En pratique, vous pouvez vous retrouver avec de nombreuses variables statiques que vous réutilisez tout au long du jeu. Voici un exemple très artificiel de la façon dont j'ai tendance à gérer cela:
Pendant le chargement des écrans, vous pouvez agrandir ou réduire vos
Map
instances à l'aide dunew
mot - clé. Mais pendant le jeu, vous voudrez éviter cela autant que possible. Si quelque chose est détruit pendant le jeu, placez un drapeau sur l'objet afin que vous sachiez que ce n'est pas quelque chose qui est actuellement actif. Si vous devez faire apparaître un nouvel objet, parcourez votreMap
jusqu'à ce que vous en trouviez un qui n'est pas actif, définissez ses propriétés et marquez-le comme actif.C'est quelque chose que vous voudrez garder à l'esprit lorsque vous utilisez Java pour des applications sensibles aux performances, que vous utilisiez AWT, JavaFX ou OpenGL pour effectuer le rendu.
Toile
Pour AWT en particulier, je recommande fortement d'utiliser la classe Canvas pour tout restituer pour diverses raisons:
la source