Ответы:
Класс Camera содержит объект Frustum с открытым методом pointInFrustum (точка Vector3), который возвращает значение true, если ваш спрайт находится в области усеченного пространства камеры. Вы также можете взглянуть на пользовательскую вики для других методов отбора. http://code.google.com/p/libgdx-users/wiki/Culling
Если вы создаете 2D-игру с плитками, вы можете легко реализовать свою собственную отбраковку, которая намного дешевле, так как вы можете выбирать только то, что вам нужно в вашем массиве плиток.
Вещи, которые вы должны знать:
Теперь мы можем рассчитать, сколько плиток нужно нарисовать.
viewport.width / tileWidth
viewport.height / tileHeight
Математика зависит от того, как все настроено, но очень проста. Например, имеет значение, если в центре экрана находится местоположение камеры, вверху слева или внизу слева.
Вы должны получить что-то вроде этого:
int startX = cameraWorldPosX / tileWidth;
int startY = cameraWorldPosY / tileHeight;
//When you have the position of the camera in the center of the screen you do something like this:
int startX = (cameraWorldPosX - viewport.width / 2) / tileWidth;
int startY = (cameraWorldPosY - viewport.height / 2) / tileHeight;
for (int y = startY; y < startY + viewportWidth / tileWidth; y++)
{
for (int x = startX; x < startX + viewportHeight / tileHeight; x++)
{
//Draw logic
}
}
Преимущество этого по сравнению с проверкой, находится ли точка в пределах вашего усеченного конуса, заключается в том, что с последним вам нужно выполнять итерацию по каждой точке вместо использования какого-либо простого массива, в котором вы всегда выполняете итерацию по установленному количеству плиток, равному количеству горизонтальных плиток. * вертикальные плитки, которые на самом деле нужно рисовать. Таким образом, вы можете иметь огромные карты и при этом иметь хорошую частоту кадров. К сожалению, это становится все сложнее и сложнее при использовании 3D, но экспоненциально усложняется со свободой, которую пользователь получает с камерой. Вы можете представить себе камеру с фиксированной перспективой, которая движется вместе с персонажем, и ей нужна пара жестко закодированных переменных, чтобы выполнить те же трюки с массивом сеток, представляющих вашу карту.
Просто используйте проверку ограничивающей сферы. (Вы можете рассчитать радиус с помощью Пифагора). Он быстр, как ад, а также работает с вращением. Это не идеально, но никогда не вызывает ложного отбора.
Для специальной оптимизированной версии Intersector имеет некоторые прямоугольники, содержащие методы rectanle, которые тоже могут работать. Но вам нужно рассчитать прямоугольник для камеры самостоятельно.
Эта функция проверяет, является ли актер видимым (работает только для 2D). Работает во всех ситуациях, например, когда актер находится внутри группы.
/**
* Returns if the actor is visible or not. Useful to implement 2D culling.
**/
public static boolean actorIsVisible(Actor actor) {
Vector2 actorStagePos = actor.localToStageCoordinates(new Vector2(0,0));
Vector2 actorStagePosTl = actor.localToStageCoordinates(new Vector2(
actor.getWidth(),
actor.getHeight()));
Vector3 actorPixelPos = new Vector3(actorStagePos.x, actorStagePos.y, 0);
Vector3 actorPixelPosTl = new Vector3(actorStagePosTl.x, actorStagePosTl.y, 0);
actorPixelPos = actor.getStage().getCamera().project(actorPixelPos);
actorPixelPosTl = actor.getStage().getCamera().project(actorPixelPosTl);
return !(actorPixelPosTl.x < 0 ||
actorPixelPos.x > Gdx.graphics.getWidth() ||
actorPixelPosTl.y < 0 ||
actorPixelPos.y > Gdx.graphics.getHeight()
);
}