Jumat, 26 Oktober 2018

Penulisan Script - Part 2

Beberapa aksi dalam Godot dipicu melalui callback atau fungis virtual, maka dari itu tidak selalu diperlukan (menulis sendiri) code untuk menjalankannya.

Bagaimanapun juga, secara umum masih dibutuhkan script untuk melakukan proses terhadap setiap frame. Ada dua tipe pemrosesan (processing): idle processing dan physics processing.

Idle processing akan aktif ketika metode Node._process() terdapat di dalam script. Bisa diatur, dimatikan dan dihidupkan menggunakan fungsi Node.set_process().

Metode ini akan diproses setiap saat frame terload, jadi hal ini sangat berpengaruh terhadap FPS (Frame Per Second).
func _process(delta):
    # Do something...
    pass
Parameter "delta" berisi waktu yang berlalu dalam hitungan detik, yang merupakan titik penting terhadap fungsi _process().

Parameteri ini bisa digunakan untuk memastikan semuanya berjalan selalu pada saat bersamaan, mengesampingkan FPS dari game itu sendiri.

Sebagai contoh, pergerakan suatu object (movement) biasanya dikalikan dengan waktu "delta" untuk memaksa pergerakannya memiliki kecepatan yang sama dan terbebas dari rate (rata-rata) kecepatan frame.

Physics processing dengan menggunakan _physics_process() adalah mirip cara kerjanya, hanya saja metode ini lebih digunakan untuk memproses langkah (dengan suatu pengaruh) fisika pada suatu objek (dalam hal ini adalah node), seperti misal mengontrol sebuah karakter. Semua code yang berada didalam fungsi _physics_process() akan selalu diproses seiring dengan proses fisika dan selalu berjalan pada interval waktu: 60 kali per detik secara default. Anda bisa mengganti interval tersebut pada menu Project Settings, dibawah opsi Physics -> Common -> Physics Fps.

Fungsi _process() sendiri, bagaimanapun tidak tersingkronisasi dengan fisika. Frame rate-nya tidak memiliki nilai konstan dan bergantung terhadap hardware dan optimisasi game.

Cara sederhana untuk melakukan tes pada metode ini adalah dengan cara membuat satu node Label, dengan berisi script sebagai berikut:
extends Label

var accum = 0

func _process(delta):
    accum += delta
    text = str(accum) # 'text' is a built-in label property.
Dimana scene tersebut apabila dijalankan akan memperlihatkan angka yang akan selalu bertambah di setiap frame update.

Grup

Node bisa ditambahkan ke dalam grup (dikelompokkan), sebanyak yang diinginkan per node, dan sangat berguna kedepannya saat mengorganisasi banyak scene. Ada dua cara untuk melakukan ini. Cara pertama mengguanakan visual interface Godot, dari tombol Groups dibawah panel Node, seperti gambar dibawah ini:
Menambahkan ke grup
Menambahkan ke grup
Cara kedua adalah tentunya menggunakan script, melalui code. Satu contoh adalah menandai scene yang termasuk dalam grup enemies (musuh):
func _ready():
    add_to_group("enemies")
Dengan cara ini, jika player ditemukan sedang menyelinap kedalam markas rahasia musuh, maka semua musuh akan diberitahukan tentang hal ini dengan menggunakan metode SceneTree.call_group():
func _on_discovered(): # This is a purely illustrative function.
    get_tree().call_group("enemies", "player_was_discovered")
Code diatas memanggil fungsi player_was_discovered di setiap member grup enemies.

Juga sangat mungkin untuk mendapat semua daftar node dari grup enemies dengan memanggil metode SceneTree.get_nodes_in_group():
var enemies = get_tree().get_nodes_in_group("enemies")
Class SceneTree menyediakan banyak metode yang berguna. Memudahkan Anda untuk berpindah scene atau melakukan reload, untuk keluar dari game atau pause/unpause.

Notifikasi

Godot memiliki sistem notifikasi. Notifikasi biasanya tidak memerlukan script, sebagaimana hal ini adalah merupakan low-level dan fungsi virtual biasanya yang lebih diperlukan. Hanya perlu Anda ketahui saja bahwa notifikasi ini ada. Sebagai contoh, Anda bisa menambahkan fungsi Object._notification() di dalam script Anda:
func _notification(what):
    match what:
        NOTIFICATION_READY:
            print("This is the same as overriding _ready()...")
        NOTIFICATION_PROCESS:
            print("This is the same as overriding _process()...")
Dokumentasi setiap class-nya bisa Anda baca di Class Reference. Meskipun pada dasarnya GDScript memberikan fungsi pengganti yang lebih sederhana.

Fungsi pengganti

Berikut ini merupakan beberapa yang disebut sebagai fungsi pengganti:

func _enter_tree():
    # When the node enters the _Scene Tree_, it becomes active
    # and  this function is called. Children nodes have not entered
    # the active scene yet. In general, it's better to use _ready()
    # for most cases.
    pass

func _ready():
    # This function is called after _enter_tree, but it ensures
    # that all children nodes have also entered the _Scene Tree_,
    # and became active.
    pass

func _exit_tree():
    # When the node exits the _Scene Tree_, this function is called.
    # Children nodes have all exited the _Scene Tree_ at this point
    # and all became inactive.
    pass

func _process(delta):
    # This function is called every frame.
    pass

func _physics_process(delta):
    # This is called every physics frame.
    pass
Seperti yang dibicarakan sebelumnya, bahwa lebih baik menggunakan fungsi diatas dari pada menggunakan cara notifikasi. Yang bagaimana outputnya adalah sama, hanya saja lebih sederhana.

Membuat node

Untuk membuat sebuah node dengan menggunakan code, gunakan metode .new(), seperti dataype class-based lain. Contoh:
var s
func _ready():
    s = Sprite.new() # Create a new sprite!
    add_child(s) # Add it as a child of this node.
Untuk menghapus sebuah node, berada di dalam atau diluar scene, gunakan .free(). Contoh:
func _someaction():
    s.free() # Immediately removes the node from the scene and frees it.
Ketika node terbebaskan (dalam hal ini terhapus), node tersebut juga selalu menghapus node anakannya (apabila ada). Karena itu, menghapus node secara manual lebih mudah dilakukan daripada memunculkannya. Menghapus node utama akan menghapus semua yang melekat terhadapnya.

Sesuatu mungkin saja "mencegah" node kita terhapus pada saat ingin menghapusnya, dikarenakan sedang memancarkan signal atau sedang melakukan panggilan terhadap sebuah fungsi. Hal ini akan membuat game kita berhenti (crash). Menjalankan Godot dengan debugger akan selalu memonitor setiap kasus yang dialami game Anda.

Cara paling aman dalam menghapus sebuah node adalah dengan Node.queue_free(). Ini akan menghapus node secara aman selama idle.
func _someaction():
    s.queue_free() # Queues the Node for deletion at the end of the current Frame.


Membuat instance sebuah scene

Membuat instance menggunakan code bisa dilakukan dengan dua cara. Yang pertama adlah dengan me load scene dari hard drive Anda:
var scene = load("res://myscene.tscn") # Will load when the script is instanced.
Menggunakan preload bisa dibilang lebih mempermudah kerja sistem, karena code ini dieksekusi secara lokal  (pada waktu awal sebelum scene di load) oleh Godot:
var scene = preload("res://myscene.tscn") # Will load when parsing the script.
Tapi scene belum bisa disebut sebuah node. Scene merupakan resource lain yang disebut PackedScene. Untuk membuat node dari sebuah scene, bisa digunakan metode berikut PackedScene.instance(). Metode ini akan membuat tree sebuah node bisa ditambahkan ke scene aktif:
var node = scene.instance()
add_child(node)
Kelebihan dari dua-langkah proses diatas adalah PackedScene yang ter-load akan selalu siap untuk di-load ulang sebanyak apapun sesuai keinginan Anda. Hal ini sangat berguna untuk meng-instance musuh, peluru, dan banyak objek lain secara masal di dalam sebuah scene aktif.

0 komentar:

Posting Komentar