L’instanciation par le code (avec si possible un zeste d’aléatoire) est une tâche extrêmement courante dans le processus de création de la plupart des jeux vidéo.

Voyons ensemble comment faire en utilisant GDScript.

Situation de départ

Pour commencer, j’ai :

  • Une scène 2D qui contient juste une PackedScene de type Player.
  • La PackedScene Player est un node de type Kinematic2D parent d’un Sprite et d’un Collision2D. Est associé un simple script pour bouger le player avec les touches du clavier.
  • Une autre PackedScene qui est un Area2D parent d’un Sprite (multiframe) et d’un Collission2D. Est associé un script pour exporter le type d’item (frame, nom et valeur de score).

Voila ce que nous allons faire :

Instancier l’Item

Dans le script de la scène parente, on commence par déclarer une variable qui va pointer vers notre PackedScene grâce au mot clé « preload » :

Ensuite, on crée une fonction qui va générer le ou les items puis on la passe dans _ready() pour appeler cette fonction à l’appel de ce script :

Notre variable « item » et de type Packedscene, cette class permet différente méthode et notamment la méthode .instance() qui permet de générer une instance de l’objet. On stock cette nouvelle instance dans une nouvelle variable pour pouvoir la manipuler facilement plus tard :

func spawnItem():
	var inst = item.instance()

Avant de continuer dans le script principale, il convient de créer une fonction dans le script de notre item afin de déterminer via ses arguments quelques caractéristique qui seront utilisé lors de la création des instances. Par exemple, sa position.

On ouvre le script de l’item et on crée une fonction « initialize() » (le nom importe peu) pour laquelle nous allons passer des arguments. Dans mon cas, les arguments sont la position (pos) et la famille d’items (familly) :

func initialize(pos, familly):
	pass

Cet item contient un enumerate qui va determiner son nom, son sprite et sa valeur de score :

extends Area2D

enum type_item {APPLE = 16, GEM = 26, SWORD = 39, KEY = 59}
export(type_item) var item_type
var my_name
var score

func initialize(pos, familly):
	self.position = pos
	item_type = familly
	match item_type:
		type_item.APPLE :
			$Sprite.frame = 16
			my_name = "une Pomme yeahh !!!"
			score = 10
		type_item.GEM :
			$Sprite.frame = 26
			my_name = "une Gemme yeahh !!!"
			score = 20
		type_item.SWORD :
			$Sprite.frame = 39
			my_name = "une Epée yeahh !!!"
			score = 10
		type_item.KEY :
			$Sprite.frame = 59
			my_name = "une Clef yeahh !!!"
			score = 10

Dans le script parent, les arguments pos et familly seront envoyés au script à l’appel de cette méthode .initialize() sous cette forme par exemple :

func spawnItem():
	var inst = item.instance()
	inst.initialize(Vector2(500, 500, 16)

Il ne reste plus qu’une dernière chose à faire, a savoir créer l’instance dans la scène parente. Pour cela on ajoute un enfant à la scène :

func spawnItem():
	var inst = item.instance()
	inst.initialize(Vector2(500, 500, 16)
	self.add_child(inst)

Et pour finir, voila a quoi ressemble le code final du script parent :

extends Node2D

onready var screenSize = get_viewport().size
const tile = 64
var item = preload("res://PackedScenes/item.tscn")

func _ready():
	randomize()
	spawnItem()
	
func spawnItem():
	var random_type = [16, 26, 39, 59]
	var X = []
	var Y = []
	for i in range(16) : X.append(i)
	for i in range(10) : Y.append(i)
	X.shuffle()
	Y.shuffle()
	print(X)
	print(Y)
	for i in 10:
		random_type.shuffle()
		var inst = item.instance()
		inst.initialize(Vector2(X[i]*tile+32, 
								Y[i]*tile-32), 
								random_type[0]
								)
		self.add_child(inst)


func hit_item(my_signal01, my_signal02):
	print("Je suis " + str(my_signal01))
	print("Score : " + str(my_signal02))

Et le code de l’item :

tool
extends Area2D

signal hit(value01, value02)

enum type_item {APPLE = 16, GEM = 26, SWORD = 39, KEY = 59}
export(type_item) var item_type
var my_name
var score

func _ready():
	self.connect("hit", get_parent(), "hit_item")
	
func initialize(pos, familly):
	self.position = pos
	item_type = familly
	match item_type:
		type_item.APPLE :
			$Sprite.frame = 16
			my_name = "une Pomme yeahh !!!"
			score = 10
		type_item.GEM :
			$Sprite.frame = 26
			my_name = "une Gemme yeahh !!!"
			score = 20
		type_item.SWORD :
			$Sprite.frame = 39
			my_name = "une Epée yeahh !!!"
			score = 10
		type_item.KEY :
			$Sprite.frame = 59
			my_name = "une Clef yeahh !!!"
			score = 10

func _process(delta):
	pass

func _on_Area2D_body_entered(body):
	self.emit_signal("hit", my_name, score)
	queue_free()

Résultat final :


0 commentaire

Laisser un commentaire