Détecter si un sprite a quitté la caméra dans libgdx?

8

Existe-t-il une méthode pour savoir si un sprite a quitté la caméra de la scène? ou je dois faire mes opérations? : P

Rudy_TM
la source

Réponses:

5

La classe Camera contient un objet Frustum avec la méthode publique pointInFrustum (point Vector3) qui renvoie true si votre sprite se trouve dans le tronc de la caméra. Vous pouvez également consulter le wiki de l'utilisateur pour d'autres techniques d'abattage. http://code.google.com/p/libgdx-users/wiki/Culling

Majd
la source
2
pointInFrustum (point) renvoie true si le point spécifié se trouve dans le tronc, pas un Sprite. Le Sprite peut avoir sa propre largeur et hauteur, il ne peut donc pas être vérifié pour être à l'intérieur de l'écran en utilisant directement cette méthode.
arielsan
@arielsan Tant que vous pouvez vérifier si un point se trouve à l'intérieur du tronc, vous pouvez simplement vérifier si les quatre points d'un sprite se trouvent dans un tronc.
TomTsagk
3

Si vous créez un jeu 2D avec des tuiles, vous pouvez facilement implémenter votre propre abattage, ce qui est beaucoup moins cher car vous ne faites que répéter exactement ce dont vous avez besoin dans votre tableau de tuiles.

Ce que vous devez savoir:

  • Emplacement de la caméra
  • Largeur / hauteur de la fenêtre
  • Largeur / hauteur du carreau

Nous pouvons maintenant calculer combien de tuiles doivent être dessinées.

  • Tuiles horizontales totales à l'écran = viewport.width / tileWidth
  • Tuiles verticales totales à l'écran = viewport.height / tileHeight

Le calcul dépend de la façon dont tout est configuré, mais est très simple. Par exemple, cela fait une différence si le centre de l'écran est l'emplacement de la caméra, en haut à gauche ou en bas à gauche.

Vous devriez vous retrouver avec quelque chose comme ceci:

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

L'avantage de cela sur la vérification si un point est dans votre tronc est qu'avec ce dernier, vous devez itérer sur chaque point au lieu d'utiliser un tableau simple où vous itérez toujours sur une quantité définie de tuiles qui est égale à la quantité de tuiles horizontales * tuiles verticales qui doivent réellement dessiner. De cette façon, vous pouvez avoir d'énormes cartes et toujours avoir une bonne fréquence d'images. Malheureusement, cela devient plus difficile et plus délicat lors de l'utilisation de la 3D, mais devient exponentiellement plus difficile avec la liberté que l'utilisateur obtient avec l'appareil photo. Vous pouvez imaginer qu'une caméra à perspective fixe qui se déplace avec le personnage n'a besoin que de quelques variables codées en dur pour effectuer les mêmes astuces sur un tableau de maillages qui représentent votre carte.

Madmenyo
la source
0

Utilisez simplement la vérification de la sphère englobante (vous pouvez calculer le rayon à l'aide de Pythagore). Il est rapide comme l'enfer et fonctionne également avec la rotation. Ce n'est pas parfait mais ne provoque jamais de faux abattages.

Pour la version optimisée ad hoc, Intersector a des méthodes de rectanle contenant des méthodes rectangulaires qui peuvent aussi fonctionner. Mais vous devez calculer vous-même le rectangle pour le tronc de la caméra.

kalle_h
la source
0

Cette fonction vérifie si un acteur est visible (ne fonctionne que pour 2D). Fonctionne dans toutes les situations, par exemple lorsque l'acteur fait partie d'un groupe.

    /**
     * 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
la source