endless game - scene aleatoire

Bonjour, comment faire pour faire apparaître des scènes aléatoires pour réaliser un endless-game ?
j’arrive a faire de l’aléatoire pur et dur en mettant comme nom de scène des numéro puis en mettant Random dans aller a la scène .
Les problèmes que j’ai sont les suivants:
A- Comment faire pour pas que une scène apparaissent 2 fois de suite.
par exemple je veut pas avoir scène 1 puis scène 1.
disons que j’ai les scènes : 1,2,3,4 je ne veux jamais qu’une scène revient 2 fois de suite.
B- Disons que je possède un grand nombre de scène avec une grande variété et que je possède une scène principale 0.
voici le schéma que je veut à l’infini : 0(xxx)0[xxx]0(xxx)0[xxx]0. . .
les x représente une scène au hasard, je veut pas que la partie entre parenthèse et crochet se ressemble.
Cela signifie que si je prend la partie (xxx) [xxx] qui se suit je ne dois pas avoir de doublons.

Merci d’avance.

C’est un peu compliqué à expliquer comme ça suivant ta connaissance de Gdevelop, mais en gros il faut savoir à quoi servent les types de variables : notamment les variables globales, qui te permettront de stocker des valeurs d’une scene à l’autre.

En gros tu fais une scene, tu remplis un certains nombres de conditions pour ton niveau, qui une fois réunie vont changer de scene (pour pointer sur la même). Les variables globales te permettront de stocker un certain nombre de valeurs qui elles te permettront par exemple de définir le niveau effectué, si telle “type” de scene a déjà été faite, etc…

Voilà dans les grandes lignes, apres pour te donner des conseils j’ai besoin de savoir l’état de tes connaissances informatiques… L’idée étant qu’en gros on peut utilsier des variables globales de types scene/structure pour définir des “classes” de niveaux. Imagine un tableau excel (à la manière d’une base de données relationnelle) avec les entetes : id, type de niveau(arriere plan), difficulté(variables d’ajustement en fonction du nombre de scene jouée),etc.

Apres toute la difficulté réside dans les liens que tu fais car ça va t’obliger à faire correpsondre des valeurs pour définir des conditions, générer la scene, liée les classes entre elles, etc.

Je bosse depuis décembre sur un gros projet qui fonctionne exactement sur ce principe, ou des j’ai définis des classes d’objets dans des variables structures de la scene, et je génère ma scene en fonction de valeur de variables globales. Pour moi y’a 2 notions : un coté modele logique et conceptuel (comme sur une base de données), et la notion de programmation objet où tous les objets sont instanciés.

Merci kink pour tes explications, même si je n’ai pas tous saisis.Sinon je suis étudiant en licence d’informatique (L2) donc j’ai déjà vu de la programmation et j’ai fait des base de données cette année même ^^.

Mes questions :

une variable globale = une valeur ? tu est d’accord ?

Sinon je n’ai pas compris quand tu parle de type de scène. Il y a différent types de scènes ? tu peut expliquer la notion de “type” stp.
Par contre, les structures je c’est ce que c’est en programmation C par exemple mais dans GDevelop je n’ai pas saisi a quoi correspond ces derniers. Quand je clique sur structure, il y a juste écrit “Existence d’un enfant”, je n’ai pas compris.

Donc en faite il faut utiliser les variables globales c’est ça ? jusque là je l’ai jamais utiliser pour le passage d’une scène a l’autre mais plutôt pour la vie du personnage par exemple ou le temps. Je vais dabord essayer de faire ce que j’ai dit en A- et je te le montre puis je passerai au B- qui est plus dur .
Bon merci encore :slight_smile:
Cordialement.

Une variable globale = une valeur

A moins d’en faire une variable structure auquel cas tu fais ce que tu veux :

ma_var_globale.enfant1.ma_valeur1
ma_var_globale.enfant1.ma_valeur2
ma_var_globale.enfant1.ma_valeurn
ma_var_globale.enfant2.ma_valeur1
ma_var_globale.enfant2.ma_valeur2
ma_var_globale.enfant2.ma_valeurn
ma_var_globale.enfantn.ma_valeurn

Regarde ce que ça donne en faisant un clic droit sur le nom de ton projet, puis modifier les variables globales :

  • Ajoutes une variable nommée “parent”
  • clic droit sur ta variable “parent” => ajouter un enfant

Tu vas comprendre comment ça fonctionne directement dans l’éditeur de variable, après à toi de concevoir ta variable structure comme une table de database.

Au niveau des actions il n’y a que l’action “enlever un enfant”, mais au final on s’en fout, seules servent les actions “modifier la valeur de la variable” dans structure/globale. Pour t’éclairer sur la syntaxe (comment pointer/modifier la valeur d’un enfant), regardes ce poste même si je parle également de concaténation pour généré dynamiquement des enfants, en tant qu’étudiant en L2 info ça devrait pas trop te dérouter : https://forum.gdevelop.io/t/demande-de-tuto-sur-les-variables-structures-dynamiques/10813/1] Sinon le wiki y’a un tres bon exemple : [url]http://wiki.compilgames.net/doku.php/gdevelop/documentation/manual/global_variables

Regardes également à quoi correspondent les variables d’objets et de scenes, mais encore une fois seules les globales font le liens entre 2 scenes.

Non il n’y a qu’un “type” de scene, j’ai fait un abus de langage : j’entendais par “type” finalement une instance de ta scene, exemple tu 4 arrieres plan/décor soit 4 scènes potnetielles (mais en une seule scene réelle), avec chacune un arriere plan différent. tu veux que chacun de tes arrieres plans ne soient vu qu’une seule fois. Dans une variable globale, tu as une variable compteur_scene que tu incremente à chaque nouvelle scene, delà ça te permet de savoir cb de scene le joueur a traversé. l’idée c’est que si compteur_scene = 1 alors on affiche l’arriere plan, si compteur_scene =2 l’arriere plan 2, etc.

N’hésites pas à travailler la logique du truc pur bien comprendre avec de te lancer à développer, c’est préférable pour “se faire les dents” comme j’aime dire.

Essai juste par exemple de faire un bouton qui te relance la scene en incrémentant une var globale compteur_scene à chaque lancement dans un premier temps. De là tu pourras voir comment appréhender tes var structures.

Faudrait commencer par un truc simple.
Si ton jeu a 3 niveaux, tu te crées 3 variables globales : niv1, niv2, niv3.

Ensuite tu as un “pool” de scènes. On va dire le double, soit 6 scènes représentant chacune un niveau.

Au début du jeu, tu tires un aléatoire pour le niveau 1, et tu stockes son identifiant dans niv1. Ensuite, tu tires un autre niveau au pif, et s’il est différent de niv1, tu le colles dans niv2. Idem pour niv3.
Tu obtiens alors niv1 = 2, niv2 = 1, niv3 = 6.

Enfin, pour passer d’une scène à l’autre, tu suis le plan avec tes niv1, niv2, niv3.

Maintenant, pour des raisons de performances, il vaut mieux faire des pools de pools.
A savoir, le niveau 1 sera tiré parmi 3 niveaux possibles propres à lui, le niveau 2 parmi 3 niveaux possibles propres à lui, etc.
Car il y a toujours un risque que l’ordi tire 1 milliard de fois les mêmes numéros, et donc que ton jeu soit coincé pendant des heures à mouliner en attendant un nombre “libre”. Et plus il y a de niveaux, plus ce risque devient commun.

Donc j’ai réussi a créer trois variables globales Niveau1,Niveau2 et Nieveau3 initialisé au début avec un nombre aléatoire entre 1 et 3, et il n’y a pas de doublons. image : randomNiv123.png

mtarzaim tu parle de stocker l’identifiant “Au début du jeu, tu tires un aléatoire pour le niveau 1, et tu stockes son identifiant dans niv1”. J’espère que tu voulait parler de nombre. Donc comme nom de scène j’ai choisi 1,2 et 3, vu que je tire au sort des nombres.

La ou je bloque c pour passer d’une scène à l’autre.(image : problemePassage.png) j’avais réussi le passage d’une scène a l’autre en faisant une boucle d’aléatoire en faisant ceci (allez a la scène “ToString(Random(2)+1)”)pour chaque scène sans me préoccuper qu’une scène apparaisse deux fois d’affilé.
mais ici je ne comprend pas je n’arrive pas a convertir le contenu de la variable globale en texte pour choisir une scène. Et sinon pour les noms de scènes, on est obligé de mettre des nombres vu qu’on fait Random qu’avec des nombres . ^^

D’autre part tu as dis : Enfin, pour passer d’une scène à l’autre, tu suis le plan avec tes niv1, niv2, niv3.
je dois faire dans scène 1 (passer scène 2), scène 2(passer scène 3) et scène 3(passer scène 1)
ou scène 1(passer scène 1), scène 2(passer scène 2) et scène 3(passer scène 3). Les deux possibilités n’ont pas d’influence selon moi, tu en penses quoi ?


ok pour ça.

Fais simple : trois scenes nommées scene1, scene2 et scene3.
Dans chaque scene, il y a un objet texte où est écrit en gros SCENE X. Avec x = 1, 2 ou 3.

Dans chaque page d’évènements de ces 3 scenes, il y a :

// on change de scene au bout de 5 secondes si temps depuis le début de la scène > 5 secondes alors numeroSceneSuivante + 1

ainsi que l’évènement externe GestionDeScene :

// si on passe a la scene suivante, on doit déterminer où aller Si numeroSceneSuivante != numeroSceneCourante alors --- numeroSceneCourante = numeroSceneSuivante --- si numeroSceneCourante == 1 alors // on est dans la 1ere scene, on regarde la valeur dans niveau1 ----- si niveau1 == 1 alors aller a scene1 ----- si niveau1 == 2 alors aller a scene2 ----- si niveau1 == 3 alors aller a scene3 --- si numeroSceneCourante == 2 alors ----- si niveau2 == 1 alors aller a scene1 ----- si niveau2 == 2 alors aller a scene2 ----- si niveau2 == 3 alors aller a scene3 --- si numeroSceneCourante == 3 alors ----- si niveau3 == 1 alors aller a scene1 ----- si niveau3 == 2 alors aller a scene2 ----- si niveau3 == 3 alors aller a scene3

Tu as trois nombres aléatoires qui correspondent à une scene unique.
Ton jeu commence au niveau 1 (scene de la valeur de niveau1), puis passe au niveau 2 (scene de la valeur de niveau2) et enfin au niveau 3 (scene de la valeur de niveau3). C’est ce que j’appelle ton “plan”.
Ce plan est réalisé dans la scene Titre, par le tirage aléatoire qui remplit les variables niveauX au lancement de la scène.
Le jeu commence quand tu cliques sur Commencer, dont l’évènement fait numeroSceneSuivante + 1.
Cela enclenche l’évènement externe GestionDeScene , inclus également dans la scène Titre.

Il te faut donc 1 scène “Titre” et 3 scènes “de jeu”, ainsi qu’un évènement externe GestionDeScenes, présent dans toutes tes scènes.

Les variables SceneCourante et SceneSuivante au début sont initialisés a 0. C’est exact ?

c’est juste la condition pour changer de scène la phrase ci-dessus ?
ma condition est joueur est en collision avec un objet alors numeroSceneSuivante + 1
Pourquoi fait -on numeroSceneSuivante + 1 ?

il y a seulement une itération qui marche pour moi, j’arrive a effectuer 2 passage seulement.(passage de la scène titre a la scène 1 puis scène 1 a la scène 2 puis ça se bloque.(c’est juste un exemple, les scènes sont tirés aléatoirement, en faite j’avais pas tout à fait réussi le tirage lors du premier post mais j’ai corrigé l’erreur et le tirage est fonctionnelle maintenant.
il y aura un problème si numeroSceneSuivante=4.
Que faire ?

L’image ne correspond pas vraiment au problème je pense mais il y a un problème sur l’incrémentation “numeroSceneSuivante + 1” et le fait que la variable globale ne soit pas majoré.


Oui. Elles le sont par défaut au lancement du jeu, à moins que tu aies mis une valeur lors de la création de la variable.

Pour être plus pro, tu pourrais créer un évènement externe que tu appellerais dans chaque scène.

Si Au lancement de la scène et JeuInitialisé == 0 alors SceneCourante = 0 SceneSuivante = 0 JoueurHP = 100 randomDesScenes // l'évènement externe où est généré le random des niveauX etc. Jeuinitialisé = 1 fin si

Comme ça, quelque soit la scène que tu veux tester, tu auras un minimum de variables initialisées comme il faut.
La condition au début te permet d’être sûr que ce ne sera lu qu’une fois par lancement de jeu.
Tu pourras aussi provoquer une réinitilisation, en mettant JeuInitialisé = 0, par exemple après les crédits de fin ou le game over, pour que le joueur recommence une partie sans récupérer ses valeurs de fin de partie.

Oui.
C’est moins chiant que de gérer des collisions, puisque c’est automatique. Idéal pour du test.
Désactive cette ligne quand tu veux tester “pour de vrai” le comportement de la scène.
Tu peux aussi lui rajouter une conditionnelle “si modeDebug==1 alors” et tu changes la valeur de debug depuis un évènement externe “Debug” ou dans la fenêtre de gestion des variables.

Ton jeu a besoin de deux informations : la scène où il se trouve actuellement (numéroSceneCourante) et la scène où tu veux qu’il se rende (numéroScèneSuivante).
En changeant numéroScèneSuivante, tu lui indiques qu’il doit gérer un changement de scène, avec tout le pataquès que cela peut impliquer (transition, sons, contrôles, variables, graphismes, etc.).

Tu auras donc au minimum deux grands évènements dans chaque scène :
numéroScèneSuivante == numéroScèneCourante, où tu gères ce qu’il se passe dans ta scène.
numéroScèneSuivante != numéroScèneCourante, où tu gères ce qu’il se passe quand tu veux changer de scène (game over, retour au titre, écran de sauvegarde, inventaire, carte du monde, niveau suivant, intro, options, etc.).

Pour ce deuxième évènement, il sera dans un évènement externe, je le nomme GestionDeScenes, pour qu’il soit appelable par toutes les scènes.
Il devrait ressembler à un truc comme ça :

si numéroScèneSuivante != numéroScèneCourante alors --- numéroScèneSuivante = numéroScèneCourante // on évite de changer de scène après avoir changé de scène --- si numeroScèneSuivante = 0 alors aller à la scène titre --- si numeroScèneSuivante = 1 alors aller à la scène Niveau1 --- si numeroScèneSuivante = 2 alors aller à la scène Niveau2 --- si numeroScèneSuivante = 3 alors aller à la scène Niveau3 --- si numeroScèneSuivante = 4 alors aller à la scène Niveau4 --- etc. --- si numeroScèneSuivante = 997 alors aller à la scène Intro --- si numeroScèneSuivante = 998 alors aller à la scène Credits --- si numeroScèneSuivante = 999 alors aller à la scène GameOver --- si numeroScèneSuivante = 1000 alors aller à la scène Chargement --- etc. fin si

En réalité, tu auras toute une liste d’évènements externes (gestionJoueur, gestionEnnemi, BandeSon, Interface, etc.), qui agiront en fonction de la valeur de numéroScèneSuivante et de numéroScèneCourante.

Les évènements 1, 2 & 3 devraient être rassemblés en un seul, avec en condition de déclenchement “si niveau1 == 0 alors”. On aurait alors :

si niveau1 == 0 alors random pour niveau1, random pour niveau2, random pour niveau3 -- tant que niveau1 == niveau2 alors random pour niveau2 -- étiquette refaireRandom -- tant que niveau1 == niveau3 alors random pour niveau3 -- tant que niveau2 == niveau3 alors random pour niveau3 -- si niveau3 == niveau1 aller à l'étiquette refaireRandom
Le mieux sera de passer par un tableau, dont on intervertit les éléments une ou deux fois. Mais je ne sais pas si GD gère les tableaux. Il y a une extension je crois, mais je suis pas sûr qu’elle soit encore maintenue …

tab[0] = 1, tab[1] = 2, tab[2] = 3, i=0 tant que i < 3 -- val1 = random(2) -- val2 = random(2) -- temp = tab[val1] -- tab[val1] = tab[val2] -- tab[val2] = temp -- i++ fin tant que niveau1 = tab[0] niveau2 = tab[1] niveau3 = tab[2]

Ajoutes avant 4.1 “si numeroSceneCourante > x alors numeroSceneCourante = 0 et aller à la scène Titre”, où x est le nombre max de niveaux

Salut , aujourd’hui est un grand jour ^^. J’ai réussi mais je suis pas tout a fait satisfait :wink: et j’ai plein de question en suspens :confused: , donc on y va . . . :slight_smile:
D’abord j’ai compris le mécanisme que tu m’a présenter. On tire aléatoirement l’enchaînement des niveaux au début puis le joueur suit cette enchaînement et ainsi de suite on redémarre. Ce qui m’a perturbé c’est le bouclage .

Je suis pas d’accord ici sur la partie souligné on devrait plutôt faire “alors numeroSceneSuivante=0” car on fait l’incrémentation des SceneSuivante et non des SceneCourante.

Sinon dans un jeu le joueur n’a pas forcément envie de revenir a chaque fois sur la scène titre pour rejouer, notre scène titre c’est juste pour débuter le jeu, et ça serait mieux de changer et de mettre le tirage au sort autre part.

Etant donné que le tirage au sort est effectué au début, alors il y a un problème que deux scènes se suivent mais comme nous avons le rebouclage sur la scène titre alors ça ne se voit pas cependant c’est évident par exemple l’enchainement suivant : 1,2,3,titre,3,1,2.

Pour le rebouclage, je propose de mettre une variable booléenne qui indique si c’est le début (on passe par titre )ou si c’est un rebouclage et on tir au sort sans titre pour passez a une scène aléatoire directement.

Et pour évitez que la scène du niveau 3 de l’itération 1 soit la même que la scène de l’itération suivante du niveau 1, en considérant qu’on fait le tirage au sort au niveau 3 lors d’un rebouclage,
on doit faire :
Random variable niveau1
tant que variable niveau1 = variable niveau3
alors Random variable niveau1

Voilà.

Exact, je ne me suis pas relu sur ce passage. Désolé. :stuck_out_tongue:

Mauvaise idée.
Le tirage doit être fait dès le départ, ainsi tu n’auras plus à t’en occuper. Je considère cela comme de l’initialisation.
Tu peux plus tard ajouter son évènement externe ailleurs, mais en règle générale, c’est mieux de réaliser un traitement à un endroit et de ne plus y toucher ensuite. Surtout qu’il est assez lourd, et peut durer des heures si le random tire à chaque cycle une même valeur.

Le rebouclage sur la scène, c’est pour rester simple et vérifier le comportement rapidement.
On teste un algorithme de façon basique, et après on construit quelque chose de plus complexe.

Dans un vrai jeu, tu aurais dans l’ordre des scènes :
Loading // l’écran de chargement où tu fais les initialisations générales et tu prépares le lancement du jeu pour la première fois
Titre // écran titre avec les menus qui vont bien
NiveauX // les niveaux du jeu
Fin // la scène de fin du jeu
Credits // les crédits de jeu, que tu peux appeler depuis l’écran titre ou depuis une option spéciale en cours de jeu
Chargement // charger une sauvegarde depuis le titre ou depuis un niveau
GameOver // gérer le game over, qui renvoie généralement au titre ou à un chargement de sauvegarde
Intro // si tu veux mettre une intro, que tu peux jouer après 20 secondes de titre ou/et en commençant une nouvelle partie

Inutile. Si c’est le début, sa valeur vaut zéro et il faut se rendre sur la scène Titre. Si elle a une autre valeur, il faut se rendre à la scène correspondante, via GestionDeScenes. Le booléen “jeSuisAuDébut” est redondant avec la valeur de numéroSceneCourante.

Après, si tu veux faire un endless sur 3 niveaux, tu peux zapper le repassage à la scène titre. Et là, effectivement, tu devras refaire un tirage après le niveau3. Mais c’est de la bidouille interne.
Dans une partie normale, le joueur commence à l’écran titre, joue au jeu, puis revient à l’écran titre pour quitter ou recommencer à zéro ou charger une vieille sauvegarde. Au bout du compte, on revient toujours à l’écran titre. D’où l’intérêt de l’utiliser comme réinitialisateur général.

Sauf que tu n’as aucune garantie que niveau2 ait une valeur différente.
Ex : 1-2-1-2-1-2-1-2-1-2-1-2-1-2, le 3 ne sort jamais, même s’il y a bien 3 niveaux.

Il faut tirer les niveauX simultanément, pour les comparer les uns aux autres. Sinon une même valeur pourrait être présente dans plusieurs niveauX.
D’où ma proposition de gérer ça via un tableau, dont on intervertit les valeurs au pif, et qu’on distribue ensuite dans l’ordre des niveauX.

Salut, donc je te tiens juste au courant de mon avancement. Donc en effet tu as raison c’est mieux d’avoir une scène d’initialisation. J’ai essayer de mettre l’initialisation a la fin de la scène 3 mais comme tu l’a dit c’est pas top donc j’ai fait autrement. C’et-à-dire vu que je n’avait pas envie de faire apparaître une scène titre a chaque fois, j’ai fait une scène principale scene0 qui apparaîtra a chaque fois que tous les niveaux seront passés et c’est la que l’initialisation sera faite mais le joueur jouera une scène comme les autres :smiley:

Sinon donc pour l’instant j’avais trois scène et que j’avais parfois le plan suivant : 1,2,3,0,1,2,3,0,1,2,3,0,2,1,3 Donc c’est que ce sont les même tirage au sort.Est-ce qu’il y a un moyen pour éviter cela ? Appart ajouter un grand nombre de scène je ne vois pas d’autre moyen pour d’éviter que deux tirages consécutifs soit identique. Avec un grand nombre de scène ça devrait passez je pense, étant donné que le but ici c’est de montrer au joueur la diversité et de mettre une sensation de nouveauté, d’aléatoire même si a un moment on sera limité.

Perso, je vois deux moyens :

  • faire un max de scènes différentes, une dizaine devrait faire illusion
  • Mettre de l’aléatoire dans les scènes elles-mêmes, genre des éléments de décor positionnés différemment, des ennemis différents ou disposés autrement, un swap de couleurs, un npc au lieu d’un boss, etc.

L’idéal étant d’avoir les deux. Comme ça, on est sûr que le joueur ne se prendra jamais la même salle, même si c’est la même à la base.
ex : Binding of Isaac, dungeon of the endless, FTL