Don't misunderstand all this. It's not like i'm posting this tutorial for you or anything. i'm just bored... Baka!! (HBK61 Tsundere mode)Ehm, sebelum memulai, saya berasumsi bahwa agan2 yang baca ini sudah paham dasar-dasar ruby seperti method, module, class, hierarchy, instances, variables, comparable, dll, namun masih bingung tentang bagaimana workflow dari RMVX Ace.
Tutorial ini mungkin kurang berguna bagi pengguna VX karena VX tidak menggunakan module-module tertentu seperti SceneManager dan BattleManager. Akan tetapi, tidak ada salahnya juga membaca tutorial ini karena secara garis besar, workflow VX dan VX Ace tidak jauh berbeda.
Untuk sementara, tutorial ini hanya akan menjelaskan prosedur dari awal game dimulai sampai dengan Scene Title selesai diproses.
Kembali ke topik, silakan buat new project, tekan F11, dan lihat di "Main"
- Code:
-
rgss_main { SceneManager.run }
kode di atas adalah akar dari semua permasalahan dari engine RMVX Ace. Apabila line tersebut dihapus, maka semua masalah juga akan hilang (baca: no game at all
)
Awal dari semua (default) game Ace adalah menjalankan method "run" dari module SceneManager. Mari kita lihat sebagian isi dari module tersebut.
- Spoiler:
- Code:
-
module SceneManager
@scene = nil
@stack = []
@background_bitmap = nil
def self.run
DataManager.init
Audio.setup_midi if use_midi?
@scene = first_scene_class.new
@scene.main while @scene
end
def self.first_scene_class
$BTEST ? Scene_Battle : Scene_Title
end
...
end
method run itu berfungsi untuk:
- Menjalankan method init dari module Data_Manager <= intinya sih buat nge-load database dari folder Data
- Menjalankan method setup_midi dari module Audio <= baca di help file
- Mendeklarasikan variable @scene sebagai sebuah instance dari method first_scene_class
- Menjalankan method main dari variable @scene
method first_scene_class merupakan conditional.
Jika $BTEST maka first_scene_class adalah Scene_Battle.
Jika bukan, maka first_scene_class adalah Scene_Title
$BTEST akan diset "true" secara otomatis saat kita menjalankan Battle Test dari tab Troop. Dengan asumsi yang kita jalankan adalah default play test (F12) maka secara garis besar dapat dikatakan bahwa:
- Code:
-
@scene = Scene_Title.new
@scene.main
*)RMVX Ace menggunakan Array @stack untuk mengatur posisi hierarchy scene. Saat sebuah scene dipanggil menggunakan method call, maka current scene akan di push ke dalam array tersebut sehingga saat method return_scene di call dari scene yang baru dibuat, dia akan mengambil kembali scene terakhir dari @stack. (<< saya sendiri bingung gimana jelasinnya ya
)
Untuk lebih jelasnya pake perumpamaan aja deh
- Spoiler:
Awal
@scene = Scene_Map
@stack = []
Nampilin Menu
player pencet tombol Esc ==> SceneManager.call(Scene_Menu)
@stack = [@scene] << @scene di sini adalah Scene_Map
@scene = Scene_Menu.new
Exit Menu
player pencet tombol Esc ==> SceneManager.return
@scene = @stack.pop << elemen terakhir dari @stack diambil dan mengakibatkan @stack jadi kosong
Ada 2 tipe pemanggilan di SceneManager:
method call => push @scene ke dalam @stack
method goto => langsung bikin instance baru
perbedaan mendasar dari kedua method ini adalah apabila sebuah scene dipanggil menggunakan goto, kemudian dilakukan SceneManager.return, maka game akan otomatis keluar karena @stack = [ ]
mudah-mudahan cukup jelas tentang @stack ini
Sekarang mari kita lihat di class Scene_Title, tekan ctrl + F dan ketik "def main".
whaddehel? kok ga ada method main di Scene_Title? Tenang, jangan panik... Coba lihat dulu baik-baik
- Code:
-
class Scene_Title < Scene_Base
Nah, karena di Scene_Title tidak ada method main, maka coba kita lihat di Scene_Base
- Spoiler:
- Code:
-
class Scene_Base
def main
start
post_start
update until scene_changing?
pre_terminate
terminate
end
...
end
Saya hanya akan menjelaskan secara garis besar apa yang dikerjakan oleh method main ini.
- membuat @viewport dengan z=200. Dari hasil penerawangan sekilas, saya melihat bahwa viewport ini nantinya akan digunakan sebagai viewport untuk sebagian besar class Window seperti Window_Menu, Window_Message, dll.
- melakukan transisi dari scene sebelumnya untuk 10 frame
- meng-update Graphics, Input, dan Windows sampai scene tersebut selesai. Perlu diperhatikan bahwa method update perlu diperlakukan dengan hati-hati karena method ini merupakan sebuah loop yang hanya akan berakhir saat scene itu selesai.
- meng-capture Graphics untuk dipergunakan sebagai transisi ke scene berikutnya, menghapus @viewport, menghapus semua window instance (saat scene selesai)
OK, we're done with Scene_Base#main, so far...
Kembali ke Scene_Title...
- Spoiler:
- Code:
-
class Scene_Title < Scene_Base
def start
super
SceneManager.clear
Graphics.freeze
create_background
create_foreground
create_command_window
play_title_music
end
Hal yang pertama dilakukan adalah super, berarti:
- step pertama dari method ini mengacu kepada method start di Scene_Base, yaitu membuat sebuah Viewport dengan z = 200
- SceneManager.clear >> membuat @stack kosong (empty Array)
- Graphics.freeze >> membuat sebuah screen capture untuk transisi
- create_background >> membuat background (Gambar)
- create_foreground >> membuat foreground (Titel game, kalo pilihan Draw Title di cek)
- create_command_window >> membuat command window (yang isinya New Game, Continue, dan Shutdown)
- play_title_music >> dan memutar musik
Mengesampingkan create_background dan create_foreground yang lumayan mudah, mari kita membahas create_command_window
- Spoiler:
- Code:
-
def create_command_window
@command_window = Window_TitleCommand.new
@command_window.set_handler(:new_game, method(:command_new_game))
@command_window.set_handler(:continue, method(:command_continue))
@command_window.set_handler(:shutdown, method(:command_shutdown))
end
hal yang pertama dilakukan oleh method ini adalah
- men-declare @command_window sebagai sebuah instance baru dari class Window_TitleCommand
- menghubungkan antara symbol2 yang ada dengan method tertentu
mari berpaling sebentar ke Window_TitleCommand
- Spoiler:
- Code:
-
class Window_TitleCommand < WIndow_Command
...
def make_command_list
add_command(Vocab::new_game, :new_game)
add_command(Vocab::continue, :continue, continue_enabled)
add_command(Vocab::shutdown, :shutdown)
end
def continue_enabled
DataManager.save_file_exists?
end
...
end
Ini adalah salah satu perbedaan yang cukup menarik antara VX dan VX Ace.
RMVX menggunakan index dari command window itu sendiri, sementara Ace menggunakan Array @list di mana setiap elemennya berisi hash dengan element
- Code:
-
{:symbol, method(method_yang_akan_dipanggil), conditional, ext }
Keterangan lebih lanjut liat Window_Command line 54
Mari kita cari cara gampangnya aja
, format untuk membuat sebuah command di window adalah:
*WARNING: bukan plug n play, cuma format aja loh ini- Spoiler:
- Code:
-
class Your_Window_Name < Window_Command
...
def make_command_list
add_command("Your String", :your_symbol)
<add another add_command method here>
end
...
end
Sedangkan eksekusinya dilakukan dari class Scene_Base dan peranakannya
- Spoiler:
- Code:
-
class Your_Scene
...
def create_command_window
@your_window_name = Your_Window_Name.new #<= bisa diganti dengan class apa aja asalkan classnya Window_Command atau peranakannya.
@your_window_name.set_handler(:your_symbol, method(:command_new_game))
<add another set_handler>
end
...
end
perlu diperhatikan bahwa ":your_symbol" yang di set di Scene dan Window harus sama.
Nah setelah kita tahu bahwa Scene_Title memiliki perintah untuk membuat sebuah Window_TitleCommand dengan 3 link antara symbol dan method di dalamnya, sekarang mari kita lihat command2 yang berhubungan dengan symbol tadi.
back to Scene_Title...
- Spoiler:
- Code:
-
...
def command_new_game
DataManager.setup_new_game
close_command_window
fadeout_all
$game_map.autoplay
SceneManager.goto(Scene_Map)
end
def command_continue
close_command_window
SceneManager.call(Scene_Load)
end
def command_shutdown
close_command_window
fadeout_all
SceneManager.exit
end
...
saat :new_game dipilih, method command_new_game akan dijalankan.
saat :continue dipilih, method command_continue akan dijalankan.
saat :shutdown dipilih, method command_shutdown yang akan dijalankan.
Sementara cukup sekian dulu dari saya, semoga tulisan ini sedikit banyak bisa memberi inspirasi bagi RMID-er. Bagi yang belum tahu, agar bertambah ilmunya, bagi yang sudah tahu agar tetap ingat ilmunya
Mohon koreksi, kritik, atau sarannya
Nambah as requested by TheoAllen
Penggunaan AliasAlias adalah salah satu cara untuk menambahkan line pada suatu method dengan aman.
Langsung contoh ya, coba liat di Game_Actor. Mari kita coba menambahkan instance variable age. Secara default, line nya berbunyi begini
- Spoiler:
- Code:
-
class Game_Actor < Game_Battler
...
def initialize(actor_id)
super()
setup(actor_id)
@last_skill = Game_BaseItem.new
end
def setup(actor_id)
@actor_id = actor_id
@name = actor.name
@nickname = actor.nickname
init_graphics
@class_id = actor.class_id
@level = actor.initial_level
@exp = {}
@equips = []
init_exp
init_skills
init_equips(actor.equips)
clear_param_plus
recover_all
end
...
end
Instance variable biasanya di declare pada saat initialization, namun karena struktur Game_Actor menambahkan semua instance variablenya di method setup, mari kita ikuti struktur default ace aja ya...
Coba buat line script baru di bawah material
- Spoiler:
- Code:
-
class Game_Actor
alias new_setup setup
def setup
new_setup
@age = 0
end
end
Bagaimana maksud script di atas?
Well secara gampangannya sih,
- Code:
-
alias new_setup setup
line ini melakukan "rename sementara" terhadap method setup. Namanya diganti jadi new_setup
- Code:
-
def setup
new_setup
@age = 20
end
nah di tahap ini, dia menjalankan method "new_setup" yang tadi sudah kita rename dahulu, kemudian menambahkan instance @age = 20
Jadi secara keseluruhan system akan membaca seperti ini:
- Spoiler:
- Code:
-
def setup
@actor_id = actor_id
@name = actor.name
@nickname = actor.nickname
init_graphics
@class_id = actor.class_id
@level = actor.initial_level
@exp = {}
@equips = []
init_exp
init_skills
init_equips(actor.equips)
clear_param_plus
recover_all
@age = 20
end
*Perhatikan bahwa @age = 20 ditambahkan pada line setelah new_setup selesai.
Q= Lah bedanya sama menulis method setup dari awal apaan?A= Beda... Bedanya... ummmm
pake contoh lagi ya
Coba buat line baru di bawah penambahan age tadi. Sekarang kita coba menambah gender pada actor.
contoh 1
- Spoiler:
- Code:
-
class Game_Actor
alias new_setup2 setup
def setup
new_setup2
@Gender: "Female"
end
end
contoh 2
- Spoiler:
- Code:
-
class Game_Actor
def setup
@actor_id = actor_id
@name = actor.name
@nickname = actor.nickname
init_graphics
@class_id = actor.class_id
@level = actor.initial_level
@exp = {}
@equips = []
init_exp
init_skills
init_equips(actor.equips)
clear_param_plus
recover_all
@gender = "Female"
end
end
Contoh 1: dia aliasing method setup menjadi new_setup2. Nah, semua method setup yang sudah dilakukan sebelum line ini ditambahkan akan di-run terlebih dahulu, termasuk saat kita menambahkan @age tadi.
Contoh 2: dia langsung overwrite method setup, di sini @age yang tadi kita tambahkan tidak dijalankan karena line ini me-rewrite semua method setup.
Pada praktiknya, pasti kita banyak memakai script add-on. Dan akan terlalu lama untuk meneliti method mana saja yang sudah dialias. Untuk menghindari script-script terlewati seperti contoh 2 tadi, ada baiknya kita selalu melakukan aliasing (sebisa mungkin) untuk menambah compatibility dengan script yang lain.
Kira-kira segitu saja tambahannya, mudah2an ngerti
Special Thanks:GubiD
Huw Collingbourne
Anyone who created RMVX Ace Help File
Anyone who created ctrl + shift + f & ctrl + f on RMVX Ace
Part 2: Database + Notetagging