[TUTO] Créer un jeu avec GameMaker

Pour tout ce qui est fan arts, homebrew, shooters codés à la main, rip de sprites, doujins et toute autre productions artistiques ou logicielles faites maison.
Répondre
serod
Insert Coin
Messages : 5
Inscription : 17 janv. 2012, 20:57

Merci pour la rapidité de ta réponse, c'est super que ça puisse se faire : )
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

voilà, le tuto n'est pas terminé...
Mais si tu es intéressé, je peux reprendre l'écriture et corriger des choses...

Tuto.rar - 0.29MB
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
serod
Insert Coin
Messages : 5
Inscription : 17 janv. 2012, 20:57

Super : )
J'avais commencé à étoffer un moteur de shmup codé en Jse à partir de quelques classes de base qu'on a étudié en cours, mais en surfant j'ai découvert cette petite application qui pourrait bien de m'éviter à avoir à réinventer la roue.
J'étudierai attentivement ton document dans mon temps libre et je reviendrai vers toi dès que j'aurai fini. En tout cas merci beaucoup pour le partage et la motivation que tu y mets.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Pas sûr que le tuto t'aide énormément vu que tu as déjà des notions de programmation...

Il apprend surtout la philosophie gamemaker, apprendre à réfléchir et monter des mini projets et comment se débrouiller avec l'aide.

Pour ce qui est du coding, y en a pas des masses ^^
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Je vais reprendre l'écriture du tuto...
Et je vais en réécrire la majorité.
Je vais écrire les parties suivant mes envies et faire une compilation des écris plus tard.

Je ferai des "mini tuto" que je posterai sporadiquement ici pour décrire des techniques avec gamemaker.

A la fin, l'ensemble des mini tuto formeront un mega tuto sous forme de livre au format PDF.
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Voilà, je commence l'écriture du prochain tuto au format "How to", donc sans réellement d'explications en dehors des commentaires dans le code.

Il concernera la création d'un système de menu, avec les choix pour lancer une partie, quitter, vue des highscores et régler les options sonores.

Une seule technique présentée, sur deux possibles. En gros, Une technique multi-rooms et une technique mono-room.

Je verrai si j'inclurai ou non un système de sauvegarde des options. ( car faut que je regarde comment on utilise les fichiers *.ini avec gamemaker )
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Créer un menu

I] Prérequis

Pour créer un menu, il faut avoir un certain niveau d'abstraction. C'est à dire que le joueur va voir du texte, des images, une interface, qui pour nous ne seront représentés que par des chiffres, des valeurs.
Par exemple, quand le joueur verra les boutons « Jouer » « Options » ou « Quitter », nous, dans notre code nous ne verrons que des valeurs de type 1, 2 ou 3 et nous feront des actions en fonction de la valeur que le joueur choisira. Ce n'est pas l'unique manière de faire. Mais une relativement intuitive à mettre en place.
Dans un menu, il faut voir les choses comme un question du type « Choisi-tu l'option 1 2 ou 3 ? »

II] Phase de réflexion

1) Définition des besoins du joueur

Comme toute partie d'un jeu, on passe d'abord par une phase de réflexion. Définir ce que l'on veut faire.
Pour notre menu, nous voulons que le joueur puisse choisir entre :

Lancer une partie
Régler les options de jeu
Voir les scores
Quitter le jeu


Nous voulons que le joueur puisse régler les options dans une room particulière, voir les scores dans une room particulière, et que la partie se lance dans ces rooms dédiées.

Il faut que les options modifiées par le joueur soient conservées au moins durant le temps de la partie. Ce qui veut dire que les données doivent être conservées quelque soit la room dans laquelle le joueur se trouve.

Nous voulons que le joueur puisse régler le volume des effets sonores , des musiques, écouter les sons et les musiques ( autrement dit, un sound test ), la difficulté, le nombre de vies de départ.

Nous voulons aussi que le joueur puisse choisir les options ou les modifier aussi bien au clavier qu'à la souris.

2) Définition des besoins du programmeur et écriture des scripts

Comme dit au début, la façon la plus naturelle de voir un menu, c'est de le représenter par un questionnaire à tiroirs. A chaque tiroir correspondra une room, exception faite pour la « réponse » « Quitter » du joueur. Nous aurons besoin d'un objet de contrôle pour stocker la valeur de « choix ».

Tiroirs principal
=> Jouer
Lance une partie
=> Options
Emmène dans le menu des options
=> Highscores
Emmène dans la room des highscores
=> Quitter
Quitte la partie.

En algorithmique ca donne quelque chose du genre :

Code : Tout sélectionner

Si ( choix_joueur == 1)
{
	Aller dans room premier niveau ;
}

Si ( choix_joueur == 2)
{
	Aller dans room options;
}

Si ( choix_joueur == 3)
{
	Aller dans room highscore;
}

Si ( choix_joueur == 4)
{
	Quitter le programme;
}
On pourra simplifier comme cela :

Code : Tout sélectionner

Cas_possibles ( choix_joueur )
{
	Cas 1 : Aller première room du jeu ;
	Cas 2 : Aller room options ;
	Cas 3 : Aller room highscore ;
	Cas 4 : Quitter programme ;
}
Code :

Code : Tout sélectionner

switch (choix)
{
    case 1 : room_goto(jeu); break;
    case 2 : room_goto(options); break;
    case 3 : room_goto(highscores); break;
    case 4 : game_end(); break;
}
Maintenant, réfléchissons au mécanisme de sélection au clavier. Le joueur sélectionnera un menu avec les touches haut et bas. Il faut que ca puisse faire une « boucle ». Ce qui induit que si la variable « choix » est supérieur à 4, elle devra prendre la valeur 1, et si « choix » prend une valeur inférieur à 1, elle devra prendre la valeur 4.

Code :

Code : Tout sélectionner

if ( choix < 1 )
{
	choix=4 ;
}

if ( choix > 4 )
{
	choix=1 ;
}
Le mécanisme de sélection  avec les touches du clavier ne devra incrémenter ou décrémenter choix qu'à la condition que la touche haut ou bas soit pressée. Dans le cas où le joueur maintienne la touche, il ne faut pas que cela change continuellement la valeur de « choix ».
Nous avons défini que haut remonte le menu, et de par la conception que nous avons donné à notre menu, il faut décrémenter, inversement, la touche bas incrémentera.

Code :

Code : Tout sélectionner

if ( keyboard_check_pressed(vk_up) )
{
	choix -= 1 ;
	if ( choix < 1 )
	{
		choix=4 ;
	}
}

if ( keyboard_check_pressed(vk_down) )
{
	choix += 1 ;
	if ( choix > 4 )
	{
		choix=1 ;
	}
}
Pour valider, on va utiliser la touche « entrée ». Et c'est à ce moment là que nous exécuterons le code de sélection de salle écris plus tôt.

Code :

Code : Tout sélectionner

if ( keyboard_check_pressed(vk_enter) )
{
	switch (choix)
	{
	    case 1 : room_goto(jeu); break;
	    case 2 : room_goto(options); break;
	    case 3 : room_goto(highscores); break;
	    case 4 : game_end(); break;
	}
}
Maintenant, le mécanisme à la souris. Ce mécanisme peut paraître plus complexe, mais restera relativement simple. Il n'y a pas de gestion d'interface dans gamemaker, il va donc falloir passer autrement.

Une méthode, consiste à regarder s'il y a une collision entre le pointeur de la souris et un un des boutons. Ca sous-entend que nous avons besoin d'un objet pour chaque bouton. Plusieurs méthodes, créer un objets qui suivra le pointeur, ou simplement vérifier quel objet est sous le pointeur au moment du clic.

Nous allons choisir la seconde solution. Moins gourmande et très précise ( trop dans certaines situations ). Pour vérifier ce qu'il y a sous le pointeur, on va utiliser l’événement « mouse_enter » qui est l'équivalent du « hover » ( survol ). Quand le pointeur survol un des objets, cela modifie la valeur de la variable « choix ».
Comme l'événement « mouse_enter » n'est pas détecté par la souris mais par un objet, cela va délocaliser les scripts non pas sur la souris, mais sur les objets des boutons.

Nous créons donc 4 objets dans notre exemple, un pour « jouer », options, highscores et quitter. Le script de validation sera exécuté quand le joueur pressera le bouton gauche de la souris. Il faut aussi prévoir le cas où le joueur clique en dehors d'un bouton. Pour cela, on va utiliser l'événement « mouse_leave » et passer a variable choix à 0 ( zéro ). Il ne faut pas oublier que nous allons changer la valeur d'une variable contenue dans un autre objet.

code  pour le bouton jouer:

Code : Tout sélectionner

controle.choix=1 ;
code  pour le bouton option:

Code : Tout sélectionner

controle.choix=2 ;
code  pour le bouton highscores:

Code : Tout sélectionner

controle.choix=3 ;

code  pour le bouton quitter:

Code : Tout sélectionner

controle.choix=4 ;
Code pour événement mouse_leave :

Code : Tout sélectionner

controle.choix=0 ;
Le code est extrêmement simple.

Maintenant que nous avons tous nos petits scripts, il faut les mettre dans les bons objets avec les bons événements...

III] L'intégration


Objet : oControle

event step :

Code : Tout sélectionner

if ( keyboard_check_pressed(vk_up) )
{
	choix -= 1 ;
	if ( choix < 1 )
	{
		choix=4 ;
	}
}

if ( keyboard_check_pressed(vk_down) )
{
	choix += 1 ;
	if ( choix > 4 )
	{
		choix=1 ;
	}
}

if ( keyboard_check_pressed(vk_enter) )
{
	switch (choix)
	{
	    case 1 : room_goto(jeu); break;
	    case 2 : room_goto(options); break;
	    case 3 : room_goto(highscores); break;
	    case 4 : game_end(); break;
	}
}

if ( mouse_check_button_pressed(mb_left) )
{
	switch (choix)
	{
	    case 1 : room_goto(jeu); break;
	    case 2 : room_goto(options); break;
	    case 3 : room_goto(highscores); break;
	    case 4 : game_end(); break;
	}
}
Exemple d'un des boutons du menu :

Objet : oJouer
event mouse_enter :

Code : Tout sélectionner

controle.choix=1 ;
event mouse_leave :

Code : Tout sélectionner

controle.choix=0 ;
Il ne reste plus qu'à faire les autres rooms !

S'il y a des zones d'ombre, ou si vous avez besoin de plus d'explications, hésitez pas. Si vous rencontrez des bugs, hésitez pas non plus ^^ Je me suis basé sur l'un de mes projets qui fonctionnait sous GM7 et la syntaxe semble passer sous 8.1...
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Avatar de l’utilisateur
Alec
King Fossile
Messages : 15772
Inscription : 12 juil. 2004, 18:04
Localisation : nstc-j

excellent Gunny !


Pour un prochain jeu, je m'en servirai !
ImageImageImage
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

J'ai oublié de précisé que toute la partie affichage n'est pas décrite et qu'il y a d'autres manière de faire et que l'on peut optimisé un minimum tout ca...
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
BiB
Jeune Pad-awan
Messages : 51
Inscription : 11 nov. 2011, 10:51
Localisation : desvres

Moi j'ai fait ca avec mon moteur de jeu shoot them up old school, enfin je suis pas un as du codage :)).

Code : Tout sélectionner

draw_set_font(system);
draw_set_color(c_black); 
draw_text(68,192,string("facile"));
draw_text(192,192,string("normal")); 


if(keyboard_check_pressed(vk_left))
{
instance_create(48,192,object51)
position_destroy(176,192)
}         
           
if(keyboard_check_pressed(vk_right))
{
instance_create(176,192,object52)
position_destroy(48,192)
}
et pour la validation du level facile ou normal

Code : Tout sélectionner

globalvar facile,normal;
    
if(instance_position(48,192,object51))
 {
   facile =true
   normal =false
   room_goto_next()
 }
   
if(instance_position(176,192,object52))
 {
  normal =true
  facile = false
  room_goto_next()
 }
A quand des shmup avec des idoles
dodonpachi leaderboard Novice ranking - BiB
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Je te conseille très fortement de lire l'intégralité du sujet pour voir où sont les erreurs de conceptions ;)

Car là, il y a clairement un problème dans la manière d'aborder le fonctionnement de gamemaker et la programmation.

Ta manière de faire fonctionne peut-être, mais c'est loin d'être un fonctionnement naturel, et ca va te causer d'énorme soucis par la suite.
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
BiB
Jeune Pad-awan
Messages : 51
Inscription : 11 nov. 2011, 10:51
Localisation : desvres

Bon je sais a la base je suis pas programmeur d'où ma logique bizarre enfin mon code marche pour juste faire une sélection facile ou normal, peut être un jour je pourrais mieux faire :)) mais bon voila a quoi ressemble mon moteur.

Il y a des bugs le script pour refaire apparaitre le joueur déconne il apparait hors écran par moment.

Sinon il y a encore pas mal de boulot a faire dessus
pour les commandes les flèches pour se déplacé et w pour tiré


http://www.mediafire.com/?z4szx1taspe4ea3
A quand des shmup avec des idoles
dodonpachi leaderboard Novice ranking - BiB
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Ecriture en cours d'un tuto sur les fonctions.
Ca devrait être d'une grande aide pour Alec ;)
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Avatar de l’utilisateur
Alec
King Fossile
Messages : 15772
Inscription : 12 juil. 2004, 18:04
Localisation : nstc-j

Gunny a écrit :Ecriture en cours d'un tuto sur les fonctions.
Ca devrait être d'une grande aide pour Alec ;)

Tout est bienvenu !

Moi c'est surtout un tuto sur les timelines détaillé pas à pas car je m'en sort pas alors que c'est si simple apparement.....
ImageImageImage
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Pour le prochain tuto, je ferai quelque chose à ce sujet ;)
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Avatar de l’utilisateur
Alec
King Fossile
Messages : 15772
Inscription : 12 juil. 2004, 18:04
Localisation : nstc-j

Gunny a écrit :Pour le prochain tuto, je ferai quelque chose à ce sujet ;)

carrément car sur le net en général, les topic à ce sujet commencent par :
- "ahhh c'est dûr les timelines, quelqu'un peut m'aider ?"
et ça finit par :
"bah c'est facile, enfantin même, t'as qu'à te démerder espèce de noobà la mords moi le n_d....

Merci Gunny de m'éclairer dans un futut proche !
ImageImageImage
BiB
Jeune Pad-awan
Messages : 51
Inscription : 11 nov. 2011, 10:51
Localisation : desvres

il y a pas de topic pour mettre nos script
voici un petit script qui évite de faire plein de ligne quand un veut faire un pattern en cercle direction fixe

Code : Tout sélectionner

var rond;
rond=0

 for (rond=0; rond<360; rond+=45) // 45 c'est les angles haut-droite,.....
 {
 shoot=instance_create(x,y,votre_objet)
 with(shoot)motion_set(rond,2) 
 };
 sound_play("votre_son")
 sound_loop=false


A quand des shmup avec des idoles
dodonpachi leaderboard Novice ranking - BiB
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Il y a des trucs qui vont pas avec ton script.

Les raisons qui vont que c'est pas le must sont plutot techniques et de l'ordre de l'optimisation.

Le mot clé "var" sert a délimiter la "portée" de ta variable ( notion de programmation très abstraite ) au script uniquement. Le problème que ca pose, c'est qu'a chaque exécution de ton script, la variable va être créée et ensuite initialisée avec la valeur 0.
Quand le script se termine, la variable est détruite.

Ensuite, dans ta boucle for, tu réinitialise ta variable rond avec 0 ( le premier "argument" d'une boucle for sert a créer un "itérateur", ensuite vient la condition de vérité, et enfin l'action à effectuer sur l'itérateur ).

Je préfère de loin les boucles while aux boucle for, mais ca reste une préférence perso ^^

Ensuite, il manque les points virgules et il y en a un très mal placé.

Ensuite se poser la question... Est-il plus rapide de demander à une boucle de créer des objets et leur attribuer une vitesse avec une fonction accesseur, ou bien de créer des objets avec un comportement déjà défini ?

La, ca va que tu n'as que peu de boulette à faire, mais il faut bien voir que le temps de calcul entre chaque frame est limité et donc moins on fait de calcul, mieux le jeu se comportera et plus on aura de temps pour des calculs importants comme les collisions qui réclament beaucoup de temps de calcul.

Sinon c'est correct et ca fait bien en théorie un cercle de boulette qui va s'étendre. Pour un cercle de boulette de taille fixe dirigé vers le joueur, ce script devra être modifié.
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
BiB
Jeune Pad-awan
Messages : 51
Inscription : 11 nov. 2011, 10:51
Localisation : desvres

donc avec while j'ai testé sa passe aussi mais je suis obligé de créé une variable sinon j'ai un message d'erreur sur cette ligne "with(shoot)motion_set(rond,2)" unknow variable rond

mais dans le principe for et while sont pareil?

Code : Tout sélectionner

var rond;
rond = 0
while(rond<360)
{
shoot=instance_create(x,y,object)
with(shoot)motion_set(rond,2) 
rond+=45
}
A quand des shmup avec des idoles
dodonpachi leaderboard Novice ranking - BiB
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Avec une boucle while, tu es effectivement obligé de créer au préalable une variable comme itérateur.

En principe, une boucle for ou while, sont aussi rapide l'une que l'autre. Dans le cas du gml, ca ne se vérifie pas car c'est du code interprété. Vu qu'il y a moins de lignes à lire avec une boucle for, c'est plus rapide. Mais ca tient de l'optimisation et d'une bonne connaissance du fonctionnement de gamemaker.

Si tu préfères les boucles for, continue ^^
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Bientot fini le tuto sur l'écriture de fonctions, et j'ai entamé le tuto sur les timeline pour alec.

Si la motivation va bien, d'ici une semaine je posterai les deux tutos.
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Avatar de l’utilisateur
Alec
King Fossile
Messages : 15772
Inscription : 12 juil. 2004, 18:04
Localisation : nstc-j

Ben merci d'avance parce que sans ça je me retrouve avec des comportements assez limité niveau de mes boss ....
ImageImageImage
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Créer et utiliser les fonctions

I] Prérequis

Pour créer et utiliser les fonctions, il faut savoir créer un script et utiliser les fonctions intégrée à gamemaker.

II] Utilité des fonctions

Les fonctions, sont des morceaux de codes qui effectuent un travail spécifique dans le but d'être réutilisé dans un maximum de cas sans avoir à tout recoder en « dur » pour chaque objet.
Quand on voit que l'on utilise le même code à quelques variations prêtes, il peut être envisageable et bénéfique de le transformer en fonction. Cela représente une partie pour optimiser le code. Car s'il y a moins de code écris, il y a moins de code exécuté et donc un temps d'exécution plus rapide.
Il est aussi possible de transformer du code que l'on va souvent réutiliser dans d'autres projets de le transformer en fonctions pour gagner du temps d'écriture futur.

III] Créer et utiliser ces propres fonctions

1) Construction d'une fonction
1. Architecture et fonctionnement d'une fonction


Une fonction se compose ainsi :

Code : Tout sélectionner

nom_de_la_fonction ( valeur1 , valeur2 , … , valeur16 )
{
	travail à effectuer  avec les valeurs;
	return résultat ;
}
les éléments que nous voyons ici sont :

a) nom de la fonction
C'est le nom de la fonction. Pas grand chose à ajouter pour le moment.

b) les valeurs entre parenthèse
Ce sont ce qu'on appelle des paramètres. Il peut n'y avoir aucun paramètre ou bien jusqu'à 16. Cela va dépendre de ce que vous voulez que fasse la fonction.
Les paramètres sont noté de la manière suivante :

nom_fonction ( argument0 , argument1 , … , argument9 )

c)le bloc de code entre accolade
C'est ici que nous écrirons le code qui effectuera les actions avec les paramètres que vous avez spécifiez si vous en avez spécifiez.

d)le mot clé return
C'est un mot clé qui permet de renvoyer un résultat. A utiliser quand vous souhaitez récupérer le résultat d'une fonction pour l'utiliser plus tard. Après le mot clé, on peut aussi bien trouver une variable qu'une expression.


2. Plusieurs types de fonctions

Il existe deux grand types de fonctions, les fonctions que je qualifie de « travail » et celles de « ressources ».

Les fonctions de « travail » sont des fonctions qui fournissent un travail sans retourner de valeur à utiliser plus tard. Par exemple, une fonction pour déplacer un objet ne va pas retourner de valeur exploitable. Au mieux, elle dira que l'objet a été déplacé avec succès ou non ( cas de gestion des erreurs ).

Les fonctions de « ressources » quant à elles, manipulent d'autres valeurs pour fournir une valeur exploitable. Par exemple, si nous voulons calculer l'aire d'un disque et utiliser ce résultat pour ensuite dans une autre fonction calculer le volume d'un cylindre basé sur ce disque.

2) Construire ces premières fonctions
1. Construire une fonction en GML


Il faut savoir qu'en GML, tout script est une fonction en soi.
Donc il suffit de créer un script, lui donner un nom, et on peut appeler ce script en tant que fonction comme ceci :

Code : Tout sélectionner

nom_du_script( arguments ) ;
2. Fonction de « travail »

Pour créer notre fonction de travail, on va reprendre l'exemple qui consiste à déplacer un objet.
Prenons le cas où nous voulons que l'objet représentant le joueur ce déplace vers la droite quand il appuie sur la touche flèche droite.
Nous allons la construire de manière à ce qu'il n'y ait pas besoin de paramètres.

Code : Tout sélectionner

function_deplacement_droite()
{
x+=10 ;
}
En gml on aura un script nommé function_deplacement_droite avec uniquement ca :

Code : Tout sélectionner

x+=10;
Rien de plus à faire si ce n'est d'intégrer la fonction dans un script qui vérifiera l'état de la touche pour aller vers la droite ou d'utiliser le drag&drop pour cela.

L'appel à la fonction dans un script:

Code : Tout sélectionner

function_deplacement_droite();
3. Fonction de « ressources »

Pour créer une fonction de « ressources », on va prendre l'exemple d'un RPG où nous voulons faire un jet d'un ou plusieurs dés suivant un nombre de faces variables. Nous voulons aussi pourvoir réutiliser le résultat de cette fonction pour par exemple définir la valeur d'une attaque.

Pour cet exemple, nous voyons qu'il y a 2 paramètres variables. Le nombre de dés, et le nombre de faces.

Cela nous mènes à cette construction :

Code : Tout sélectionner

fonction_jet_de_de ( nombre_des , nombre_faces )
{
}
Il faut maintenant se figurer comment fonctionne un jet de dé dans la vie réelle pour reproduire le plus fidèlement possible dans le jeu.

Pour cela, comment fait-on dans la vie réelle pour calculer le résultat d'un jet de plusieurs dés ?
On prend séparément la valeur d'un dé, et nous l'ajoutons au résultat d'un autre dé, tant que nous avons des dés.

Nous savons aussi qu'un dé prend une valeur minimale de « 1 » et que la valeur maximale est dépendant du nombre de face.

Nous allons donc tirer un nombre entier compris entre 1 et un nombre de face indéfini, puis l'ajouter à un autre tirage jusqu'à ce que nous n'ayons plus de dés.

On voit que l'on a un comportement répété ce qui nous amène à intégrer une boucle.

Code : Tout sélectionner

fonction_jet_de_de ( nombre_des , nombre_faces )
{
	tant que ( nombre dé > 0 )
	{
		tirer un nombre aléatoire entre 1 et nombre_faces ;
		ajouter le résultat du tirage au résultat précédent ;
	}

	return résultat ;
}
en gml cela donne :

Code : Tout sélectionner

resultat=0;
while (argument0 > 1)
{
    jet=round (random_range(1,argument1));
    resultat+=jet;
    argument0 -= 1;
}

return resultat;
Vous voyez des variable que nous n'avons pas encore vues... c'est normal. Les variables argument0 et argument1 sont comme le suggèrent leur nom, les paramètres passés à la fonction.

Le GML contrairement à d'autres langages ne peut pas utiliser directement les variables en paramètres et on doit donc passer par les variables argumentX ( pour ceux qui ont fait du C/C++, comme on ne peut pas créer de prototype, déclaration et définition pour une fonction, cela nous oblige soit à réaffecter les paramètres argumentX à l'intérieur de la fonction, soit à les utiliser directement ).

Il est possible de faire quelque chose de plus propre, mais ca consommera plus de lignes. Là, à part utiliser une boucle for, on peut difficilement faire plus petit.

Nous sommes obligés de mettre un resultat=0 sinon gamemaker conserve la valeur de la variable entre chaque utilisation de la fonction.

L'appelle à la fonction se fera comme suit :

Code : Tout sélectionner

test=jet_de_des( nombre_des , nombre_faces );
Les variables nombre_des et nombre_faces seront initialisée au préalable.
La variable test sert à récupérer la valeur calculée par la fonction.
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Avatar de l’utilisateur
Alec
King Fossile
Messages : 15772
Inscription : 12 juil. 2004, 18:04
Localisation : nstc-j

je commence à me servir des fonctions, ça commence à rentrer ^^
ImageImageImage
tendinite du pad
No-bullet mode
Messages : 22
Inscription : 21 avr. 2010, 18:05
Localisation : CAEN 14

merci pour ces tutos gunny,
étant moi aussi en train de bosser sur un shmup sous GM, ton topic est d'une grande aide.
j'attend aussi avec impatience le chapitre sur les timelines, car je suis en plein dedans en ce moment :))
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Je ne sais pas si c'est claire sur le tuto des fonctions, mais j'ai adopté une écriture type "langage C".

Histoire que ceux qui veulent faire une transition vers le c/c++ puissent se baser sur leurs travaux précédent avec gamemaker qui a une syntaxe et une partie de ces concepts tirés très fortement du C++.

Il y a des variations fondamentales comme le fait que l'on gère très difficilement la mémoire. Il faut comprendre les mécanismes de gamemaker pour savoir où et comment on peut en gagner.

J'ai fait exprès de faire deux fonctions totalement différente dans l'approche et le but.

Je n'ai pas abordé un type de fonction que l'on appelle récursive. La théorie, c'est en fait une fonction qui s'appelle elle-meme ( en gros, elle prend son propre résultat pour calculer le prochain résultat )... Ca peut très vite devenir dangereux en créant une boucle infini ( très difficile a discerner ) d'appels de la fonction sur elle-meme. Comme une boucle en fait... Il existe très peut de cas où les fonctions récursives sont le moyen le plus efficace d'obtenir un résultat à la place d'une boucle normale. Donc je n'en ai pas parlé et présenté à la place, la boucle de tirage de dés ^^
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Il me reste un chapitre à écrire sur les timeline, mais j'ai peur que certains en attendaient beaucoup de cette fonctionnalité finalement assez limitée et il faut bien réfléchir pour contourner les limitations de manière efficace...

En sachant qu'il y a moyen de faire pareil à la main sans ajouter une surcouche "inutile" ( ca reste mon point de vue cela dit... )
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Kidd
Insert Coin
Messages : 8
Inscription : 11 févr. 2012, 19:19

Bonsoir,

Merci pour les tutos, ça m'a bcp aidé, je commence à y voir plus clair en gml.

Je me demandais si il était possible de faire 2 types de tir avec une même touche. Si on tapote sur la touche > tir normal et si on laisse appuyé > laser.
J'ai essayé avec keyboard_check_pressed pour le tir normal et keyboard_check pour le laser. Quand je tapote la touche ça marche pour le tir normal mais le laser ce déclenche toute les secondes puisque j'ai réglé le timer à 30. Est-ce qu'il y a un moyen de donner l'ordre de ne pas tirer le laser quand la touche est tapotée?
Gunny
Empereur Bydo
Messages : 3404
Inscription : 15 mai 2006, 15:26
Localisation : Rayon chaussettes du Kiabi du coin
Contact :

Ton code ne fonctionne pas comme tu le souhaite car tu as mal identifié le problème.

J'ai été confronté au même problème pour l'un de mes projets ;)

La fonctionnalité que l'on souhaite :

1) Quand le joueur appuie sur la touche A (admettons la touche A ) le vaisseau tir
2) Quand le joueur maintient la touche A pendant un certain temps, le tir passe en mode tir chargé.

Analysons plus en détail le deuxième point...

Les points importants sont :

a) Trouver un moyen de savoir au bout de combien de temps la touche est appuyée
b) C'est SEULEMENT après une période de temps que le tir passe en mode chargé

On voit donc que l'on a besoin de ce que l'on appelle un timer. Une sorte de chronomètre.
C'est uniquement dans le cas où la touche est maintenue depuis un instant 0 jusqu'à un instant X que la fonction se déclenche.

De plus, on distingue deux mode de tir. Il faut donc trouver un moyen de différencier ces deux mode de tir.

Si tu n'arrive pas à résoudre le problème, je te ferai un petit script démonstratif.
Pour le moment, il vaut mieux que tu te casses les dents et que tu comprennes par toi-même qu'il manque des étapes dans ton raisonnement.

Une grande majorité des problèmes rencontrés viennent d'un manque d'analyse du problème ainsi qu'une conception pas assez poussée. ( et j'y suis encore confronté même si de moins en moins, on développe au fur et à mesure la logique de développement )
Si t'as un truc électronique cassé, ça se passe par là https://www.atelier-electrodd.fr/

-Je comprend rien à ce que tu dis...
-Pas grave... C'est pas en vivant plus longtemps qu'on deviens moins con.
Kidd
Insert Coin
Messages : 8
Inscription : 11 févr. 2012, 19:19

Merci pour ta réponse!

Avec ton explication est pas mal (bcp) de réflexion j'ai réussi à taper un code qui fonctionne apparemment :)) .

Code : Tout sélectionner

shoot_on = keyboard_check_pressed (vk_space);
laser_check = keyboard_check (vk_space);
laser_off = keyboard_check_released (vk_space);

//Tirs
if (shoot_on == 1)
    {
    script_shoot_player(obj_shootup, 15, 3, 5);
    }
    
if (laser_check == 1)
{
timer+=1;
    
    if (timer > 30)
    {
    instance_create(x, y-40, obj_shootpup)
    }
}

if (laser_off == 1)
    {
    timer=0;
    }
Le script_shoot_player c'est pour le tir normal avec power up, je peux régler le rayon de tir, le nbre de bullets et la vitesse.
Répondre