Движущиеся объекты застряли в углу - PullRequest
1 голос
/ 12 ноября 2010

Я работаю над программой, которая имитирует объекты, движущиеся в поле. Поле имеет границу 1024х1024. Объект не может опускаться ниже 0 в терминах координат x, y и не может превышать 1024. У меня есть метод для каждого объекта, называемый «move ()», который перемещает объект в его текущем направлении с его текущей скоростью. Если объект приближается к границе, он поворачивается с новым направлением и той же скоростью.

Проблема, с которой я столкнулся, заключается в том, что когда один из моих объектов приближается к границам x и y (угол поля), он застревает в углу. Это почти как если бы он пытался отойти от угла, но затем он поворачивает назад. Это должно любить этот угол. Я просмотрел свой код и мне моя логика кажется правильной. Я проверяю, чтобы убедиться, что новое направление не отрицательно или не превышает 359. Я проверяю, чтобы новая координата x, y с новым направлением тоже находилась в границах. У меня даже есть способ установить новое направление.

Я пытался повторно реализовать этот метод с другой логикой, но безуспешно. Если бы кто-то мог найти ошибку в моем программировании или указать, что может быть причиной, то это было бы очень ценно.

Я попытался отладить и пройтись по моей программе, и я вижу, что, когда она добирается до угла, она меняет направление, чтобы развернуться, перемещается примерно на 3 пробела, а затем возвращается в угол. Должно быть, прекрасный уголок.

Код для метода перемещения ниже:

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);

 }

и вот код для setDirection

public void setDirection(int d) {
        direction = d;
    }

Ответы [ 3 ]

2 голосов
/ 12 ноября 2010

Скажем, у вас есть объект в левом верхнем углу, идущий вверх. Ваш первый тест переворачивает его так, что он падает. Затем приходит ваш второй чек, который снова поворачивает его, чтобы подняться ... снова.

Ваш код также может использовать больше читабельности. Самое первое, что я заметил, это то, что вы используете чеки >359, чтобы нормализовать новое направление движения. Тем не менее, все случаи также включают код движения. Я бы сделал что-то вроде:

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

чтобы переместить код движения из направления, проверяя блоки if / else. 360 также лучше использовать магическое число; 359 градусов ничего не значит. Как уже было предложено, вы должны в конечном итоге использовать векторную библиотеку и, следовательно, отбросить большую часть математики.

1 голос
/ 12 ноября 2010

Проблема: когда ваш объект касается края, вы поворачиваете его на 180 градусов.Если он ударяет по обоим краям, он будет вращаться на месте, и тестовые координаты всегда будут в неправильном месте.

Когда один из ваших объектов достигает края, он должен отскочить, а не от лица!Угол падения == угол преломления или что-то подобное.Другими словами, если вы проверяете координату x, и она отскакивает, отрицайте скорость x, а не оба x & y.

1 голос
/ 12 ноября 2010

Я бы действительно рекомендовал сохранять ваше направление в виде вектора (x, y) вместо вычисления этого вектора из скаляра; Я думаю, что это очень поможет вам с вашим кодом.

...