Mendeteksi jika sprite telah meninggalkan kamera dalam libgdx?

8

Apakah ada metode untuk mengetahui apakah sprite telah meninggalkan kamera panggung? atau saya harus melakukan operasi saya? : P

Rudy_TM
sumber

Jawaban:

5

Kelas Kamera berisi objek Frustum dengan titik metode publikInFrustum (titik Vector3) yang mengembalikan true jika sprite Anda berada dalam frustrasi kamera. Anda juga dapat melihat wiki pengguna untuk teknik pemusnahan lainnya. http://code.google.com/p/libgdx-users/wiki/Culling

Majd
sumber
2
pointInFrustum (point) mengembalikan true jika titik yang ditentukan berada dalam frustum, bukan Sprite. Sprite dapat memiliki lebar dan tinggi sendiri sehingga tidak dapat diperiksa untuk berada di dalam layar menggunakan metode itu secara langsung.
arielsan
@arielsan Selama Anda dapat memeriksa apakah suatu titik berada di dalam frustum, Anda dapat dengan mudah memeriksa apakah keempat titik sprite berada dalam frustum.
TomTsagk
3

Jika Anda membuat gim 2D dengan ubin, Anda dapat dengan mudah menerapkan pemusnahan sendiri yang jauh lebih murah karena Anda hanya mengulangi apa yang Anda butuhkan dalam larik ubin.

Hal yang harus Anda ketahui:

  • Lokasi kamera
  • Lebar / tinggi viewport
  • Lebar ubin / tinggi

Sekarang kita dapat menghitung berapa banyak ubin yang harus ditarik.

  • Total ubin horizontal pada layar = viewport.width / tileWidth
  • Total petak vertikal pada layar = viewport.height / tileHeight

Perhitungannya tergantung pada bagaimana semuanya diatur tetapi sangat sederhana. Misalnya itu membuat perbedaan jika pusat layar adalah lokasi kamera, kiri atas atau kiri bawah.

Anda harus berakhir dengan sesuatu seperti ini:

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

Manfaat dari ini lebih dari memeriksa jika suatu titik berada dalam frustum Anda adalah bahwa dengan yang terakhir Anda perlu mengulangi setiap titik alih-alih menggunakan beberapa array sederhana di mana Anda selalu beralih pada jumlah ubin yang sama dengan jumlah ubin horizontal * Ubin vertikal yang sebenarnya perlu digambar. Dengan cara ini Anda dapat memiliki peta besar dan masih memiliki frame rate yang bagus. Sayangnya ini semakin sulit dan rumit ketika menggunakan 3D tetapi semakin eksponensial dengan kebebasan yang didapat pengguna dengan kamera. Anda dapat membayangkan kamera perspektif tetap yang bergerak dengan karakter hanya membutuhkan beberapa variabel hardcoded untuk melakukan trik yang sama pada array jerat yang mewakili peta Anda.

Madmenyo
sumber
0

Cukup gunakan bounding sphere check. (Anda dapat menghitung radius menggunakan pythagoras) Ini sangat cepat dan juga bekerja dengan rotasi. Itu tidak sempurna tetapi tidak pernah menyebabkan pemusnahan palsu.

Untuk versi yang dioptimalkan ad hoc, Intersector memiliki beberapa persegi panjang yang berisi metode persegi panjang yang dapat digunakan juga. Tetapi Anda perlu menghitung persegi panjang untuk kamera Anda sendiri.

kalle_h
sumber
0

Fungsi ini memeriksa apakah aktor terlihat (hanya bekerja untuk 2D). Berfungsi dalam semua situasi, misalnya ketika aktor berada di dalam grup.

    /**
     * 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
sumber