Deteksi Tabrakan Memperlambat Gambar Layar

8

Saya baru-baru ini mengejar pengembangan game sebagai hobi, dan memutuskan bahwa untuk belajar masuk dan keluar dari pengembangan game, bahwa saya harus membuat game dan membuat semuanya sendiri (tanpa menggunakan mesin game). Ini terbukti agak rumit, namun saya membuat kemajuan besar. Namun, saya mengalami masalah yang menurut saya mungkin terkait dengan cara ponsel Android merender gambar mereka dan akan membutuhkan klarifikasi tentang masalah ini.

Masalah

Gim saya berisi serangkaian bola dalam meriam; ketika pengguna menekan layar, meriam meluncurkan bola dan mesin (yang saya laksanakan) menangani pembaruan informasi lokasi dan deteksi tabrakan dari sana. Sekarang, sebelum saya menerapkan deteksi tabrakan, permainan saya berjalan sangat lancar dan responsif, namun ketika saya memberi tahu mesin untuk hanya menggambar manik-manik jika berada dalam batas, dan "memantulkannya" ke dinding, jika tidak, sepertinya mesin loop sekarang membutuhkan waktu yang jauh lebih lama untuk dijalankan.

Ini akan baik-baik saja, jika bukan karena latensi itu menyediakan pengalaman pengguna. Misalnya ketika layar disentuh sekarang , dibutuhkan ~ 2 detik untuk bola ditampilkan sebagai bergerak di sekitar layar, dan kadang-kadang tidak muncul sama sekali . Sebelumnya, reaksinya seketika.

Lebih lanjut, ketika saya berkomentar tentang bagian pendeteksian tabrakan dari mesin fisika saya, ia melanjutkan kembali perilaku responsifnya yang biasa.

Apa yang Saya Pikirkan Menyebabkan Perilaku Ini

Catatan: Saya telah menarik kembali asumsi ini (lihat 'Informasi Debugging' di bawah)

Saya pikir karena saya tidak memiliki frame limiter diimplementasikan untuk permainan saya, dan itu membuat secepat perangkat keras akan memungkinkannya, bahwa itu menggambar begitu banyak frame lama (dalam beberapa buffer, mungkin?) Ke layar yang sibuk menggambar sementara harus memperbarui fisika. Meskipun debugging saya sejauh ini belum mengindikasikan bahwa ini adalah kasusnya, saya sepertinya tidak dapat mencapai kesimpulan lain.

Beberapa kode

Perhatikan bahwa kode ini akan agak membingungkan untuk memahami tidak mengetahui apa yang dilakukan semuanya. Saya hanya memasukkannya jika ada orang yang memiliki kode tertentu untuk dikerjakan. Variabel diklarifikasi di bawah kutipan.

PhysicsEngine.updateBeadPositions (float) :

private void updateBeadPositions(float delta){

    //Update all of the beads currently on the board.
    beads = control.getBoard().getValues();

    temp_x = 0.0f;
    temp_y = 0.0f;

    //For each row...
    for(Bead[] row : beads){

        //For each bead...
        for(Bead bead : row){

            //If this bead exists...
            if(bead != null){

                temp_y = (float) (bead.getYCoordinate() * bead.getYVelocity() * delta);

                //If the coordinates are within the bounds of the game
                if(outwithVerticalBounds(temp_y, control.getBoard())){

                    //Set the X coordinate equal to the distance * the time differential (delta).
                    bead.setXCoordinate(temp_x);

                    //Set the X coordinate equal to the distance * the time differential (delta).
                    bead.setYCoordinate(temp_y);
                }
            }
        }
    }

    //If the cannon Bead has been set...
    if(control.getCannon().getReleased() != null){

        //Update the cannon bead
        if(control.getCannon().getReleased().getXVelocity() == PhysicsEngine.VELOCITY_STATIC && control.getCannon().getReleased().getYVelocity() == PhysicsEngine.VELOCITY_STATIC){

            control.getCannon().getReleased().setXCoordinate(control.getCannon().getX());
            control.getCannon().getReleased().setYCoordinate(control.getCannon().getY() - Cannon.PIVOT_Y_OFFSET);
        }
        else{

            temp_x = control.getCannon().getReleased().getXCoordinate() + (control.getCannon().getReleased().getXVelocity() * delta);
            temp_y = control.getCannon().getReleased().getYCoordinate() + (control.getCannon().getReleased().getYVelocity() * delta);

            //TODO: Commented out collision checkers!

            //If the horizontal coordinates are within the bounds of the game
            if(!outwithHorizontalBounds(temp_x, control.getBoard())){

                //If the vertical coordinates are within the bounds of game
                if(!outwithVerticalBounds(temp_y, control.getBoard())){

                    //Set the X coordinate equal to the distance * the time differential (delta).       
                    control.getCannon().getReleased().setXCoordinate(temp_x);

                    //Set the X coordinate equal to the distance * the time differential (delta).
                    control.getCannon().getReleased().setYCoordinate(temp_y);
                }
                //Otherwise...
                else{

                    //Bounds off the wall in the y direction
                    control.getCannon().getReleased().setYVelocity(-1.0f * control.getCannon().getReleased().getYVelocity());
                }
            }
            //Otherwise...
            else{

                //Bounce off the wall in the x direction (flip the x velocity)
                control.getCannon().getReleased().setXVelocity(-1.0f * control.getCannon().getReleased().getXVelocity());
            }
        }
    }
}

Di sini, variabel didefinisikan sebagai:

  • controladalah referensi ke pengontrol permainan saya. Paket sebagian besar kode permainan.

  • beads adalah referensi ke array 2D yang berisi manik-manik di papan saat ini (tidak termasuk yang bergerak)

  • delta adalah perbedaan waktu antara panggilan sebelumnya ke mesin fisika, dan panggilan saat ini

Lihat komentar di dalam kode untuk penjelasan lainnya.

PhysicsEngine.outwithHorizontalBounds (float, Board) :

private boolean outwithHorizontalBounds(float x, Board board){

    //If the horizontal values are within the bounds...
    if(x > (board.getRight() - bead_radius)){

        return true;
    }

    if(x < (board.getLeft() + bead_radius)){

        return true;
    }

    //Otherwise, it is not.
    return false;
}

Metode outwithVerticalBounds(float, Board)ini memiliki fungsi yang setara, tetapi dalam arah y.


Pertanyaan saya

Bagaimana dengan deteksi tabrakan akan menyebabkan rendering layar terhambat secara drastis? Saya tahu ini adalah operasi yang sangat intensif, tetapi debugging saya telah menunjukkan bahwa pembaruan fisika selesai pada waktu yang sama dengan undian.

Informasi Debugging

Terakhir Diperbarui: 29 Jan 2013 16:27 EST

Berikut ini adalah agregasi dari informasi debug yang saya dapatkan sejauh ini. Saya akan memperbarui ini seiring berjalannya waktu:

  • The update()Metode dalam mesin saya, mengambil, rata-rata, hanya .018 msuntuk mengeksekusi. Biasanya, penundaan meningkat hingga 0.020 ms, ketika saya mengetuk layar untuk melepaskan manik-manik.

  • Setelah membandingkan waktu pengundian dan pembaruan game, akan tampak bahwa saya benar: semuanya terjadi secara bersamaan . Jadi, ini bukan masalah, kan?

  • The FPSdari permainan ini adalah kira-kira 87, itu paku secara acak ke (pada akhir rendah) 60 FPS, namun lonjakan ini tidak terkait dengan pelepasan manik-manik. Tidak ada FPSkekurangan untuk melakukan ini. Ini masuk akal karena satu-satunya bagian yang meningkatkan kompleksitasnya setelah manik dilepaskan adalah update()panggilan, menggambar masih terjadi secepat mungkin.

  • Setelah pengujian lebih lanjut, menjadi jelas bahwa ini bukan kasus bahwa layar tertinggal dari fisika. Saya menguji ini dengan bendera boolean sederhana di mana latar belakang layar akan menjadi putih ketika saya menyentuhnya, dan ini terjadi segera . Dengan demikian, harus ada beberapa penyebab lain untuk manik-manik tidak menarik Saya akan segera memperbarui.

Informasi suplemen

Berikut adalah beberapa informasi tambahan yang akan membantu Anda memahami keadaan saya:

  • Saya menguji ini di Google Nexus 7.

  • Ada beberapa manik-manik di peta yang diperbarui sekaligus (sekitar 30), tetapi hanya satu yang bergerak.

  • Biasanya, setelah manik mulai bergerak (setelah penundaan awal dan jika itu benar-benar menarik), terus bergerak dengan cara yang sangat halus.

  • Penting untuk dicatat bahwa saya memiliki elemen UI lain di layar yang diperbarui sebagai reaksi terhadap acara sentuh. Misalnya, manik-manik yang dimuat dalam meriam menjadi manik-manik baru ketika layar disentuh (menandakan bahwa itu telah dirilis), tetapi manik-manik ponsel tidak ditarik.

Squagem
sumber
Pikirkan proses debug Anda yang menunjukkan pembaruan fisika sesuai dengan undian mungkin tidak akurat? Sudahkah Anda melakukan profiling lain dengan kode ini?
MichaelHouse
Saya telah melakukan beberapa debugging ekstensif menggunakan output ke konsol (LogCat), namun tidak ada yang lebih rumit dari ini. Bisa jadi pernyataan debug saya salah, saya akan memeriksanya sekarang.
Squagem
Yang juga menarik adalah jika FPS (Frames Per Second) berubah ketika menambahkan case bounding, atau bahwa masalahnya tidak terkait dengan seberapa cepat program berjalan.
Qqwy
Saya telah mengedit pertanyaan saya untuk menjawab poin yang telah Anda angkat.
Squagem

Jawaban:

8

Terus terang, saya agak malu untuk mengumumkan solusi untuk masalah saya karena saya menghabiskan banyak waktu untuk mencarinya, dan itu sangat sederhana dan bisa dihindari dengan mudah dengan sedikit kelalaian atas nama saya. Sisi baiknya, saya akhirnya menemukan beberapa kode lain yang sekarang dapat saya optimalkan untuk kinerja yang lebih baik!

Solusinya

Meriam yang meluncurkan manik berada di bawah batas bawah area yang bisa dimainkan.

Ini menyesatkan karena batas bawah area bermain saya sedikit di atas bagian bawah layar ponsel yang sebenarnya. Jadi, pada dasarnya, mesin fisika memantul kembali dan keempat sedikit (tidak terlihat oleh inspeksi manusia) selama sekitar 5 detik sebelum ditampilkan di layar.

Saya memindahkan meriam 50 piksel lebih tinggi dan berfungsi seperti yang dimaksudkan sekarang.


Terima kasih atas bantuannya! Saya tidak akan sampai di sini tanpa saran Anda yang bijaksana.

Squagem
sumber
3
+1 untuk pertanyaan yang diformat dengan baik dan +1 untuk menjawabnya sendiri
RoughPlace
Aduh, lupakan pertanyaan ini! Terima kasih teman-teman :)
Squagem