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:
control
adalah 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 ms
untuk mengeksekusi. Biasanya, penundaan meningkat hingga0.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
FPS
dari permainan ini adalah kira-kira87
, itu paku secara acak ke (pada akhir rendah)60 FPS
, namun lonjakan ini tidak terkait dengan pelepasan manik-manik. Tidak adaFPS
kekurangan untuk melakukan ini. Ini masuk akal karena satu-satunya bagian yang meningkatkan kompleksitasnya setelah manik dilepaskan adalahupdate()
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.
Jawaban:
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.
sumber