[RPG-MAKER.FR] Oniromancie: tout l'univers de RPG Maker en français - Tutoriels - Zones de combat


Découvrir
RPG Maker

RM 95
RM 2000/2003
RM XP
RM VX/VX Ace

Apprendre
RPG Maker

Guides
Tutoriels
Astuces
Making-of


Comment ça marche?

Aëdemphia
Par Sylvanor

Fighting Robots Quest
Par Boulon

Geex
Par roys

Inexistence
Par Falco

La Légende d'Ibabou
Par Zaitan

Nylu
Par NanakyTim

Sarcia
Par Kaëlar

Super Mario RPG - Lost Souls
Par Omegabowser

Jeux: Inexistence / Tutos: Faire de la neige facilement en (...) / Jeux: ARCH ULTRA / Sorties: ARCH ULTRA / News: Alex d'Or 2019 : Les Vainqueurs ! /

Chat  

Bienvenue
visiteur !




publicité RPG Maker!

Statistiques

Liste des
membres


Contact

Mentions légales

155 connectés actuellement

10288498 visiteurs
depuis l'ouverture

92 visiteurs
aujourd'hui



Barre de séparation

Partenaires






TOP
GAMEMAKING


Les 5 plus
visités

Akademiya RPG Maker

Alex d'Or

BloGecko

ConsoleFun

Eclipso

Au hasard

Leo-Games

Kingdom Ultimate

Tashiroworld

Les deux derniers

Zarok

Akademiya RPG Maker

Nos autres partenaires

Devenir
partenaire


Barre de séparation

Un site du réseau
War Paradise

Annuaires référenceurs




Zones de combat
Ecrit par Lufia

Zones de combat en Ruby



Ceci est un tutoriel pour vous apprendre comment coder vos zones de combat en Ruby sous RMXP, pas un script prêt à être copié-collé. La théorie est exactement la même que celle expliquée dans cet excellent tuto de Joke que je vais vous demander d'aller lire.

...

Vous l'avez compris et assimilé ? Bien, nous allons pouvoir ajouter une couche de Ruby par dessus tout ça !


I. Comment ça marche, une liste de monstres ?

Ouvrez votre éditeur de script et allez farfouiller dans Game_Map. A la ligne 177 se trouve le code suivant :



Portion de code:





def encounter_list

return @map.encounter_list
end


Quoi qu'ça fait ? Lisons ensemble.

def encounter list : Définition d'une fonction nommée "encounter_list". Notez comme le nom est prometteur pour ce qui nous intéresse...

return : Renvoie la valeur contenue dans ce qui suit.

@map.encounter_list : Ce qui suit. Tire la langue Il s'agit de la liste des monstres contenue dans les propriétés de la carte (si, si, vous savez, dans l'éditeur...). Cette variable (car c'est une variable) est un tableau contenant toutes les ids des groupes de monstres "rencontrables" sur une carte, sous la forme [x, y, z].

end : Fin de la définition de notre fonction (car même les meilleures choses ont une fin...)

Vous l'aurez compris, tout ce que fait le programme par défaut pour définir la liste des monstres présents sur une carte, c'est d'aller chercher la-dite liste dans les propriétés de la carte. Et ça, ça ne nous plait pas. Eh bien ! Qu'attendons-nous pour changer les choses ?


II. Nos premières zones

1) Zones définies par deux points

Si le titre ne vous dit rien, retournez lire le tutoriel de Joke sur les zones par variables.

Vous vous souvenez de ce code pour savoir si le joueur est dans une zone ou pas ?
modifier variable : "X héros" rendre égal à coordonnée X du héros
modifier variable : "Y héros" rendre égal à coordonnée Y du héros
condition : si "X héros" supérieur ou égal à "56"
--condition : si "X héros" inférieur ou égal à "88"
----condition : si "Y héros supérieur ou égal à "40"
------condition : si "Y héros inférieur ou égal à "77"
[...]


Nous allons le traduire en Ruby. ^^


If et coordonnées du joueur

Voici la première condition :



Portion de code:





# condition : si "X héros" supérieur ou égal à "56"

if $game_player.x >= 56


Lisez "Si la valeur de $game_player.x est supérieure ou égale à 56". Et la valeur de $game_player.x est tout simplement la valeur de la coordonnée en x (comptée en carreaux) de $game_player, le joueur. De la même façon, la coordonnée en y du joueur sera désignée par $game_player.y

Facile, non ?


Avec plusieurs conditions

C'est pas tout ça, mais nous, on voudrait bien les quatre conditions simultanées... Et c'est pour ça qu'on est bien contents que les opérateurs logiques marchent en Ruby. Si vous voulez une codition de la forme "Si ça et ça", ça s'écrit "if ça and ça".

Pouvez-vous écrire les quatre conditions simultanées sans regarder ce qui suit ?



Portion de code:





if $game_player.x >= 56 and

$game_player.x <= 88 and
$game_player.y >= 40 and
$game_player.y <= 77


Alors, ça ressemble à ce que vous aviez fait ?

NB : En général, en Ruby, un saut de ligne représente une fin d'instruction, ma condition devrait donc se finir à la fin de ma première ligne de code. Cependant, comme la ligne se finit par l'opérateur "and" qui appelle nécessairement une suite, le programme comprend que ma condition se poursuit sur la ligne suivante et ne s'arrête qu'a la première ligne qui n'appelle pas de suite, ici la dernière ligne de mon code. C'est important de ne pas sauter des lignes n'importe comment, ça conduit à des erreurs de syntaxe.

Au fait, faudrait pas un peu changer notre liste de monstres, aussi ?


Si la condition est remplie...

Le conditionnement est fait, faudrait peut-être faire quelque chose quand notre condition est remplie, non ? Examinons le code à écrire...



Portion de code:





if $game_player.x >= 56 and

$game_player.x <= 88 and
$game_player.y >= 40 and
$game_player.y <= 77
return [7, 8]
end


Le code est tout simplement calqué sur la fonction originale de Game_Map. Si nos quatre conditions sont remplies, alors on renvoie [7, 8], les groupes de monstres aux ids 7 et 8 sont maintenant ceux rencontrés dans la zone.

Le "end" est important car il indique au programme de n'effectuer que les actions situées avant celui-ci quand les conditions sont remplies, et pas le reste du programme. De toute façon, si vous l'oubliez, vous aurez une erreur de syntaxe lors de l'exécution. ^^'


Le beau code complet



Portion de code:





def encounter_list

if $game_map.map_id == 1 and
$game_player.x >= 56 and
$game_player.x <= 88 and
$game_player.y >= 40 and
$game_player.y <= 77
return [7, 8]
else
return @map.encounter_list
end #du if
end #du def


Quelques petites choses ont été rajoutées :

$game_map.map_id == 1 : Le signe "==" sert à vérifier une égalité et $game_map.map_id désigne tout simplement l'id d'une carte. Si vous ne le précisez pas, votre zone sera créée sur toutes les cartes du jeu ! Cette condition existait de façon implicite dans la programmation en évènement, puisque les évènements sont propres à une carte.

else : "sinon". Ben oui, faut bien dire à la bestiole ce qu'elle doit faire si on n'y est pas, dans la zone créée... Sinon vous aurez un beau bug dès que vous en sortirez. J'ai remis la définition par défaut de la liste de monstres dans ce "else", mais si un coup de folie vous prend, libre à vous de changer cela.

Une traduction "littérale" du code, pour être sûre que même les dissipés du fond suivent :
<>définir la fonction "encounter_list"
<><>si l'id de la carte est 1
<><>et que la coordonnée x du joueur est supérieure ou égale à 56
<><>et que la coordonnée x du joueur est inférieure ou égale à 88
<><>et que la coordonnée y du joueur est supérieure ou égale à 40
<><>et que la coordonnée y du joueur est inférieure ou égale à 77
<><><> alors on rencontre les groupes de monsstres aux ids 7 et 8
<><>sinon
<><><>on rencontre la liste spécifiée dans les propriétés de la carte
<><>fin
<>fin



2) Zones définies par un point et une distance

Maintenant que vous avez assimilé les bases (*ahem* ...), je vais pouvoir aller un peu plus vite.

Reprenons le code de Joke dans la section correspondante :
<>modif variable "X diff" = coord "X perso 2"
<>modif variable "Y diff" = coord "Y perso 2"
<>modif variable "X diff" - (soustraire) coord X "perso 1"
<>modif variable "Y diff" - (soustraire) coord Y "perso 1"
condition : si "X diff" >= -3
--condition : si "X diff" <= 3
----condition : si "Y diff" >= -3
------condition : si "Y diff" <= 3
[...]


Et sa traduction (l'explication suit, pas d'inquiétude) :



Portion de code:





if $game_map.map_id == 1 and

$game_player.x - $game_map.events[1].x >= -3 and
$game_player.x - $game_map.events[1].x <= 3 and
$game_player.y - $game_map.events[1].y >= -3 and
$game_player.y - $game_map.events[1].y <= 3
return [3, 4]
end


Utiliser une variable "différence" ? Pah, on fait les calculs directement, nous. Clin d'oeil Ca ressemble furieusement à notre code d'avant, avec toutefois l'apparition d'une nouvelle variable.

$game_map.events[1] : L'évènement avec l'id 1. Tous les évènements du jeu avec l'id 1. Vous comprenez l'importance de la condition sur l'id de la carte... Et nous utilisons ses coordonnées x et y comme nous utilisons celles de $game_player.

N.B. : Contrairement au tuto de Joke, nous travaillons bien ici avec des coordonnées absolues et non pas avec des coordonnées écran.

Voilà notre nouveau "code complet" qui crée une zone de 3 carreaux de large autour de l'évènement avec l'id 1 :



Portion de code:





def encounter_list

if $game_map.map_id == 1 and
$game_player.x - $game_map.events[1].x >= -3 and
$game_player.x - $game_map.events[1].x <= 3 and
$game_player.y - $game_map.events[1].y >= -3 and
$game_player.y - $game_map.events[1].y <= 3
return [3, 4]
else
return @map.encounter_list
end #du if
end #du def


Rien de nouveau sous le soleil, mais traduisons quand même :
<>définir la fonction "encounter_list"
<><>si l'id de la carte est 1
<><>et que (joueur.x - évènement 1.x) est supérieur ou égal à -3
<><>et que (joueur.x - évènement 1.x) est inférieur ou égal à 3
<><>et que (joueur.y - évènement 1.y) est supérieur ou égal à -3
<><>et que (joueur.y - évènement 1.y) est inférieur ou égal à 3
<><><> alors on rencontre les groupes de monsstres aux ids 3 et 4
<><>sinon
<><><>on rencontre la liste spécifiée dans les propriétés de la carte
<><>fin
<>fin


3) Les deux en même temps !

Une seule zone par jeu, ça craint un peu... La clé pour réunir nos deux zones précedentes ? Le elsif !

La démonstration en image :



Portion de code:





def encounter_list

if $game_map.map_id == 1 and
$game_player.x >= 56 and
$game_player.x <= 88 and
$game_player.y >= 40 and
$game_player.y <= 77
return [7, 8]
elsif $game_map.map_id == 1 and
$game_player.x - $game_map.events[1].x >= -3 and
$game_player.x - $game_map.events[1].x <= 3 and
$game_player.y - $game_map.events[1].y >= -3 and
$game_player.y - $game_map.events[1].y <= 3
return [3, 4]
else
return @map.encounter_list
end #du if
end #du def


Vous avez maintenant sur votre carte 1 deux zones : une zone rectangulaire définie par deux points dans laquelle on rencontre les groupes 7 et 8 et une zone de 3 carreaux de large autour de l'évènement 1 dans laquelle on rencontre les groupes 3 et 4.

Attention ! Le programme vérifie d'abord le premier jeu de conditions, si elles ne sont pas remplies, celles du 1e elsif, si celles-ci ne sont pas remplies non plus, celles du 2nd elsif, etc. L'ordre dans lequel vous écrivez votre échelle de elsif définit donc la priorité des conditions les unes par rapport aux autres. Si je suis dans les deux zones à la fois, je rencontrerai les monstres 7 et 8, ceux qui correspondent au premier jeu de conditions à être rempli.

Si ce n'est pas très clair, je vous invite à tester vous-même.

Vous pouvez ajouter autant de elsif que vous voulez.


III. Variantes

1) Sur les coordonnées

Il y a en Ruby deux autres manières de désigner les coordonnées des objets.

$game_player.screen_x
C'est ce qui est appelé la "coordonnée écran" en évènements et qui désigne la coordonnée x du joueur par rapport au bord de l'écran. Cette coordonnée est au pixel près.
De la mêmz manière, il existe
$game_player.screen_y
$game_map.events[1].screen_x
$game_map.events[1].screen_y

$game_player.real_x
La coordonnée absolue du joueur... au quart de pixel près ! Comme $game_player.x mais 128 fois plus précis.
Bien sûr, on peut écrire :
$game_player.real_y
$game_map.events[1].real_x
$game_map.events[1].real_y


2) Sur les conditions

Pourquoi se limiter à de bêtes zones ? Lâchez vous ! Quelques exemples de conditions que vous pourrez réutiliser ailleurs :

if $game_party.item_number(1) > 0
Si l'équipe a au moins un exemplaire de l'objet avec l'id 1

if $game_party.actors[0] == $game_actors[1]
Si le premier membre de l'équipe est le héros avec l'id 1

$game_actors[1].weapon_id == 1
Si le héros avec l'id 1 est équipé de l'arme 1

$game_party.actors.include?($game_actors[1])
Si le héros avec l'id 1 est dans l'équipe

if $game_variables[1] == 1
Si la variable 1 est égale à 1

if $game_switches[1] == true
Si l'interrupteur 1 est sur ON

Enfin bref, toutes les conditions disponibles en évènements, plus toutes celles qui vous passent par la tête.


3) Sur la forme des zones

Vous décidez des conditions à remplir, vous décidez de la forme de vos zones ! Utilisez des "and" et des "or" pour faire quelque chose de bien.

Dans les choses qui marchent, j'avais fait ça :



Portion de code:





if game_map.map_id == 1 and

($game_player.x - 12)*($game_player.x - 12) +
($game_player.y - 12)*($game_player.x - 12) < 9
return [4, 5]
end


C'est l'équation d'un disque. ^^ (Il n'était pas très rond, il faudrait essayer avec des coordonnées au pixel... Mais pas de message d'erreur, donc ça marchait !)


4) Et si on veut changer la fréquence des rencontres ?

Devinez quoi ? Juste en dessous de notre terrain de jeu sur Game_Map figure la fonction suivante :



Portion de code:





def encounter_step

return @map.encounter_step
end


Ca ressemble à ce qu'on sait déjà modifier, non ? Ben oui, ça marche exactement pareil, sauf que ce n'est plus une liste mais un nombre seul qui doit figurer après return.



Portion de code:





def encounter_step

return 10
end


Je vous laisse vous amuser pour mettre des conditions.


IV. Le mot de la fin

Ce tutoriel m'a permis de vous montrer par l'exemple quelques trucs faisables en Ruby, et de vous expliquer quelques fonctions et variables présentes de base. Je vous encourage à vous plonger dans l'éditeur de script et à essayer de comprendre comment ça marche par vous-mêmes. Il faut juste de la logique, des bases d'anglais et un peu de rigueur. ^^

Merci de votre attention.


d arkangel - posté le 20/05/2009 à 22:31:58 (322 messages postés)

❤ 0

bidouilleur professionnel

Excellent tuto, très instructif et bien expliqué en plus.

Par contre ça doit être chaud de créer des zones sur des dizaines de map différentes...

La théorie, c'est quand on comprend tout mais que rien ne marche. La pratique, c'est quand ça marche mais personne ne sait pourquoi. Ici, on fait les deux : rien ne marche et personne ne sait pourquoi !


Lufia - posté le 20/05/2009 à 22:52:15 (5792 messages postés)

❤ 0

Un Oniromancien. PVs 1, Attaque 0, Défense 0.

J'ai foiré la fermeture d'une $@#* de balise couleur. image

C'est chaud d'en faire beaucoup, oui et non. C'est toujours le même principe, si tu sais en faire une, tu sais en faire 2573. Faut juste un peu d'organisation.

Une signature ? Pour quoi faire ?


Alemphkujo - posté le 06/07/2009 à 12:43:59 (21 messages postés)

❤ 0

Un cartomancien, c'est pas un vieux qui joue aux cartes, OK ?

Voilà un bon tuto ^^ explications claires et nettes (même si je l'ai brièvement parcouru par manque de temps). Bravo :)

Si vous piquez son coeur au trèfle, tenez vous à carreaux !


Zealous - posté le 28/12/2009 à 14:51:10 (39 messages postés)

❤ 0

Artisan Scripteur

Yop
Je me permets de réagir sur ce tutorial qui m'a d'ailleurs aidé un peu à capter ces @#*#!$ de variables Ruby.
Dans l'ensemble c'est une bonne méthode, mais pour les projets de grand envergure avec des maps de 50 voir 60 microzones, voir même plusieurs map de plusieurs microzones, ça ne devient pas un peu usine à gaz dans la classe Game_Map ?

Ne serait ce pas plus simple (même si on se retrouve submergé d'events) d'entourer de doubles couches nos zones d'events où l'on veut trouver des créatures différentes, en appelant juste une fonction de script dynamique ? :-/

Suite à de nombreux abus, le post en invités a été désactivé. Veuillez vous inscrire si vous souhaitez participer à la conversation.

Haut de page

Merci de ne pas reproduire le contenu de ce site sans autorisation.
Contacter l'équipe - Mentions légales

Plan du site:

Communauté: Accueil | News | Forum | Flash-news | Sorties | Chat | Commentaires | Galerie | Blogs | Articles perso | Screen de la semaine | Palmarès | Livre d'or | Recherche | Interviews | OST | L'Annuaire | Divers
Apprendre: Le Wiki | Tutoriels | Guides | Gaming-Live | Tests | Making-of
Télécharger: Programmes | Scripts | Packs de ressources | Midis | Eléments séparés | Sprites
Jeux: Index jeux séparés | Top Classiques | Top Originaux | Les autres | Collection Oniro | RPG Maker 95 | RPG Maker 2000 | RPG Maker 2003 | RPG Maker XP | RPG Maker VX | RPG Maker VX Ace | RPG Maker MV | Autres | Jeux complets | Proposer
Hébergés: Aëdemphia | Fighting Robots Quest | Geex | Inexistence | La Légende d'Ibabou | Nylu | Sarcia | Super Mario RPG - Lost Souls
Ressources RPG Maker 2000/2003: Chipsets | Charsets | Panoramas | Backdrops | Facesets | Battle anims | Battle charsets | Monstres | Systems | Templates
Ressources RPG Maker XP: Tilesets | Autotiles | Characters | Battlers | Window skins | Icônes | Transitions | Fogs | Templates
Ressources RPG Maker VX: Tilesets | Charsets | Facesets | Systèmes
Ressources RPG Maker MV: Tilesets | Characters | Faces | Systèmes | Title | Battlebacks | Animations | SV/Ennemis