Ex-Admin-Script
Age : 42 Inscrit le : 26/05/2008 Messages : 2360
| Sujet: [VX] Minijeu - Cube Rubik (script + events) Mer 9 Déc 2009 - 13:30 | |
| Auteur : MirainoHikari (moi) Version : VX 1.5, Console 2.7 Date : 8 décembre 2009 pour VX Explication du conceptProbablement le jeu le plus connu et le plus arrache cheveux pour les non initiés. Ce script gère un cube Rubik 3x3x3. L'affichage dépendra majoritairement de vos events (car l'affichage doit être fait en event dans cette version pour VX). À ce sujet, il existe deux version, une VX et l'autre console. Pourquoi deux numéros de version... En fait, l'idée m'est venue après avoir corrigé les examens d'étudiants en programmation à l'université. Ceux-ci devait codé une version simplifié de ce truc en C++. J'ai repris l'idée, affecté au concept de Rubik's Cube et l'ai codé en Ruby, sachant bien que cela en intéresserait certainement quelques uns ici pour faire un mini-jeu. La première version n'était pas faite cependant pour VX, mais pour être affiché en console. La version console a été débuggé mainte et mainte fois, ajoutant des fonctionnalité, en retirant d'autre, pour finalement arrivé à cet écart de version. Pour le moment, je ne retourcherai pas au script, mais la version Console 3 (et du coup, VX 2) devrait peut-être pouvoir gérer des cubes de dimension différentes. Évidemment, seul la version VX est présente ici (les fonctions pour la console ne sont pas présente puisqu'elle utilise des méthodes que VX gère plutôt mal) FonctionnementBon. C'est ici que ça se complique. Vous aurez besoin pour cette version du script, de fichiers et d'event. Je vous donnerai un exemple de chacun, n'ayez crainte. Si vous n'êtes pas expert en cube Rubik, je vous suggère fortement de commencer avec les fichiers que j'ai fourni qui mettent en place un cube parfait puis lui affecte un certain nombre de modification. Ainsi, vous serai assurer d'avoir un cube qui peu être réalisable. Il y a également une fonction "save" qui vous permet d'enregistrer un fichier modifier. Si vous ne désirez pas que les modification effectué soit visible, vous pouvez partir d'un fichier enregistrer par cette méthode comme base pour votre jeu. Donc, première étape, copier le script dans une nouvelle page de script avant le main (le Main est la seule vraie restriction. Comme ce script n'utilise aucune classe de VX, son emplacement n'a aucune espèce d'importance, du moment qu'il est avant le script de lancement du jeu). Voici le script: - Code:
-
############################################################# ### Classe RubiX ### ### Auteur : MirainoHikari ### ### Version: 1.5 VX ### ### rpg-maker-vx.bbactif.com ### ############################################################# ### La classe RubiX permet de généré et de gérer un ### ### cube Rubik 3x3x3. Ce script doit être accompagné ### ### d'une série d'event pour l'affichage. Référez-vous ### ### au forum mentionné ci-haut pour les détails. ### #############################################################
############################################################# ## Exemple d'apel ## ############################################################# # $my_cubiX = RubiX.new # # $my_cubiX.read_cube("inputCube.gcx") # # $my_cubiX.read_move("inputMove.gcx") # # $my_cubiX.save_cube("current.gcx") # # $my_cubiX.get_move(['A','1']) # ############################################################# ## Types de mouvements ## ############################################################# # T:Dessus B:Dessous S:Lateral ## # R:Droite L:Gauche C:Centre ## # F:Devant A:Derriere M:Median ## #############################################################
class RubiX ################################################# # void # # initialize (void) # ################################################# # Initialisation du cube. Celui-ci est toujours # # initialiser vierge # ################################################# def initialize @cubiX = [[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]] @moveX = [] end ################################################# # =string # # get_val (ligne, colonne) # ################################################# # Renvoie la valeur se trouvant dans la case # # à l'index ligne colonne spécifié. # ################################################# def get_val(l,c) return @cubiX[l][c].chr.to_s end ################################################# # =bool # # validate (ligne, colonne) # ################################################# # Renvoie vrai si toutes les cases autour de # # l'index ligne colonne spécifié ont la même # # valeur que cette même case. # ################################################# def validate(l,c) val = (@cubiX[l][c].chr.to_s).to_i rtrn = true for i in 0..2 for j in 0..2 tst = (@cubiX[l-1+i][c-1+j].chr.to_s).to_i rtrn = rtrn && (val == tst) end end return rtrn end ################################################# # void # # rotate (ligne) # ################################################# # Utilisé à l'interne. Sert à décaler les blocs # # de la ligne touchant à la face en mouvement. # ################################################# def rotate(line) my_size = line.size-1 for t in 1..3 last = line[my_size] for i in 0..my_size line[my_size-i] = line[my_size-i-1] end line[0]=last end end ################################################# # void # # do_sqr (ligne, colonne) # ################################################# # Utilisé à l'interne. Sert à effectuer la # # rotation de la face (carré) en mouvement. # ################################################# def do_sqr(l,c) for t in 1...3 first = @cubiX[l][c] @cubiX[l+0][c+0] = @cubiX[l+1][c+0] @cubiX[l+1][c+0] = @cubiX[l+2][c+0] @cubiX[l+2][c+0] = @cubiX[l+2][c+1] @cubiX[l+2][c+1] = @cubiX[l+2][c+2] @cubiX[l+2][c+2] = @cubiX[l+1][c+2] @cubiX[l+1][c+2] = @cubiX[l+0][c+2] @cubiX[l+0][c+2] = @cubiX[l+0][c+1] @cubiX[l+0][c+1] = first end end ################################################# # void # # do_move (face) # ################################################# # Utilisé à l'interne. Sert à préparer la ligne # # et le carré qui devront être modifié dans le # # cube pour effectuer le changement. # ################################################# def do_move(face) line = [0,0,0,0,0,0,0,0,0,0,0,0] case (face) when 'T' #face du dessus for i in 0...9 line[i] = @cubiX[3][8-i] end for i in 0...3 line[9+i] = @cubiX[11][3+i] end rotate(line) for i in 0...9 @cubiX[3][8-i]=line[i] end for i in 0...3 @cubiX[11][3+i]=line[9+i] end do_sqr(0,3) return when 'B' #face du dessous for i in 0...9 line[i] = @cubiX[5][i] end for i in 0...3 line[9+i] = @cubiX[9][5-i] end rotate(line) for i in 0...9 @cubiX[5][i]=line[i] end for i in 0...3 @cubiX[9][5-i]=line[9+i] end do_sqr(6,3) return when 'R' #face de droite for i in 0...12 line[i]=@cubiX[11-i][5] end rotate(line) for i in 0...12 @cubiX[11-i][5]=line[i] end do_sqr(3,6) return when 'L' #face de gauche for i in 0...12 line[i]=@cubiX[i][3] end rotate(line) for i in 0...12 @cubiX[i][3]=line[i] end do_sqr(3,0) return when 'F' #face avant line = [@cubiX[2][3],@cubiX[2][4],@cubiX[2][5], @cubiX[3][6],@cubiX[4][6],@cubiX[5][6], @cubiX[6][5],@cubiX[6][4],@cubiX[6][3], @cubiX[5][2],@cubiX[4][2],@cubiX[3][2]] rotate(line) @cubiX[2][3],@cubiX[2][4],@cubiX[2][5], @cubiX[3][6],@cubiX[4][6],@cubiX[5][6], @cubiX[6][5],@cubiX[6][4],@cubiX[6][3], @cubiX[5][2],@cubiX[4][2],@cubiX[3][2] = line do_sqr(3,3) return when 'A' #face arrière line = [@cubiX[8][3],@cubiX[8][4],@cubiX[8][5], @cubiX[5][8],@cubiX[4][8],@cubiX[3][8], @cubiX[0][5],@cubiX[0][4],@cubiX[0][3], @cubiX[3][0],@cubiX[4][0],@cubiX[5][0]] rotate(line) @cubiX[8][3],@cubiX[8][4],@cubiX[8][5], @cubiX[5][8],@cubiX[4][8],@cubiX[3][8], @cubiX[0][5],@cubiX[0][4],@cubiX[0][3], @cubiX[3][0],@cubiX[4][0],@cubiX[5][0] = line do_sqr(9,3) return when 'C' #Centre vertical for i in 0...12 line[i]=@cubiX[i][4] end rotate(line) for i in 0...12 @cubiX[i][4]=line[i] end return when 'S' #Centre latéral for i in 0...9 line[i] = @cubiX[4][i] end for i in 0...3 line[9+i] = @cubiX[10][5-i] end rotate(line) for i in 0...9 @cubiX[4][i]=line[i] end for i in 0...3 @cubiX[10][5-i]=line[9+i] end return when 'M' #Centre median line = [@cubiX[1][3],@cubiX[1][4],@cubiX[1][5], @cubiX[3][7],@cubiX[4][7],@cubiX[5][7], @cubiX[7][5],@cubiX[7][4],@cubiX[7][3], @cubiX[5][1],@cubiX[4][1],@cubiX[3][1]] rotate(line) @cubiX[1][3],@cubiX[1][4],@cubiX[1][5], @cubiX[3][7],@cubiX[4][7],@cubiX[5][7], @cubiX[7][5],@cubiX[7][4],@cubiX[7][3], @cubiX[5][1],@cubiX[4][1],@cubiX[3][1] = line return end end ################################################# # void # # read_move (filename) # ################################################# # Permet de faire la lecture des mouvements # # préenregistrer dans un fichier. Celui-ci lit # # chaque mouvement dans le fichier puis les # # exécute. # ################################################# def read_move(filename) rfile = IO.read(filename) for i in 0..rfile.size/3 @moveX[i] = "#{rfile[i*3].chr}#{rfile[(i*3)+1].chr}" end for i in 0...@moveX.size face = @moveX[i][0].chr.to_s time = (@moveX[i][1].chr.to_s).to_i for m in 0...time do_move(face) end end end
################################################# # void # # get_move (choice) Version VX # ################################################# # choice est un Array 1x2 contenant la face et # # le modificateur. Exemple ["A","2"]. # # Il prend ce qu'un event lui demande de faire # # et l'exécute. # ################################################# def get_move(choice) face = choice[0].to_s time = (choice[1].to_s).to_i for m in 0...time do_move(face) end end
################################################# # void # # read_cube (filename) # ################################################# # Permet de faire la lecture d'un cube Rubik # # préenregistrer dans un fichier. Celui-ci lit # # chaque valeur dans le fichier puis les # # affecte dans le jeu. # ################################################# def read_cube(filename) #1 = Rouge, 2 = Orange, 3 = Jaune, 4 = Vert, 5 = Bleu, 6 = Blanc cfile = IO.read(filename) tmp = cfile.to_a for i in 0...12 for j in 0...9 @cubiX[i][j] = tmp[i][j] end end end ################################################# # void # # save_cube (filename) # ################################################# # Optionnel. Permet de sauvegarder dans un # # fichier le cube résultant. # ################################################# def save_cube(filename) sfile = File.new(filename, "w") for i in 0...@cubiX.size for j in 0...@cubiX[i].size sfile.syswrite(@cubiX[i][j].chr) end sfile.syswrite("\n") end sfile.close end end Ensuite, vous devrez vous créer des fichiers. Pour le moment, ils ne sont pas encodé. Peut-être pour la version VX 2 ou 3. Il ne s'agit que d'un fichier en texte brute. L'extension des fichiers n'a pas d'importance, assurez-vous simplement que lorsque vous les appelez, vous donniez le bon nom de fichier et la bonne extension. Pour correspondre à l'exemple, le fichier du cube devrait s'appeler inputCube.gcx et le fichier de mouvement devrait s'appeler inputMove.gcx. Mais comme je vous dit, le nom et l'extension n'ont pas d'importance du moment que lorsque vous les appèlerai vous donniez les nom de vos fichiers. Voici le contenu du fichier InputCube.gcx du cube "initiale" - Code:
-
000111000 000111000 000111000 444555333 444555333 444555333 000222000 000222000 000222000 000666000 000666000 000666000 Voici un exemple de contenu du fichier InputMove.gcx - Code:
-
S1 C2 M3 A1 T2 L3 B1 R3 F2 Bon maintenant, vous être presque prêt. La partie script et fichier est terminé, il faut maintenant faire les events... Le premier est celui qui créera votre cube dans votre jeu à partir des fichiers. Le voici: - Citation :
- @>Script: $my_cubiX = RubiX.new
: : $my_cubiX.read_cube("inputCube.gcx") @>Wait: 60 frame(s) @>Script: $my_cubiX.read_move("inputMove.gcx") : : $my_cubiX.save_cube("current.gcx") @>Control Self Switch: A =ON @> Le wait et le save sont facultatif. En mettant le wait là, cela permet au joueur de voir qu'il s'agit d'un casse-tête. En partant de l'original, toutes les couleurs seront affiché regroupé, puis après le délais, elles seront mélangées. Si vous ne voulez pas que le joueur vois la version "parfaite", vous avez simplement à enlever le délais. Comme mentionné précédemment, vous n'êtes pas obligé de partir du fichier "parfait". En mettant le save, vous venez de créer un nouveau fichier nommé current.gcx. Ce fichier contient le cube mélangé. Ainsi, si vous désirez partir simplement d'un fichier déjà mélangé, votre event de départ ressemblera plutôt à ceci. - Citation :
- @>Script: $my_cubiX = RubiX.new
: : $my_cubiX.read_cube("current.gcx") @>Control Self Switch: A =ON @> Le SelfSwitch est là simplement pour que le cube ne soit pas recréé et réinitialisé à chaque fois. Si vous voulez permettre à l'utilisateur de recommencer le casse tête, vous n'aurez besoin que de cette commande une fois que le cube à été créé. - Citation :
- @>Script: $my_cubiX.read_cube("current.gcx")
@> où current.gcx est le nom de votre fichier "initiale". Vous ne devez créer qu'une seule fois $my_cubiX. Soit en début de jeu, soit en arrivant dans le mini-jeu. Mais dès que le cube est créé, vous ne devez plus le recréer. Si vous voulez créer plusieurs Rubik, changer le nom de la variable $my_cubiX. Bon, ok, c'est bien beau, mais comment fait-on pour l'afficher... Là, ça, c'est un travail d'event et de minutie. Vous devrez vous créer votre affichage, selon ce que vous désirez come effet visuel. Dans l'exemple que je présente ici, c'est en forme de croix (correspondant à la croix du fichier), mais vous êtes libre d'afficher comme vous le voulez (6 carrées côte à côte, un rectangle 3 faces x 2 faces, En forme de Z) Assurez-vous simplement que le joueur comprendra comment les carrés interagissent entre eux. L'important est de ne pas se mélangé en inscrivant quel carré on affiche. Je vous montre un exemple, et je l'expliquerai ensuite... Il n'y a pas le reste de l'event, mais en fait, ce ne sont que les "Branch End" qui apparaisse, aucun code utile... Cette structure utilise les scriptes comme conditions pour une bonne raison... Ça va vous coupé votre travaille d'un ratio de 1 pour 10. Vous voyez la première ligne de script au sommet de l'event. Et bien, en copiant collant votre event les 72 fois nécessaires, c'est la seule ligne que vous aurez à changer dans vos event. Voyons comment j'ai placer ces events avant de poursuivre les explications: À titre indicatif, le bouton est l'event qui me crée mon cube, les pics sont la sortie qui sera débloquée par la réussite de mon cube et la petite crois est l'indicateur de réussite (nous y reviendront plus tard). Pour le moment, regardons la grande croix. L'event précédent corresponds au premier carré rouge dans l'ordre de lecture. le get_val(0,3) indique la coordonée à regarder pour l'affichage. Selon le chiffre lu, il modifiera la couleur du carré. (N'oubliez pas de le mettre en processus parallèle si vous désirer le changement en temps réel). Pour avoir le decond carré, vous modifier get_val(0,3) pour get_val(0,4). Pour celui en dessous du premier, get_val(1,3). Ainsi de suite... Vous pouvez choisir l'images que vous voulez. J'ai pris les Hexagramme car ils offraient déjà plusieurs couleurs sans me casser la tête. Vous devez prendre les coordonnées correspondant au fichier (et non celle de votre maping). Ainsi, si vous faites une forme en Z, faites attention au fait que vous devrez "tourner" votre carré pour qu'il fasse du sens... Bon, pour les icones de validation... C'est simple... Si vous volez que l'image correspondent à l'image de votre jeu, vous copiez le centre de chaque carré. Puis pour la validation, vous faites ceci (l'exemple qui suit correspond au carré bleu) : Tout ce que vous devez faire, c'est ajouter ce code en prenant la peine de changer les coordonnées de validation. Pour le bleu, le carré central correspondant est le carrée (10,4), donc il faut validé le (10,4). Pour que les pics partent du chemin, je vous laisse vous débrouiller. Il s'agit simplement de vérifier que les 6 validations sont vraies. Je vous laisse également le soin dé modifier l'event pour qu'il correspondent mieux à vos besoins... Dans ce cas, j'ai simplement "activé la lumière" des hexagrammes. À vous de modifier selon vos images (dans ce cas, il se pourrait que le simple fait de faire tourner l'image soit inapproprié ou insuffisant). Ok, on peut afficher, maintenant, pour déplacé. Vous avez remarquer mes events en pourtour du jeu. En fait, les commandes de déplacements sont caché à l'intérieur. On ajoute simplement dans les event le script correspondant au mouvement désiré. Exemple, pour la première ligne de lila/blanc/jaune, on inscrira le script suivant à droite de la ligne - Code:
-
$my_cubiX.get_move(['T','1']) qui effectuera un déplacement de la face supérieur (et du coup de la ligne sélectionnée). Le cube dans le code est géré pour que la face arrière soit ajouté à la rotation, donc ne vous en faites pas, les couleurs suivront correctement. (Vous pouvez tester sans appliqué de modifications (enlever la ligne du read_move à la création) pour voir comment réagissent les couleurs). Ce déplacement décalera la ligne de 3 espaces vers la gauche. Pour décaler vers la droite, la commande sera ['T','3'] (et sera placé à gauche de la ligne). Le script ne supporte pas les nombre négatif. Les déplacements s'effectue toujours dans le sens horraire de la face déplacée. Il faut donc faire attention. Pour la ligne du bas, ['B','3'] sera à droite et ['B','1'] sera à gauche. De toute façon, tester votre jeu et regarder si vous avez fait des erreurs de déplacement. (J'en ai fait car j'avais mal codé la logique au départ, d'où le pourquoi, entre autre, je suis passé de la version 1.0 à 1.5 simplement en testant pour écrire cette publication) Pour les case qui peuvent contrôler 2 direction, j'ai simplement mis une détection du sens du joueur. S'il regarde vers le bas, je faits cette action, si il regarde vers la droite, je fais l'autre action (pour le coin supérieur gauche du carré central) Les différents mouvement possible sont T,B,F,A,R,L,M,C,S. Voyez le commentaires en entête du code pour les détails. Les différentes fonctions sont les suivantes (sont également inclue les fonction console seulement) - Code:
-
void initialize() void show_cube(cube2show) #console seulement char get_val(l,c) bool validate(l,c) void rotate(line) void do_sqr(l,c) void do_move(face) void read_move(filename) void get_move(choice) # spécial VX void get_move # console seulement void read_cube(filename) void save_cube(filename) Si vous avez des questions où que vous trouvez une anomalie dans le déplacement n'hésitez pas à m'en faire part en répondant à ce sujet. |
|