2013-10-03 4 views
0

Я стараюсь сделать простую гоночную игру. Для этого я получил автомобиль с вектором для позиции и один для направления, с которым он сталкивается.2D-векторная ротация в Java

У меня есть обновление и методы ввода:

public void update(double delta) { 
    float rotation = 0; 
    if(movement.normalized().getY() < 0) { 
     rotation = (float) (2*Math.PI - Math.acos(movement.normalized().getX())); 
    } else { 
     rotation = (float) Math.acos(movement.normalized().getX()); 
    } 

    pos = pos.add(new Vector3f((float) (Math.cos(rotation) * (movement.length() - 2) * delta), (float) (Math.sin(rotation) * (movement.length() - 2) * delta), 0f)); 

    v1 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((rotation + basicAngel)) * radius), (float) (pos.getY() + (Math.sin((rotation + basicAngel)) * radius)), 0), new Vector2f(0, 0)); 
    v2 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - basicAngel) + rotation)) * radius), (float) (pos.getY() + Math.sin(((2*Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0)); 
    v3 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((Math.PI + rotation + basicAngel)) * radius), (float)(pos.getY() + Math.sin((Math.PI + rotation + basicAngel)) * radius), 0), new Vector2f(0, 0)); 
    v4 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((Math.PI - basicAngel) + rotation)) * radius), (float)(pos.getY() + Math.sin(((Math.PI - basicAngel) + rotation)) * radius), 0), new Vector2f(0, 0)); 
    v5 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos((windowAngel + rotation)) * windowRadius), (float)(pos.getY() + Math.sin((windowAngel + rotation)) * windowRadius), 0), new Vector2f(0, 0)); 
    v6 = new Vertex(new Vector3f((float)(pos.getX() + Math.cos(((2*Math.PI - windowAngel) + rotation)) * windowRadius), (float)(pos.getY() + Math.sin(((2*Math.PI - windowAngel) + rotation)) * windowRadius), 0), new Vector2f(0, 0)); 
} 

Первые если-заявление проверяет, является ли у компонента нормированного вектора ниже 0.
Это гарантирует, что автомобиль вращается ниже горизонтальной оси.
Следующая линия применяет поворот и скорость к положению.
Блок с v1 ... v4 вычисляет углы автомобиля для его рендеринга.
v5 и v6 - это углы окна автомобилей.

public void input() { 

    float tempX = movement.normalized().getX(); 
    float tempY = movement.normalized().getY(); 
    float tempLength = movement.length(); 

    if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) { 
     movement = movement.rotate(3); 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { 
     movement = movement.rotate(-3); 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_UP)) { 
     if (tempLength <= 7) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.2))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.2))); 

     } 
    } else { 
     if(tempLength > 2) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.05))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.05))); 

     } 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { 
     if (tempLength >= 0) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength - 0.2))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength - 0.2))); 

     } 
    } else { 
     if (tempLength < 2) { 

      movement.setX((float) (Math.cos(Math.acos(movement.normalized().getX())) * (tempLength + 0.05))); 
      movement.setY((float) (Math.sin(Math.acos(movement.normalized().getX())) * (tempLength + 0.05))); 

     } 
    } 

    if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { 
     reset(); 
    } 
} 

Первые два оператора if проверяют, были ли нажаты левая или правая клавиша. Если это произошло, то ветеринар движения вращается. Следующие два утверждения проверяют вверх и вниз ключ и appliing скорости к вектору движения, используя следующую формулу:

x = cos a * (l + speed) 
y = sin a * (l + speed) 

где а угол вектора движения
и л длина из вектор движения

Все должно работать нормально, и это происходит, за исключением того, что он иногда просчитывается, чтобы автомобиль двигался в другом направлении, как ожидалось.

Может кто-нибудь помочь мне найти ошибку?

ответ

1

Вы не можете использовать acos, чтобы получить угол. Например, Math.cos (Math.PI * 3/4) и Math.cos (Math.PI * 5/4) дают вам -0.7071. Посмотрите на кривую косинуса, чтобы понять, почему. Чтобы получить угол для векторного использования Math.atan2 (y, x). Кроме того, почему вы преобразовываете вектор в угол, а затем обратно в вектор. Это не обязательно. Почему бы вам не использовать нормализованный вектор для направления и float/double для скорости и умножить это на каждое обновление?

Или вы могли бы сделать движение = движение.add (motion.normalized(). Mul (0.2));

+0

Благодарим вас за ответ. Я не думал о загаре, но ты прав, это лучше. Я собираюсь применить ваши предложения и дать отчет после этого. – henne90gen

Смежные вопросы