Membuat Loading Bar Menggunakan Script RGSS3

[VXAce] Tutorial Version 1.0

 

Level : Advanced
Kebanyakan game RM saat terjadi transisi (contohnya saat perpindahan dari map ke map), loading processnya tidak keliatan sama sekali, jadi terkesan sebuah game yg tanpa proses. :v
Beberapa developer mengakalinya dengan menggunaan event bergambar loading bar. Tapi dengan event pekerjaannya makin banyak, dan juga ribetnya harus copas event yg sama hanya untuk membuat loading bar di tempat lain. Disini saya akan mengajarkan cara membuat loading bar yang sederhana, yang durasinya bisa kita tentukan sendiri langsung dari scriptnya. Di tutorial loading bar ini juga saya akan mengajarkan beberapa fungsi yang digunakan untuk membuat sebuah loading bar melalui script. Here we go. :3


What Will Be Teached
1. Penggunaan objek module sebagai tempat menyimpan konfigurasi script.
1. Penggunaan objek Game_System sebagai tempat menyimpan data system.
2. Penggunaan objek Game_Interpreter sebagai tempat menyimpan fungsi script call.
3. Sedikit penjelasan tentang Scene_Base.
4. Sedikit penjelasan tentang class Sprite dan metodenya (bitmap, x, y, z, rect, blt).

Preparation
- Persiapkan Desain Loading Bar
Pertama siapin dulu desainnya kaek gimana. Jangan langsung asal hantam script aja tapi ga tau peletakannya gimana. :v #hammer
Kita misalkan desainnya seperti ini (ini model jadinya, kita akan ikuti modelnya):
Untuk itu kita butuh 3 buah gambar. 1 gambar untuk tulisan "Loading ...":
1 gambar untuk base loading barnya :
1 gambar untuk loading barnya :
Persiapan desain sudah selesai. :v
  - Ide Scriptnya
Well, resors udah ada, sekarang kita siapkan ide scriptnya. Ide script adalah membuat script loading bar (u don't say) :v . Loading barnya bisa ngelakuin hal kaek gini :

1. Memunculkan tulisan loading dibagian atas loading bar.
2. Memunculkan gambar loading bar sebagai loadingnya (u don't say it again).
3. Kapan saja bisa diatur berapa lama durasi loadingnya.

Idenya cukup simpel yah? Tapi eksekusinya tidak semudah idenya. :v
Persiapan ide sudah selesai. Berikutnya tahap pembuatan script sesuai ide yang sudah dicantumkan.
  - Pembuatan Script + Penjelasan
Sekarang kita mulai pembuatan scriptnya. Agar mudah dalam konfigurasi, alangkah baiknya kita membuatkan module tersendiri untuk menampung konfigurasi script yang akan kita buat :
Konfigurasi kan ga ada di daftar ide, kok dimasukin? Emang apa untungnya?

Gunanya module itu sendiri buat nyimpen konfigurasi, biar script yang kita buat tidak berhamburan. Bayangin aja kalo misalnya script yang kamu buat dipublish tanpa konfigurasi module. Emang seh scripter ahli pasti bakalan ngerti, tapi gimana ama scripter noob, atau ga yang bukan scripter pake script kamu? Pasti ribet kan? Itulah gunanya konfigurasi module, mereka tidak termasuk dari ide, tapi mereka adalah salah satu INTI dari script itu sendiri. Di konfigurasi itu sendiri, saya membuat beberapa konstanta tempat nyimpen konfigurasi :

LOADING : nyimpen nama gambar tulisan loading
LOADING_X : posisi x dari gambar LOADING
LOADING_Y : posisi y dari gambar LOADING
LOADING_BASE : nyimpen nama gambar base loadingnya
LOADING_BASE_X : posisi x dari gambar LOADING_BASE
LOADING_BASE_Y : posisi y dari gambar LOADING_BASE
LOADING_BAR : nyimpen nama gambar loading barnya
SPEED : kecepatan fill bar per speed pixel

Nama tiap konstantanya terserah kamu saja, kan kamu yang buat script. :v
Konfigurasi sudah selesai, sekarang saatnya nulis scriptnya langsung.
Pertama kita harus nyimpen nilai dari konstanta di module ke sebuah objek script agar bisa diubah2 lewat script call. Disini saya akan menggunakan objek Game_System buat nyimpen kembali nilai speednya :
Eh bentar2. Di konfigurasi script kan udah nyimpen nilai speednya, kok disimpan lagi di tempat lain? Mau borosin script yah? :3
Hey hey, tenang saya jelasin dulu. Baca kembali ide nomor 3, durasinya bisa diatur kapan saja. Konstanta adalah nilai yang tidak dapat diubah secara langsung (statis), untuk itu kita butuh objek lain yang dinamis sebagai tempat untuk menyimpan nilainya. Disini saya memakai objek Game_System. Dan bagusnya lagi, nilai di Game_System akan ikut tersimpan selagi player save game tersebut, jadi saat load game nilai yang diambil adalah nilai dari Game_System. Liat kembali ide nomor 3 : Kapan saja bisa diatur berapa lama durasi loadingnya. Nilai script yang bisa diubah2 kapan saja identik dengan script call melalui event. Dan script call melalui event bisa dilakukan dengan mendeklarasikan metode baru di objek Game_Interpreter. Misalnya kamu memperbolehkan developer menggunakan script call loading_speed(value), dimana value adalah angka baru dari speed tersebut. Kamu bisa menuliskan seperti ini di script kamu : 
 Tapi tunggu dulu. Coba kamu testplay, dan liat apa yang terjadi :
 

Ah sial error lagi. Ini error apaan seh?
Syntax error, dynamic constant assignment. Well mudah saja, syntax error berarti di script kamu ada kesalahan penulisan (di script saya tepatnya di line 26). Terus yang menyebabkan kesalahan penulisan adalah dynamic constant assignment.
Apa lagi tuh?
Inilah kenapa tadi kita harus menyimpan kembali nilai konstanta SPEED ke objek lain yang dinamis (contohnya Game_System), mengingat konstanta itu jenis variabel yang nilainya tetap.
Sekarang coba rubah kembali penulisan script kamu. Ubah dikit aja, ubah aja di line yang error tadi :
Untuk mengakses objek Game_System, RGSS3 menggunakan variabel global $game_system. Untuk mengakses nilai didalam objek Game_System, gunakan tanda titik disertai dengan nilai yang ingin dimanipulasi. Tanda sama dengan (=) akan mengeset nilai baru ke objek Game_System sesuai nilai yang diketikkan tadi. Dengan seperti ini, error yang kaek tadi udah ga ada lagi. #horee

Oke kaeknya ide nomor 1 dan 2 terlewatkan. Gpplah, yang penting sequence scriptnya tidak berantakan. :v
Biar ga bentrok ama scene lain yang sedang berjalan, lebih baik buat scene baru aja dengan pewarisan dari Scene_Base :
Saat membuat scene baru, agar scene bisa jalan maka kita harus membuat method def start (sedikit berbeda dengan class lain yang pake def initialize dan class Scene_base yang pake def main). Isi dari def start kira2 seperti ini :
What is it? Ada include module AGUNG::LOADING dibagian atas?
Tadi waktu awal Scene_base ga sempat discreenshot, jadi baru discreenshot sekarang. Ya itu untuk nyingkat pengaksesan konstanta module aja, daripada harus nulis panjang2 dari parent modulenya kan diinclude aja parent modulenya, biar langsung ngakes konstantanya. :3
Ide nomor 1 dan 2 memunculkan tulisan loading, loading bar basenya, dan loading barnya. Di def start udah dibuatin method buat munculin gambar2 tersebut :
- super : ngambil isi method yang sama dari parent classnya (Scene_Base) terus dipake di child classnya.
- create_background : biar gambar latarnya ngeblur kaek waktu buka menu.
- @load_bar_duration : disini kita bikin sebuah class variable baru buat nyimpen nilai sudah berapa pixel jauhnya loading ditempuh.
- draw_loading_text : method buat nampilin tulisan loading.
- draw_loading_base : method buat nampilin gambar loading basenya.
- draw_loading_bar : method buat nampilin gambar loading barnya.

Sekarang untuk def draw_loading_text :
Well mudah saja. @text itu class variable doank. :v Isi dari @text dideklarasikan sebagai sebuah objek Sprite baru (Sprite.new). Dengan demikian apa saja method didalam objek Sprite bisa diakses lewat class variable @text. :3 Untuk menampilkan gambarnya, kita pake fungsi bitmap dari class Sprite. Tinggal ketik aja @text.bitmap, kan tadi udah diinstansiasikan objek Spritenya ke @text. :v Cache.system(LOADING), berarti kita akan memunculkan sebuah objek bitmap (@text.bitmap) yang isinya diambil dari folder System di project kamu (Cache.system) dengan nama file yang sudah disimpan di konstanta LOADING di konfigurasi script tadi.Oh ya, gambar2 tadi simpan di folder System di project kamu yah buat akses nantinya. :3 @text.x buat ngeset posisi x dari gambar tadi yang nilainya diambil dari konstanta LOADING_X di konfigurasi script. Begitu juga dengan @text.y yang ngatur posisi y. @text.z buat ngatur prioritas tampilan gambar. Semakin besar nilai z, semakin diatas posisi gambar dari gambar yang lain. Ya mirip2 layer di photoshop lah, layer teratas dia yang akan lebih tampak. Untuk def draw_loading_base :
Ga beda jauh dengan def sebelumnya, paling cuman lain di class variablenya dan objek bitmap yang ditampilkan. :3 Nah untuk def draw_loading_bar yang agak ribet : 

Nah sequencenya agak dirubah dikit. Untuk method ini pertama munculin dulu gambar loading barnya, terus set objek bitmap yang width dan heightnya mengikuti gambar loading (gambar loading berukuran 500 x 32 pixel).
Terus dibuatin sebuah object Rect dengan x = 0, y = 0, width = mengikuti durasi load bar berjalan(@load_bar_duration), height = tinggi dari gambar load bar(@load_bar_image.height)

Rect itu apaan seh?
Rect itu semacam kotak. :v #lol Ya objek kotak, dipake buat nyeleksi objek bitmap. Tau kan Rectangular Marquee Tool di photoshop yang dipake buat nyeleksi gambar secara kotak? Nah kaek gitu contohnya. :v
Dengan settingan tersebut maka object Rect akan berada di posisi x = 0 dan y = 0.
Setelah itu kita membuat sebuah block transfer (blt) dari objek bitmap yang tadi dicache (@load_bar_image) ke kotak seleksi Rect tadi (@load_bar_rect).  

Masih ingat kan kalo lebar dari Rect tersebut mengikuti durasi load berjalan? Nah saat pertama dijalankan loading barnya, maka barnya tidak akan keliatan karena lebar dari object seleksi Rect tadi masih 0, dan Rect tersebut akan terus melebar seiring durasi load bar berjalan. Dan juga, posisi Rect tadi kan masih di x = 0 dan y = 0, dengan blt tadi maka posisi Rect akan berada di posisi object bitmapnya. Jadi yang munculin barnya perlahan bukan bitmapnya, melainkan Rect nya. :3 Agar barnya berjalan seiring waktu yang ditempuh, maka kita harus membuat method update yang isinya menambahkan jumlah durasi sampai barnya keliatan penuh. Isi dari def update :
Super, hmm super, udah dijelasin tadi. :v Baris berikutnya membersihkan object bitmap yang tadi sudah dibuat biar kaga numpuk ntar. Biar Rect nya ikut membesar dan bitmapnya ikut terlihat, tulis lagi deklarasi yang sebelumnya ada di draw_loading_bar (deklarasi rect dan blt itu lho. Jangan lupa class variablenya harus sama biar keupdate di def update). Sekarang dibuat lagi sebuah class variable baru buat nyingkat variable loading_speed yang kepanjangan kalo di deklarasikan ulang. :3 Masih ingat dengan @load_bar_duration di def start kan? Nilainya waktu itu masih 0, dan class variable itu menyimpan durasi sejauh mana (dalam pixel) loading bar berjalan. Sekarang kita akan menambahkan durasi tersebut dengan speed yang sudah kita tentukan tadi.
Ada sintaks to_f? Buat apa speednya dijadiin nilai float?
Setelah beberapa kali debugging, ternyata nilai integer akan membuat loading bar tidak terisi penuh oleh nilai2 yang ganjil. Contohnya speed 33 dengan lebar gambar 500. 500 / 33 = 15 sisa 1. Ada sisa hasil bagi yang kalo di nilai integer akan dibulatkan ke 0. Jadi sisa baginya dijadiin nilai float biar tetep kebaca saat loading berjalan. :3 Baris berikutnya buat ngecek kalo (if) durasinya (@load_bar_duration.to_f) sudah lebih dari ( > ) lebar gambar loading barnya (@load_bar_image.width.to_f). Kalo emang udah, maka game akan mengembalikan kita ke scene yang sebelumnya aktif (return_scene).
Itu juga durasinya dijadiin float
Biar bisa keitung nilai kebenarannya bung, jadi tipe datanya disamain aja. :v
Mana def create background? Ga dibahas daritadi
#hammer Sory sory kelupaan. :3 Itu sebenarnya cuman copas dari Scene_MenuBase. Disana juga ada def create_background, ya copas aja, selesai. :v

Sekarang coba panggil scene baru kamu dengan script call SceneManager.call(Nama_Scenenya_Tadi_Apa). Di script ane nama scenenya Agung_Scene_Loading, jadi ane manggilnya SceneManager.call(Agung_Scene_Loading). :3 Dan coba juga untuk mengganti speednya dengan script call, misalnya speednya mau dipercepat jadi 30 pixel, ya tinggal script call loading_speed(30).
Bisa di VX ga?
Bisa aja seh, mengingat bitmap di VX ga beda jauh ama Ace. Cuman akan ada sedikit perbedaan di scriptnya ntar, karena di VX ga ada module SceneManager. :v Kalo mau diporting ke VX, def create_background diubah namanya jadi create_menu_background. Terus def update dibagian kondisi if rubah jadi kaek gini :
Sedikit lebih panjang dari Ace karena VX saat kembali ke scene sebelumnya tidak otomatis dispose segala object dari object sebelumnya. Jadi objectnya harus dihilangkan (dispose) secara manual. Beda lagi dengan Ace yang ketika kamu return_scene, scenenya akan langsung hilang seketika bersama dengan object didalamnya, lalu kembali ke scene sebelumnya. Untuk menjalankannya di VX, panggil pake $scene = Nama_Scenenya_Tadi_Apa.new . Script call untuk ganti speed masih sama dengan Ace. :3
 
Result
Untuk hasil scriptnya mohon maaf hanya bisa digunakan di Scene_Map dahulu, ada sedikit error logic tadi. :v Saya berharap setelah membaca tutorial ini kamu bisa mengerti tentang penggunaan module, Game_System, Game_Interpreter, Scene_Base, ama class Sprite dengan sedikit metode yang sudah saya jelaskan. Dari contoh ini, script buatan saya bisa didapatkan disini.
Panjang yah? Padahal idenya cuman 3 baris doank. Ya seperti itulah buat script bung, andai tadi kaga dikonsepin baek2 idenya pasti bakalan berhamburan. :v
Sekian tutorial dari saya, semoga bermanfaat.


1 comments:

wah ribet juga ya...!! masih mau coba yang ori dulu lah..

Reply

Post a Comment