Sujet n°5716
Posté par Brendan75 le 29 Déc - 17:06 (2009)
Titre : Mappemonde
Mappemonde


Non libre


Introduction
La mappemonde pose de nombreux problèmes parmi lesquels sa taille : un carreau d'une carte pokémon mesure 8px de côté, c'est 4 fois
moins qu'un carreau RMXP (32px de côté), en augmentant la taille de la carte à ce point on réduit grandement sa qualité hors en tant que
graphiste la qualité des images c'est un problème important pour moi. Ce script est très simple de par mes capacités limités en script mais
même s'il n'a pas toute les qualités de scripts plus complexes, il présente un avantage conséquent : il est flexible. N'importe qui peut le
régler comme il le souhaite et choisir la taille des carreaux de sa carte.

Mise en place et Utilisation
1. Le Script
Spoiler

Code:

#==============================================================================
# ■ Scene_Carte
# par Brendan 75
# 29/12/09
#-----------------------------------------------------------------------------
# Mappemonde adaptable à n'importe qu'elle région.
#==============================================================================
class Scene_Carte
 
  #--------------------------------------------------------------------------
  # ● Initialize
  #--------------------------------------------------------------------------
  def initialize
   
    # Numéro de la variable des coordonnée du hero en X et en Y
    $var_x = 60
    $var_y = 61
   
    # Nom de l'image de fond (avec l'extension et entre guillement)
    @carte_img = "map.png"
   
    # Nom de l'image du curseur (avec l'extension et entre guillement)
    @curseur_img = "map_curseur.png"
   
    # Nom de l'image réprésentant le personnage (avec l'extension et entre guillement)
    @perso_img = "map_hero.png"
   
    # La map est-elle visible en fond ? (true si oui, false si non)
    @spriteset_visible = true
   
    # Coordonnées X et Y de la carte
    @map_x = 0
    @map_y = 0
   
    # Taille des cases (mettre 32 pour 32x32)
    @cote_case = 8
   
    # Nombre de case à la verticale et à l'horizontale
    @nb_case_v = 40
    @nb_case_h = 60
   
    # Coordonnées X et Y des noms
    @text_x = 0
    @text_y = 0
   
    # Couleur du texte pour les noms (Color.new(Rouge, Vert, Bleu), par défaut blanc)
    @text_color = Color.new(255, 255, 255)
   
    # Taille du texte pour les noms ($fontsize pour la taille par défaut)
    @text_size = $fontsize
   
    # Police du texte pour les noms ($fontface pour la police par défaut, nom entre guillemet)
    @text_police = $fontface
   
    # Idem pour les descriptions.
    @desc_x = 0
    @desc_y = 0
    @desc_color = Color.new(255, 255, 255)
    @desc_size = $fontsize
    @desc_police = $fontface
   
    #--------------------------------------------------------------------------
    # Les zones
    #
    #   -> Nom (entre guillemets)
    #   -> Description
    #   -> Découvert
    #   -> type (0:"normal" 1:"ville")
    #
    #--------------------------------------------------------------------------
     
    if $local == nil
      $local =  []
      for x in 0.. @nb_case_h-1
        $local[x] = []
        for y in 0.. @nb_case_v-1
          $local[x][y] = ["","", false, 0]
        end
      end
    end
   
    # - init(x, y, nom, desc, type) pour initialisé une zone. -
    init(0, 0, "Exemple 1", "Rien qu'un exemple.", 0)
    init(3, 2..4, "Exemple 2", "Rien qu'un exemple...", 0)   
    # ---------------------------------------------------------
   
    note
  end
 
 
  #--------------------------------------------------------------------------
  # ● Main
  #--------------------------------------------------------------------------
  def main
   
    @spriteset = Spriteset_Map.new if @spriteset_visible
   
    @background = Sprite.new
    @map.bitmap = RPG::Cache.picture(@carte_img)
    @background.x = 0
    @background.y = 0
    @background.z = 5
   
    @curseur = Sprite.new
    @curseur.bitmap = RPG::Cache.picture(@curseur_img)
    @curseur.x = @map_x + @cote_case * ($game_variables[$var_x]-1)
    @curseur.y = @map_y + @cote_case * ($game_variables[$var_y]-1)
    @curseur.z = 8
    @index = [$game_variables[$var_x],$game_variables[$var_y]]
   
    @hero = Sprite.new
    @hero.bitmap = RPG::Cache.picture(@perso_img)
    @hero.x = @map_x + @cote_case * ($game_variables[$var_x]-1)
    @hero.y = @map_y + @cote_case * ($game_variables[$var_y]-1)
    @hero.z = 7
   
    @text = Window_Base.new(0 - 16, 0 - 16, 672, 512)
    @text.opacity = 0
    @text.contents = Bitmap.new(672, 512)
    @text.z = 6
   
    refresh
   
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @spriteset.dispose if @spriteset_visible
    @background.dispose
    @curseur.dispose
    @hero.dispose
    @text.dispose
  end
 
  #--------------------------------------------------------------------------
  # ● Update
  #--------------------------------------------------------------------------
  def update
   
    @curseur.x = @map_x + @cote_case * (@index[0]-1)
    @curseur.y = @map_y + @cote_case * (@index[1]-1)
   
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
      return
    end
   
    if Input.trigger?(Input::DOWN)
      if @index[1] != @nb_case_v
        $game_system.se_play($data_system.cursor_se)
        @index[1] += 1
      end
      refresh
      return
    end
     
    if Input.trigger?(Input::UP)
      if @index[1] != 1
        $game_system.se_play($data_system.cursor_se)
        @index[1] -= 1
      end
      refresh
      return
    end
     
    if Input.trigger?(Input::LEFT)
      if @index[0] != 1
        $game_system.se_play($data_system.cursor_se)
        @index[0] -= 1
      end
      refresh
      return
    end
     
    if Input.trigger?(Input::RIGHT)
      if @index[0] != @nb_case_h
        $game_system.se_play($data_system.cursor_se)
        @index[0] += 1
      end
      refresh
      return
    end
  end
 
  #--------------------------------------------------------------------------
  # ● Refresh
  #--------------------------------------------------------------------------
  def refresh
    @text.contents.clear
    string = $local[@index[0]][@index[1]][0]
    desc  =  $local[@index[0]][@index[1]][1]
    @text.contents.font.name = @text_police
    @text.contents.font.size = @text_size
    @text.draw_text(@text_x, @text_y, 247, 16, string, 1, @text_color, 0)
    @text.contents.font.name = @desc_police
    @text.contents.font.size = @desc_size
    @text.draw_text(@desc_x, @desc_y, 247, 16, desc, 1, @desc_color, 0)
  end
 
  #--------------------------------------------------------------------------
  # ● Init(x, y, nom, desc, type)
  #--------------------------------------------------------------------------
  def init(o_x, o_y, nom, desc, o_type)
   
    if o_type.is_a? String
      case o_type
      when "ville"
        type = 1
      else
        type = 0
      end
    else
      type = o_type
    end
     
    if o_x.is_a? Range
      o_x.each {|x|
        if o_y.is_a? Range
          o_y.each {|y| $local[x][y] = [nom,desc, false, type] }
        else
          $local[x][o_y] = [nom,desc, false, type]
        end         
      }
    else
      if o_y.is_a? Range
        o_y.each {|y| $local[o_x][y] = [nom,desc, false, type] }
      else
        $local[o_x][o_y] = [nom,desc, false, type]
      end
     
    end   
  end
 
  #--------------------------------------------------------------------------
  # ● note
  #--------------------------------------------------------------------------
  def note
    logfile = File.open("Data/carte.txt", "w")
    logfile.write("# ---------- Mappemonde ----------\n")
    logfile.write("\n")
    empty = 0
   
    for x in 0..$local.size-1
      for y in 0..$local[x].size-1
        nom = $local[x][y][0]
        if nom.length != 0
          desc = $local[x][y][1]
          type = $local[x][y][3] == 0 ? "normal" : "ville"
          string = x.to_s + '.' + y.to_s + ' -> ' + nom + ' : ' + desc + '('+type+')'
          logfile.write(string)
          logfile.write("\n")
        else
          empty += 1
        end
      end
    end
    logfile.write("\n")
    string = "Et #{empty.to_s} case"+ (empty > 1 ? "s vides." : " vide.")   
    logfile.write(string)
    logfile.close
  end
   
end

#==============================================================================
# ■ Appel depuis la map
#
# Remplacez :
#   -> Y par la touche qui ouvre la carte depuis la carte.
#   -> 200 par le n°de l'interrupteur qui active cette fonction.
#
#==============================================================================
class Scene_Map
 
  alias map_update update
  def update
    if Input.trigger?(Input::Y) and $game_switches[200]
      $scene = Scene_Carte.new
    end
    map_update
  end
end

#==============================================================================
# ■ Interpreter
#
#   Fonctions lié à la carte.
#
#==============================================================================

class Interpreter
 
  #--------------------------------------------------------------------------
  # ● Init_map (facultatif) - Remise à Zéro des infos de la map.
  #--------------------------------------------------------------------------
  def init_map
    Scene_Carte.initialize
  end
 
  #--------------------------------------------------------------------------
  # ● Init_local - Modification des infos sur un lieu (comme les "init" ligne 82)
  #--------------------------------------------------------------------------
  def init_local(x, y, nom, desc, type)
    Scene_Carte.init(x, y, nom, desc, type)
    Scene_Carte.note
  end
 
  #--------------------------------------------------------------------------
  # ● Scene_carte - Appel de la Carte
  #--------------------------------------------------------------------------
  def scene_carte
    $scene = Scene_Carte.new
  end
 
  #--------------------------------------------------------------------------
  # ● Local - Défini la position du héro
  #--------------------------------------------------------------------------
  def local(x_or_name, o_y = nil)
    if $local == nil
      Scene_Carte.initialize
    end
    @data = []
    if y == nil
      @exist = false
      for x in 0..$local.size-1
        for y in 0..$local[x].size-1
          if $local[x][y][0] == x_or_name and !@exist
            @exist == true
            @data = [x, y]
            $local[x][y][2] = true
          end
        end
      end
      print("le lieu : #{x_or_name} n'existe pas.") if !@exist
      @data [1, 1] if !@exist
    else
      @data = [x_or_name, o_y]
      $local[x_or_name][o_y][2] = true
    end
    $game_variables[$var_x] = @data[0]
    $game_variables[$var_y] = @data[1]
  end
 
end


Placez ce script n'importe où, au dessus de "Main". La partie "Initialize"(l14) est à modifier.

2. Les Coordonnées
Les coordonnées de la carte et des textes vous sont demandées. Je rappel au passage que x est horizontal et y vertical, on calcule les coordonnées
en pixel en partant du coin supérieur gauche (coordonnées 0; 0). Pour les coordonnées de la carte, on exclut les bordures et les "décorations" qui
entourent la carte et on ne prend en compte que la carte "praticable" par le curseur. Le texte peut être affiché n'importe où dans la fenêtre.

3. Le Quadrillage
Le principale avantage du script est le choix du quadrillage. Chaque carreau est un carré dont vous choisissez le côté. La taille de l'espace praticable
par le curseur est le nombre de carreau.

4. Les Images
Trois images sont nécessaire pour le script : une carte et deux icônes. La carte est forcément au format 640x480 (la taille de la fenêtre) mais peut
être en parti vide (dans ce cas rendez la map visible en fond). Les deux icônes sont sont des carrés dont le côté vaut trois carreaux de la carte (par
exemple si un carreau vaut 8x8, 8x3=24, l'icône fera 24x24), pensez à centrer l'icône de préférence.

5. Les Textes
Le script permet d'afficher un texte selon la position du curseur (généralement le nom du lieu), la "nomination des cases" est détaillé dans le script.
On peut choisir la couleur, la police et la taille du texte en plus de sont emplacement.

6. En Event
La localisation du héros sur la carte se fait par deux variable à déterminer en début du script, une pour X et une pour Y. Elle peuvent être définit pour
chaque map ou/et gérer comme n'importe qu'elle variable. De plus pour ouvrir la carte, il suffit d'insérer le script "$scene = Scene_Carte.new".

Conclusion
Je suis pas très bon pour les explications donc si vous n'avez pas compris quelque chose n'hésitez pas à demander des informations. Si un scripteur
plus compétent que moi veux améliorer ce script j'en serai ravi.

Posté par Alex le 29 Déc - 18:05 (2009)
Super Tuto, merci à toi Imbécile heureux

Posté par Bilkev le 29 Déc - 18:08 (2009)
Génial ! Mais le cadre il ets avec le script ou on doit le mettre ?
Sinon c'est quoi cette histoire quand tu marque :
Citation:
Trois images sont nécessaire pour le script : une carte et deux icônes. La carte est forcément au format 640x480 (la taille de la fenêtre) mais peut
être en parti vide (dans ce cas rendez la map visible en fond). Les deux icônes sont sont des carrés dont le côté vaut trois carreaux de la carte (par
exemple si un carreau vaut 8x8, 8x3=24, l'icône fera 24x24), pensez à centrer l'icône de préférence.

Visible en fond ?

Posté par Brendan75 le 29 Déc - 19:01 (2009)
Voici les trois images que j'ai utilisé :

La carte avec les contours etc... au format 640x480.

Le curseur

et le point "héros"

Vu que la carte est entourée de "vide" (transparence) il faut ajouter la map en fond, c'est à dire le tileset mappé... (je sens que je ne suis pas clair ><) sinon le fond est noir autour de l'image, en gros, on laisse true ligne 31.

Posté par Warp' le 29 Déc - 20:18 (2009)
Je crois avoir bien suivi les instructions mais ca me donne ce log :
---------- Erreur de script : Scene_Carte ----------
----- Type
ArgumentError
----- Message
wrong number of arguments(8 for 7)
----- Position dans Scene_Carte
Ligne 209
----- Backtrace
Script : Scene_Carte | Ligne : 209 | Méthode : in `draw_text'
Script : Scene_Carte | Ligne : 209 | Méthode : in `refresh'
Script : Scene_Carte | Ligne : 125 | Méthode : in `main'
Script : Main | Ligne : 57

Posté par Brendan75 le 29 Déc - 20:25 (2009)
J'ai fais une petite mise à jour, il n'y a donc plus de ligne 209. Réessaie et si le problème persiste post ton script. A priori c'est un problème dans le nomination des lieux.

Posté par Masharu-Law le 30 Déc - 00:06 (2009)
Intéressant Clin d'œil foireux. Mais je m'intéresse qu'à la carte : C'est toi qui l'a fait (je parle du graphisme de la carte que tu use pour ce tuto) ? J'aimerais bien m'en inspirer Imbécile heureux.

Posté par Sachafr le 14 Nov - 22:18 (2010)
Lorseque je veut commencer mon jeu sa fait ????? mini_map ??? 2 ??? Syntax erreur (mini_map c'est le nom de ton script ou j'ai changer le nom et je l'ai appeler test_carte et sa a faite ???? test_carte ??? 2 ??? syntax erreur. merci :(

Posté par Brendan75 le 15 Nov - 07:18 (2010)
Tu me déterres un sujet là X), mais tant mieux ça fait de la pub ^^
Il y a un log ? Parce que là je ne vois pas vraiment, essaie de recopier/coller le script on ne sait jamais.

Posté par Speed le 15 Nov - 11:02 (2010)
Aaah ! Enfin un script qui gère une worldmap avec des carreaux de 8x8 !
Et en plus, c'est entièrement personnalisable !

Un grand merci !

Posté par Brendan75 le 15 Nov - 15:06 (2010)
Merci Speed, mais il n'est pas nouveau du tout. X)

Posté par Slash le 15 Nov - 16:46 (2010)
script tres tres intéressant, je vait voir si je ne peut pas m'en servir de base pour afficher la position de capture dans le pokedex
je pense que via un tableau parametrable sa doit etre possible

Posté par Suicune31 le 15 Nov - 16:53 (2010)
Slash, si tu arrive à adapter le script de Brendan pour le pokédex il sera aussi utilisable pour le pokématos de PSP DS ? :?

Posté par Slash le 15 Nov - 16:56 (2010)
ah ouais j'y avait pas penser mais c'est possible

Posté par Epistol le 28 Aoû - 21:14 (2011)
Necropost désolé ^^
Quand tu dit : Les coordonnées de la carte et des textes vous sont demandées.
Seulement, est-ce les seules coordonnées a partir du coin haut gauche ou faut-il mettre ceux de bas droite aussi ?
Si non est-ce possible ?

Posté par Brendan75 le 28 Aoû - 21:29 (2011)
Demandé les coordonnée Haut-Gauche et Bas Droite, ça n'a aucun sens. Il faut juste celle par rapport au coin Haut Gauche (c'est marqué d'ailleurs..).
J'espère que ça réponds à ta question, sinon, c'est que je ne l'ai pas compris et il faudra me ré-expliquer.

Posté par Epistol le 28 Aoû - 21:33 (2011)
Oui ça répond à ma question :p
Mais le truc c'est que si tu as une ville de deux cases sur ta map, il faudra écrire deux fois le code du script mais avec deux coord différentes.
Alors que mon idée était de pouvoir dire : le message doit s'afficher de ce haut-gauche jusqu'a ce bas droite.


M'enfin voilà^^

Posté par Brendan75 le 28 Aoû - 21:39 (2011)
C'est possible, il suffit de remplacer la coordonnée (3 par exemple) par une forme 3..4.

Posté par Girakoth le 4 Jan - 20:30 (2012)
Désolé pour le nécropost!

Un problème à la ligne 246 empêchait le script de fonctionner (erreur lors du lancement), je l'ai donc corrigé:

Spoiler


   


Code:
logfile.write("# ---------- <b style=\"color:#D0D1D1\">Mappemonde</b> ----------\n") 


C'est la dernière ligne, les balises codes ont l'air de planter un peu :/(code à mettre au lieu de la ligne 256 d'origine)




Par contre j'ai beau faire D (la touche que j'ai réglée), rien ne s'affiche :/

Posté par Brendan75 le 8 Jan - 08:56 (2012)
Par défaut la touche, c'est Y, et il faut avoir active l'interrupteur 200. (voir l 284). Est ce que tu l'as changé ? Si oui, en quoi ?

Posté par Girakoth le 8 Jan - 11:06 (2012)
J'ai mis "Z" à la fonction imput, il me semble que cela correspond au D dans psp ds.
Sinon la cause du problème est peut être bien l'interrupteur 200 non activé, je test ça et je te tiens au courant.

Posté par Over le 6 Juil - 09:07 (2012)
Dsl pour le nécro post, mais j'aurais besoin de connaître les dimensions optimales que ma map devra faire pour aller dans ce script ?


car pour le moment elle est en 216x168 mais même le script de base de PSPDS pour la carte ne lui convient pas.

Posté par Overheat45 le 28 Sep - 15:26 (2012)
Salut! J'aimerais savoir si il est possible d'utiliser une worldmap de 256x168 ?
Sinon, y aurais-t-il un moyen qu'il fasse tout l'écran?

Posté par Arc-Arceus le 5 Oct - 15:07 (2012)
Modifier le script. Pour cela, bases de connaissances sur le RGSS et en avant. Par ailleurs, il faudra régler la taille des carreaux.

Posté par Pαlвσlѕку le 5 Oct - 19:12 (2012)
C'est vrai que la carte n'est pas très utilisable sur PSP DS...

Pour connaitre les touches, il faut appuyer sur F1 (ou une autre touche F si c'est pas celle-là) pour voir la correspondance entre les touches de RMXP et les touches de notre clavier.
Par exemple C = Entrée ; B = Echap