Risposte:
La classe Camera contiene un oggetto Frustum con il metodo pubblico pointInFrustum (punto Vector3) che restituisce true se lo sprite si trova all'interno del frustum della fotocamera. Puoi anche dare un'occhiata al wiki dell'utente per altre tecniche di abbattimento. http://code.google.com/p/libgdx-users/wiki/Culling
Se stai creando un gioco 2D con tessere, puoi facilmente implementare la tua abbattimento, che è molto più economica, dal momento che passi solo esattamente su ciò di cui hai bisogno nel tuo array di tessere.
Cose che dovresti sapere:
Ora possiamo calcolare quante tessere devono essere disegnate.
viewport.width / tileWidth
viewport.height / tileHeight
La matematica dipende da come è impostato tutto, ma è molto semplice. Ad esempio, fa la differenza se il centro dello schermo è la posizione della telecamera, in alto a sinistra o in basso a sinistra.
Dovresti finire con qualcosa del genere:
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
}
}
Il vantaggio di questo oltre a verificare se un punto è all'interno del tuo frustum è che con quest'ultimo è necessario iterare su ogni punto invece di utilizzare un semplice array in cui si scorre sempre su una determinata quantità di tessere uguale alla quantità di tessere orizzontali * tessere verticali che devono effettivamente disegnare. In questo modo puoi avere enormi mappe e avere comunque un buon frame rate. Sfortunatamente questo diventa più difficile e più complicato quando si usa il 3D ma diventa esponenzialmente più difficile con la libertà che l'utente ottiene con la fotocamera. Puoi immaginare una telecamera a prospettiva fissa che si muove con il personaggio e che necessita solo di un paio di variabili hardcoded per fare gli stessi trucchi su una serie di mesh che rappresentano la tua mappa.
Basta usare il controllo della sfera di delimitazione (puoi calcolare il raggio usando pitagora) È veloce come l'inferno e funziona anche con la rotazione. Non è perfetto, ma non causa mai una falsa eliminazione.
Per la versione ottimizzata ad hoc, Intersector ha alcuni rettangoli che contengono metodi rettangolari che possono funzionare anche questi. Ma devi calcolare il rettangolo per il frustum della fotocamera da solo.
Questa funzione controlla se un attore è visibile (funziona solo per 2D). Funziona in tutte le situazioni, ad esempio quando l'attore è all'interno di un gruppo.
/**
* 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()
);
}