2012-02-28 3 views
2

У меня есть игрок, который может вращаться и перемещаться по 2D картезианской сетке, мне нужно рассчитать, где рисовать врагов на экране.Вращение прямоугольника вокруг сетки для подсчета очков игроков

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

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

Проблема лучше всего представить в виде графика с зеленым, являющимся точкой зрения, которая представляет собой прямоугольник, который может вращаться и перемещаться по сетке, и точки, представляющие игрока и врага.

Blue is player, Red is Enemy Green represents viewpoint

Так что мне нужно выработать позиции врагов на экране относительно поворота игроков и положение.

ответ

2

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

The camera frustum

положение экрана противника связан с углом между камерой и врагом.

//indicates where on the screen an enemy should be drawn. 
//-1 represents the leftmost part of the screen, 
//and 1 is the rightmost. 
//Anything larger or smaller is off the edge of the screen and should not be drawn. 
float calculateXPosition(camera, enemy){ 
    //the camera man can see anything 30 degrees to the left or right of its line of sight. 
    //This number is arbitrary; adjust to your own tastes. 
    frustumWidth = 60; 

    //the angle between the enemy and the camera, in relation to the x axis. 
    angle = atan2(enemy.y - camera.y, enemy.x - camera.x); 

    //the angle of the enemy, in relation to the camera's line of sight. If the enemy is on-camera, this should be less than frustumWidth/2. 
    objectiveAngle = camera.angle - angle; 

    //scale down from [-frustumWidth/2, frustumWidth/2] to [-1, 1] 
    return objectiveAngle/(frustrumWidth/2); 
} 

Эти диаграммы визуализировать то, что переменные, я использую здесь представляют:

depiction of <code>angle</code>

enter image description here

После того, как у вас есть "X позиция" в диапазоне [-1, 1], должно быть достаточно легко преобразовать это в пиксельные координаты. Например, если ваш экран 500 пикселей в ширину, вы можете сделать что-то вроде ((calculateXPosition(camera, enemy) + 1)/2) * 500;

Edit:

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

side view - camera looking at enemy

//this gives you a number between -1 and 1, just as calculateXPosition does. 
//-1 is the bottom of the screen, 1 is the top. 
float getYPosition(pointHeight, cameraHeight, distanceFromCamera){ 
    frustrumWidth = 60; 
    relativeHeight = pointHeight - cameraHeight; 
    angle = atan2(relativeHeight, distanceFromCamera); 
    return angle/(frustrumWidth/2); 
} 

enter image description here

Вы можете вызвать метод дважды, чтобы определить у позиции как в верхней и нижней части противника:

distanceFromCamera = sqrt((enemy.x - camera.x)^2 + (enemy.y - camera.y)^2); 
topBoundary = convertToPixels(getYPosition(enemy.height, camera.height, distanceFromCamera)); 
bottomBoundary = convertToPixels(getYPosition(0, camera.height, distanceFromCamera)); 

Это должно дать вам достаточно информации, чтобы правильно масштабировать и позиционировать спрайт противника.

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

+0

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

+0

Мне удалось получить X из этого, но я боюсь также получить Y – Joel

+0

@Joel, я добавил некоторую информацию о вычислении координат Y. – Kevin

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