Question

Je travaille sur un programme qui simule des objets en mouvement dans un champ. Le champ a une limite de 1024x1024. L'objet ne peut pas descendre en dessous de 0 en termes de coordonnées x, y et il ne peut pas aller au-dessus de 1024. J'ai une méthode pour chaque objet appelé « move () », qui déplace l'objet dans sa direction de courant à sa vitesse actuelle. Si l'objet se rapproche de la limite, il se tourne alors autour d'une nouvelle direction et même vitesse.

Le problème que j'ai est que lorsque l'un de mes objets se rapproche à la fois x et y est liée (coin du champ), il se coince dans le coin. Il est presque comme si elle tente de se éloigner du coin, mais il se retourne. Il faut aimer ce coin. Je regardais mon code et pour moi, ma logique semble correcte. Je vérifie pour vous assurer que la nouvelle direction n'est pas négatif ou sur 359. Je vérifie pour vous assurer que la nouvelle coordonnée x, y avec la nouvelle direction est dans les limites aussi. J'ai même une méthode pour définir une nouvelle direction.

J'ai essayé de ré-implémenter cette méthode avec une logique différente, mais pas de chance. Si quelqu'un pourrait trouver une faille dans ma programmation ou d'un point sur ce qui peut être la cause, alors ce serait très apprécié.

J'ai essayé de débogage et pas dans mon programme et je vois que quand il arrive au coin, il change de direction pour tourner autour, se déplace environ 3 places, puis retourne dans le coin. Doit être un merveilleux coin.

code pour la méthode de déplacement est ci-dessous:

public void move(){

  localX = super.getX();
  localY = super.getY();

  float newX=0, newY=0;
  float testX, testY;
  boolean acceptX = false, acceptY = false;

  testX = (float) (Math.cos(direction)*10) + localX;
  testY = (float) (Math.sin(direction)*10) + localY;
  int testDirection;

  while(!acceptX){
   if(testX >= 0 && testX <= bound){
    newX = testX;
    acceptX = true;
   }//end if statement
   else{
    if(direction+180 > 359){
     setDirection(direction-180);
     testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX;
    }
    else{
     setDirection(direction+180);
     testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX;
    }
   }//end else
  }//end while that checks for X value

  while(!acceptY){
   if(testY >= 0 && testY <= bound){
    newY = testY;
    acceptY = true;
   }//end if statement
   else{
    if(direction+180 > 359){
     setDirection(direction-180);
     testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY;
    }
    else{
     setDirection(direction+180);
     testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY;
    }
   }//end else
  }//end while that checks for Y value

  super.setX(newX);
  super.setY(newY);

 }

et est ici le code pour setDirection

public void setDirection(int d) {
        direction = d;
    }
Était-ce utile?

La solution

Disons que vous avez un objet dans le coin supérieur gauche, en remontant. Votre premier test se retourne, il descend. Ensuite vient votre deuxième chèque, ce qui le retourne à nouveau pour remonter ... à nouveau.

Votre code pourrait également utiliser un peu plus de lisibilité. La première chose que je remarque est que vous utilisez les contrôles de >359 pour normaliser la nouvelle direction à suivre. Cependant, tous les cas comprennent le code de mouvement ainsi. Je ferais quelque chose comme:

setDirection(direction + 180);          //turn around
if (direction >= 360) direction -= 360; //normalize
testY = ...;                            //move

pour déplacer le code de mouvement de la vérification de la direction si / blocs d'autre. 360 est également un meilleur nombre magique à utiliser; 359 degrés ne signifie rien. Comme cela a été suggéré, vous devez finalement utiliser une bibliothèque de vecteur et donc jeter la plupart des mathématiques.

Autres conseils

Je vous recommande vraiment le stockage de votre direction comme vecteur (x, y) au lieu de calculer ce vecteur d'un scalaire; Je pense que cela vous aidera énormément avec votre code.

Problème: Lorsque votre objet frappe un bord, vous tournez à 180 degrés. Si elle touche les deux bords, il tournera en place, et les coordonnées de test sera toujours au mauvais endroit.

Quand un de vos objets frappe un bord, il doit rebondir, pas de visage! Angle d'incidence == angle de réfraction, ou une telle. En d'autres termes, si vous vérifiez la coordonnée x et Rebonds nier la vitesse de x, pas les deux x et y.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top