Detectar se um sprite deixou a câmera na libgdx?


8

Existe um método para saber se um sprite saiu da câmera do palco? ou eu tenho que fazer minhas operações? : P

Respostas:


5

A classe Camera contém um objeto Frustum com o método público pointInFrustum (Vector3 point) que retorna true se o seu sprite estiver dentro do frustum da câmera. Você também pode dar uma olhada no wiki do usuário para outras técnicas de descarte. http://code.google.com/p/libgdx-users/wiki/Culling


2
pointInFrustum (point) retorna true se o ponto especificado estiver dentro do frustum, não em um Sprite. O Sprite pode ter sua própria largura e altura, portanto não é possível verificar se ele está dentro da tela usando esse método diretamente.
Arielsan

@arielsan Desde que você possa verificar se há um ponto dentro do frustum, basta verificar se todos os quatro pontos de um sprite estão em um frustum.
TomTsagk

3

Se você estiver criando um jogo 2D com blocos, poderá implementar facilmente seu próprio descarte, o que é muito mais barato, pois você apenas itera exatamente o que precisa dentro do seu conjunto de blocos.

Coisas que você deve saber:

  • Localização da câmera
  • Largura / altura da janela de visualização
  • Largura / altura do ladrilho

Agora podemos calcular quantas peças devem ser desenhadas.

  • Total de blocos horizontais na tela = viewport.width / tileWidth
  • Total de blocos verticais na tela = viewport.height / tileHeight

A matemática depende de como tudo está configurado, mas é muito simples. Por exemplo, faz diferença se o centro da tela é o local da câmera, o canto superior esquerdo ou o canto inferior esquerdo.

Você deve terminar com algo assim:

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

O benefício disso ao verificar se um ponto está dentro do seu frustum é que, com o último, você precisa iterar sobre cada ponto, em vez de usar uma matriz simples em que você sempre itera sobre uma quantidade definida de peças que é igual à quantidade de peças horizontais * azulejos verticais que realmente precisam desenhar. Dessa forma, você pode ter mapas enormes e ainda ter uma boa taxa de quadros. Infelizmente, isso fica mais difícil e complicado ao usar o 3D, mas fica exponencialmente mais difícil com a liberdade que o usuário obtém com a câmera. Você pode imaginar uma câmera de perspectiva fixa que se move com o personagem e precisa de algumas variáveis ​​codificadas para fazer os mesmos truques em uma série de malhas que representam seu mapa.


0

Basta usar a verificação da esfera delimitadora (você pode calcular o raio usando pitágoras) É rápido como o inferno e também trabalha com rotação. Não é perfeito, mas nunca causa abate falso.

Para a versão otimizada ad hoc, o Intersector possui alguns métodos de retângulo e retângulo, que também podem funcionar. Mas você precisa calcular o retângulo para o frustum da câmera.


0

Esta função verifica se um ator está visível (funciona apenas para 2D). Funciona em todas as situações, por exemplo, quando o ator está dentro de um grupo.

    /**
     * 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()
                );
    }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.