Bagaimana kode Waktu Berhenti atau Waktu Peluru dalam permainan?

11

Saya mengembangkan platformer RPG pemain tunggal di XNA 4.0. Saya ingin menambahkan kemampuan yang akan membuat waktu "berhenti" atau melambat, dan hanya karakter pemain yang bergerak dengan kecepatan asli (mirip dengan mantra Time Stop dari seri Gerbang Baldur). Saya tidak mencari implementasi yang tepat, melainkan beberapa ide umum dan pola desain.

EDIT: Terima kasih semua atas masukan yang bagus. Saya telah menemukan solusi berikut

    public void Update(GameTime gameTime)
        {

            GameTime newGameTime = new GameTime(gameTime.TotalGameTime,
 new TimeSpan(gameTime.ElapsedGameTime.Ticks / DESIRED_TIME_MODIFIER));
            gameTime = newGameTime;

atau sesuatu di sepanjang garis ini. Dengan cara ini saya dapat mengatur waktu yang berbeda untuk komponen pemain dan berbeda untuk sisanya. Ini tentu saja tidak cukup universal untuk bekerja pada permainan di mana waktu warping seperti ini akan menjadi elemen sentral, tapi saya harap ini akan bekerja untuk kasus ini. Saya agak tidak suka fakta bahwa itu mengotori loop Pembaruan utama, tetapi tentu saja adalah cara termudah untuk mengimplementasikannya. Saya kira itu penting sama seperti yang disarankan tesselode, jadi saya akan memberinya tanda centang hijau :)

David Miler
sumber

Jawaban:

8

Ini mungkin solusi yang buruk, tetapi belum tentu. Jika Anda menggunakan waktu delta, Anda dapat mengubahnya untuk mengubah kecepatan hal-hal tertentu.

Sebagai contoh:

player.update(dt)
dt = dt * .5 --half speed
enemy.update(dt)

Ini, tentu saja, hanya berfungsi jika Anda bisa tahu kapan Anda memperbarui musuh daripada sesuatu yang lain. Anda juga bisa memberikan semuanya nilai kecepatan dan melakukan sesuatu seperti:

x = x + xspeed * dt * speed
tesselode
sumber
Bagian pertama masuk akal, bagian kedua tidak jelas
AturSams
2
Berikan saja setiap objek yang menggerakkan variabel kecepatan yang dapat Anda ubah, dan ketika Anda memiliki transformasi (misalnya x), lipatgandakan besarnya dengan variabel kecepatan.
tesselode
Masuk akal sekarang. :)
AturSams
Gagasan kedua terdengar ... mati. Hanya penskalaan gerakan dengan faktor "kecepatan" dapat bekerja untuk objek yang didorong fisika, tetapi AI akan dapat bereaksi pada kecepatan normal, dengan hanya gerakannya yang melambat / terganggu.
Apa maksud Anda AI dapat bereaksi dengan kecepatan normal? Kode apa yang akan dimiliki AI yang tidak dapat menerapkan variabel kecepatan?
tesselode
3

Menggunakan waktu delta (milidetik yang lewat sejak frame terakhir) mungkin tidak cukup untuk memperlambat musuh. Hal-hal seperti laju serangan mungkin diterapkan berdasarkan waktu serangan terakhir. Sementara itu akan memperlambat gerakan jika berdasarkan waktu, itu akan lalai untuk memperlambat laju serangan, casting spell dan efek lainnya (regenerasi kesehatan, durasi efek spell) .. dan semacamnya

Jika Anda ingin memperlambat sekelompok besar elemen gim dalam gim pemain tunggal, Anda bisa membuat jam internal kedua untuk setiap makhluk, jam dimulai pada waktu saat ini ketika makhluk itu muncul. Ketika mantra lambat dilemparkan, setiap frame, jam bertambah x% dari waktu yang sebenarnya berlalu. Semua perilaku monster kemudian ditentukan oleh jam internalnya. Jika berbagai monster memiliki ketahanan terhadap perlambatan, mereka dapat menggunakan jam mereka sendiri, itu pada dasarnya adalah bilangan bulat yang tidak memerlukan banyak ruang atau perhitungan.

Ketika efek lambat berhenti, jam masih digunakan dan bertambah 100% dari waktu yang sebenarnya berlalu.

Ini juga bisa bekerja untuk mempercepat mantra.

@ Sidar: Saya melihat dua pilihan,

  1. Jam internal per makhluk. Untuk mengetahui apakah makhluk itu siap menyerang lagi: simpan waktu terakhir setiap serangan digunakan + waktu pengisian ulang dan periksa apakah jam internal sudah melewati waktu itu.

  2. Satu timer per serangan: Anda tahu berapa lama serangan untuk diisi ulang dan Anda cukup mengatur timer dan kurangi waktu yang berlalu * (% 1-pelambatan) setiap belokan.

Saya pribadi lebih suka menghindari mengurangi beberapa timer individu dan menggunakan satu jam internal untuk menghemat waktu pemrosesan dan kompleksitas.

Ini benar-benar sesuai dengan preferensi (Tidak terlalu mempengaruhi kinerja).

AturSams
sumber
Kebutuhan untuk jam internal tidak diperlukan. Ini hanya datang ke pengganda yang Anda dapat (di suatu tempat) tautan ke objek Anda yang menambah atau mengurangi produk dt Anda (waktu delta) Anda dapat mengelola objek dengan kelompok atau cara apa pun. Saya pikir cara Anda mungkin sedikit berlebihan. Tapi hei, jika berhasil ... maka berhasil.
Sidar
@ Sidar Jika Anda menghindari ini, Anda mungkin akan memerlukan jam per serangan hanya untuk mengisi ulang waktu serangan, durasi Ejaan dan hal-hal semacam itu. Setidaknya dengan cara ini Anda hanya perlu memperbarui satu jam dan cukup simpan waktu 'aktivasi terakhir' untuk mengatur ulang properti.
AturSams
Namun pertanyaannya adalah tentang memperlambat lingkungan kecuali pemain. Bagi saya itu terdengar seperti bentuk paling sederhana dari hanya mengalikan dt dengan angka lebih rendah dari 1. Sambil tetap seperti itu untuk pemain.
Sidar
Yah, memperlambat lingkungan termasuk memperlambat laju serangan mereka serta kemampuan mereka yang lain (karena itu adalah rpg), mungkin ada berbagai kemampuan gerombolan yang bergantung pada waktu pengisian ulang. Menyembuhkan, buff, debuff, mantra, dll. Belum lagi waktu aktivasi.
AturSams
2

Anda bisa mulai dengan solusi sederhana seperti yang diekspos oleh tesselode atau Mr Beast. Tapi jika Anda mulai mencampur hal-hal yang kompleks, yaitu waktu peluru sementara mantra perlambatan dilemparkan, Anda akan terjebak.

Saya sarankan Anda menerapkan hierarki jam :

.
├── Main clock
│   └── UI clock
│   └── 3D clock
│       ├── GFX clock
│       └── Gameplay clock
│           └── Slowdown spell clock 01
│           └── Slowdown spell clock 02

Segala sesuatu dalam gim Anda harus menggunakan waktu delta dari salah satu jam: efek grafis dijalankan pada jam GFX, AI & animasi berjalan pada jam Gameplay, makhluk yang terkena mantra pelambatan yang dijalankan pada jam mantra Pelambatan sementara, dll. Kemudian berbagai hal memengaruhi berbagai bagian hierarki Anda: mantra pelambatan membuat dan memengaruhi jam khusus, sementara waktu peluru akan memengaruhi seluruh hierarki jam 3D.

Laurent Couvidou
sumber
Terima kasih, ini wawasan yang penting. Namun, saya pikir saya akan tetap berpikir sederhana, karena tidak masuk akal dalam kasus khusus saya bahwa beberapa efek perlambatan akan terjadi pada saat yang sama.
David Miler
1

Anda hanya perlu dua jam berbeda, bukan satu, satu untuk waktu yang relevan dengan gameplay dan satu waktu "benar".

currentGameTime = 0;
gameSpeed = 1.0f;
[...]
currentApplicationTime = GetTime():
timeDelta = (currentApplicationTime - lastApplicationTime)*gameSpeed;
currentGameTime += timeDelta;
lastApplicationTime = currentApplicationTime;

Maka Anda cukup mengubah gameSpeed ​​untuk mempercepat (> 1) atau memperlambat waktu (<1). Agar pemain dapat bergerak dengan kecepatan yang berbeda, periksa saja apakah waktunya melambat atau tidak.

API-Beast
sumber