2017-05-23 3 views
-1

J'essaie de créer un jeu de type balle balle similaire à Touhou en Java.2d Bullet jeu en Java

J'ai besoin d'aide pour commencer, comme un exemple à suivre. J'ai essayé de le faire à partir de zéro en utilisant JFrame, mais mon principal problème est le décalage lors de la création de balles.

J'ai une classe bullet, avec des paramètres pour la faire passer de A à B. Mais chaque fois que le programme crée ou supprime des objets bullet (qui sont stockés dans une ArrayList), il se fige pendant une fraction de seconde, mais devient très prononcé quand il y a beaucoup de balles. Est-ce que je me trompe pour utiliser un ArrayList ici? Quels guides sont recommandés pour apprendre à le faire correctement?

Voici ma classe Bullet:

import java.awt.Graphics; 

    public class Bullet 
    { 
     double x,y, xend, yend; 
     int width, height; 
     int life = 200; 
     private static final double speed = 8; 
     double dirX, dirY; 

     public Bullet(double x, double y, double xend, double yend, int width, int height) 
     { 
     this.x=x; 
     this.y=y; 
     this.xend = xend; 
     this.yend = yend; 
     this.width = width; 
     this.height = height; 

     dirX = speed*Math.cos(getAngle()); 
     dirY = speed*Math.sin(getAngle()); 
     } 

     public double getAngle() 
     { 
     double angle = (double) Math.toDegrees(Math.atan2(yend-y, xend - x)); 

     if(angle < 0){ 
      angle += 360; 
     } 
     System.out.println(angle); 

     return Math.toRadians(angle); 
     } 

     public void tick() 
     { 
     life--; 
     x+=dirX; 
     y+=dirY; 
     } 

     public void draw (Graphics g) 
     { 
     g.fillRect((int) Math.round(this.x),(int) Math.round(this.y),this.width,this.height); 
     } 
    } 

Et ceci est le code qui est exécuté lorsque l'utilisateur crée une balle. Il utilise mouseListener pour les coordonnées xend yend - trouver la destination de la balle. J'utilise une minuterie pour actualiser le jeu, mais il n'est toujours pas à une vitesse constante à cause des gels.

+3

Veuillez fournir un [mcve]. – Berger

+0

Vous devrez peut-être afficher du code. Utilisez-vous JBullet ou la bibliothèque Bullet? – matt

+0

J'ai ajouté du code. – SceyF

Répondre

0

ArrayList.add() devrait généralement être extrêmement rapide. Parfois, lorsque l'implémentation doit ajouter une nouvelle capacité, elle alloue une nouvelle matrice de sauvegarde, copie les données de l'une à l'autre avant de continuer. Vous pouvez éviter cela en spécifiant une capacité initiale appropriée dans le constructeur ArrayList(int initialCapacity).

Cependant, vous aurez besoin de dizaines de milliers d'entrées pour que cela prenne suffisamment de temps pour ajouter un retard de jeu notable.

ArrayList.remove(int index) doit passer au-dessus de toutes les entrées l'élément supprimé, en bas de la matrice de support par une fente. Cependant, ceci est hautement optimisé au niveau du processeur, et ne devrait pas ajouter de décalage de jeu notable à moins que vous n'ayez des dizaines de milliers de puces.

ArrayList.remove(Object o) doit examiner chaque élément à tour de rôle et exécuter equals() sur chacun d'eux, jusqu'à ce qu'il trouve l'élément cible. Evite ça!


Il est possible que les pauses que vous voyez sont dus à la collecte des ordures , et cela pourrait être parce que vous créez des milliers de Bullet de courte durée objets. Ces derniers à partir du moment où ils sont tirés jusqu'à ce qu'ils sortent de l'écran. Quand ils sortent de la portée, ils restent dans la mémoire jusqu'à ce que le GC ait à éclaircir des milliers d'entre eux.

Vous pouvez éviter cela en conservant un pool d'objets de puces. Il existe des bibliothèques avec des implémentations de pool d'objets, ou vous pouvez créer votre propre collection à l'aide de Collections. Dans les environnements soumis à de fortes contraintes de mémoire (comme les consoles de jeu 8 bits), il est nécessaire de s'assurer qu'un jeu fonctionne dans la mémoire fixe, ce qui est similaire au type de choses que les programmes sur ces plateformes feraient.


Cependant vous devez prouver que votre question est, avant d'essayer de le réparer, et que vous avez besoin d'utiliser un profileur tels que VisualVM. Cela vous montrera où votre exécution passe son temps, et comment elle utilise la mémoire. La récupération de place dans Java moderne est très performante dans la plupart des cas, cependant, ne supposez pas que c'est le problème.