Erkennen, ob ein Sprite die Kamera in libgdx verlassen hat?

8

Gibt es eine Methode, um festzustellen, ob ein Sprite die Kamera der Bühne verlassen hat? oder muss ich meine Operationen machen? : P.

Rudy_TM
quelle

Antworten:

5

Die Camera-Klasse enthält ein Frustum-Objekt mit der öffentlichen Methode pointInFrustum (Vector3-Punkt), das true zurückgibt, wenn sich Ihr Sprite im Frustum der Kamera befindet. Sie können auch im Benutzer-Wiki nach anderen Culling-Techniken suchen. http://code.google.com/p/libgdx-users/wiki/Culling

Majd
quelle
2
pointInFrustum (point) gibt true zurück, wenn sich der angegebene Punkt innerhalb des Frustums befindet und kein Sprite. Das Sprite kann eine eigene Breite und Höhe haben, sodass mit dieser Methode nicht überprüft werden kann, ob es sich direkt im Bildschirm befindet.
Arielsan
@arielsan Solange Sie überprüfen können, ob sich ein Punkt im Kegelstumpf befindet, können Sie einfach überprüfen, ob sich alle vier Punkte eines Sprites in einem Kegelstumpf befinden.
TomTsagk
3

Wenn Sie ein 2D-Spiel mit Kacheln erstellen, können Sie ganz einfach Ihr eigenes Keulen implementieren, was viel billiger ist, da Sie nur genau das durchlaufen, was Sie in Ihrem Kachelarray benötigen.

Dinge, die Sie wissen sollten:

  • Kamerastandort
  • Breite / Höhe des Ansichtsfensters
  • Fliesenbreite / -höhe

Jetzt können wir berechnen, wie viele Kacheln gezeichnet werden sollen.

  • Gesamtzahl der horizontalen Kacheln auf dem Bildschirm = viewport.width / tileWidth
  • Gesamtzahl der vertikalen Kacheln auf dem Bildschirm = viewport.height / tileHeight

Die Mathematik hängt davon ab, wie alles eingerichtet ist, ist aber sehr einfach. Zum Beispiel macht es einen Unterschied, ob die Mitte des Bildschirms der Kamerastandort oben links oder unten links ist.

Sie sollten am Ende so etwas haben:

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
    }
}

Dies hat gegenüber der Überprüfung, ob sich ein Punkt in Ihrem Kegelstumpf befindet, den Vorteil, dass Sie bei letzterem über jeden Punkt iterieren müssen, anstatt ein einfaches Array zu verwenden, bei dem Sie immer über eine festgelegte Anzahl von Kacheln iterieren, die der Anzahl der horizontalen Kacheln entspricht * vertikale Kacheln, die tatsächlich gezeichnet werden müssen. Auf diese Weise können Sie riesige Karten haben und trotzdem eine gute Bildrate haben. Leider wird dies bei der Verwendung von 3D schwieriger und schwieriger, aber mit der Freiheit, die der Benutzer mit der Kamera erhält, wird es exponentiell schwieriger. Sie können sich vorstellen, dass eine Kamera mit fester Perspektive, die sich mit dem Charakter bewegt, nur ein paar fest codierte Variablen benötigt, um dieselben Tricks auf einer Reihe von Maschen auszuführen, die Ihre Karte darstellen.

Madmenyo
quelle
0

Verwenden Sie einfach die Begrenzungskugelprüfung (Sie können den Radius mit Pythagoras berechnen). Es ist höllisch schnell und funktioniert auch mit Rotation. Es ist nicht perfekt, verursacht aber niemals falsches Keulen.

Für die Ad-hoc-optimierte Version hat Intersector einige Rechteck-Rectanle-Methoden, die auch funktionieren können. Aber Sie müssen das Rechteck für den Kamerastumpf selbst berechnen.

kalle_h
quelle
0

Diese Funktion prüft, ob ein Akteur sichtbar ist (funktioniert nur für 2D). Funktioniert in allen Situationen, z. B. wenn sich der Schauspieler in einer Gruppe befindet.

    /**
     * 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()
                );
    }
Fermmm
quelle