Compatible XP, VX et VXace.
Ce script permet de rajouter quelques petits effets de la more aux maps pour les embellir (ça s'adresse à ceux qui ont plein de temps à perdre dans des détails).
Pour faire simple ce script permet d'afficher des images qui bouclent un peu à la manière des brouillards mais juste dans le cadre d'une image et avec la forme qu'on veut.
Pour ça on a besoin de deux choses, une image en noir et blanc qui servira de masque et une texture.
Plutôt que du blabla des exemples :
- Une lumière avec de la poussière qui flotte.
Le masque et la texture utilisés :
- Une fumée dans un couloir.
Le masque et la texture utilisés (texture que j'ai par ailleurs mis a 400% de zoom dans les réglages pour avoir cet effet) :
J'ai essayé de rendre ça le plus simple possible à configurer donc on va utiliser la commande Afficher une image.
Mais avant d'utiliser la commande on insère un script en écrivant : scroll_picture_mask
Comme ça les commandes qui suivent ne seront pas gérées comme étant des images normales.
Dans la commande Afficher une image on sélectionne l'image de masque, la position sur la map en pixels, etc... toutes les réglages seront pris en compte comme sur une image normale.
Ensuite pour configurer la texture on va réutiliser la commande Afficher une image mais cette fois avant on met un script avec : scroll_picture_texture
Cette fois on choisis l'image de texture mais les autres réglages auront un autre effet, la position X indiquera la vitesse de défilement sur X, la position Y la vitesse de défilement sur Y, le zoom ici est celui de la texture qui est indépendant du zoom de l'image elle même, les autres réglages ne sont pas utilisés.
Ce qui donne quelque chose comme ça :
Si on a besoin d'en configurer plusieurs d’affiler, on a pas besoin de faire : <> Script : scroll_picture_mask
<> Afficher image : N°1 ...
<> Script : scroll_picture_mask
<> Afficher image : N°2 ...
On peut simplifier en : <> Script : scroll_picture_mask
<> Afficher image : N°1 ...
<> Afficher image : N°2 ...
De même on peut aussi utiliser les commandes Déplacer une image, Faire tourner une image, Modifier le ton d'une image et Effacer une image.
Toutes les commandes liées aux images suivant directement scroll_picture_mask sont considéré comme telles.
Idem pour scroll_picture_texture
Enfin il y'a deux réglages supplémentaires qu'on ne peut faire qu'en script.
scroll_picture(id).z = valeur
Avec id le numéro de l'image et valeur la priorité de superposition, la valeur par défaut est 1000 ce qui correspond à Au dessus de tout, mais on peut mettre par exemple 1 pour que l'image soit juste au dessus du sol, ou un nombre négatif pour qu'elle apparaisse derrière la map.
scroll_picture(id).map_anchor = valeur
Avec id le numéro de l'image et valeur le rapport entre la position de l'image et la map, la valeur par défaut est 1 ce qui signifie que l'image bouge avec la map, à 0 l'image n'est pas fixée à la map, à 2 l'image bouge avec la map et deux fois plus vite, à 0.5 l'image bouge avec la map mais deux fois moins vite.
Le script, à mettre au dessus du main comme d'hab :
# Scroll Pictures 1.0 for XP, VX & VXAce by Zeus81
class Game_Scroll_Picture < Game_Picture
attr_accessor :z, :map_anchor, :texture, :texture_ox, :texture_oy, :erased
def initialize(number)
@z , @map_anchor, @texture , @texture_ox, @texture_oy, @erased =
1000, 1 , Game_Picture.new(number), 0 , 0 , false
super(number)
end
def erase() @erased = true end
def update
super
@texture.update
@texture_ox -= @texture.x / 10.0
@texture_oy -= @texture.y / 10.0
end
end
class Sprite_Scroll_Picture < Sprite
dll = FileTest.directory?('System') ? 'System/ZEUS' : 'ZEUS'
GrayscaleMaskBlt = Win32API.new(dll, 'GrayscaleMaskBlt', 'iiiiiiiiii', 'i')
def initialize(viewport, picture)
super(viewport)
@picture, @last_args = picture, []
end
def dispose
bitmap.dispose if bitmap
super
end
def update
return unless self.visible = !@picture.name.empty? && !@picture.texture.name.empty?
if @last_mask_name != @picture.name
@last_mask_name = @picture.name.dup
bitmap.dispose if bitmap
mask = cache(@picture.name)
self.bitmap = Bitmap.new(mask.width, mask.height)
end
if @picture.origin != 0
self.ox = bitmap.width / 2
self.oy = bitmap.height / 2
else self.ox = self.oy = 0
end
self.x = @picture.x - @picture.map_anchor * map_display_x
self.y = @picture.y - @picture.map_anchor * map_display_y
self.z = @picture.z
self.zoom_x = @picture.zoom_x / 100.0
self.zoom_y = @picture.zoom_y / 100.0
self.opacity = @picture.opacity
self.blend_type = @picture.blend_type
self.angle = @picture.angle
self.tone = @picture.tone
return unless self.visible = on_screen?
super
args = [bitmap.__id__ << 1, 0, cache(@picture.name).__id__ << 1, 0,
cache(@picture.texture.name).__id__ << 1, 0,
@picture.texture_ox.to_i, @picture.texture_oy.to_i,
@picture.texture.zoom_x.to_i, @picture.texture.zoom_y.to_i]
return if @last_args == args
@last_args.replace(args)
GrayscaleMaskBlt.call(*args)
end
def on_screen?
x1, y1, w1, h1 = x, y, (bitmap.width*zoom_x).to_i, (bitmap.height*zoom_y).to_i
w2, h2 = screen_width, screen_height
if angle == 0
x1, y1 = x1-w1/2, y1-h1/2 if ox != 0
x1<w2 and x1+w1>0 and y1<h2 and y1+h1>0
else
x1, y1, r1 = (x1-w2/=2).abs, (y1-h2/=2).abs, Math.hypot(w1, h1)
r1 /= 2 if ox != 0
x1<=w2+r1 and y1<=h2+r1 and (x1<=w2 or y1<=h2 or Math.hypot(x1-w2,y1-h2)<=r1)
end
end
if defined?(Hangup) #xp
def cache(filename) RPG::Cache.picture(filename) end
def screen_width() 640 end
def screen_height() 480 end
def map_display_x() $game_map.display_x / 4 end
def map_display_y() $game_map.display_y / 4 end
else #vx & vxace
def cache(filename) Cache.picture(filename) end
def screen_width() Graphics.width end
def screen_height() Graphics.height end
if RUBY_VERSION == '1.8.1' #vx
def map_display_x() $game_map.display_x / 8 end
def map_display_y() $game_map.display_y / 8 end
else #vxace
def map_display_x() $game_map.display_x * 32 end
def map_display_y() $game_map.display_y * 32 end
end
end
end
class Game_Map
attr_reader :scroll_pictures
alias zeus81_scroll_pictures_setup setup
def setup(map_id)
@scroll_pictures = {}
zeus81_scroll_pictures_setup(map_id)
end
alias zeus81_scroll_pictures_update update
def update(*args)
@scroll_pictures.delete_if {|i, p| p.erased}
@scroll_pictures.each_value {|p| p.update}
zeus81_scroll_pictures_update(*args)
end
end
class Spriteset_Map
alias zeus81_scroll_pictures_dispose dispose
def dispose
@scroll_picture_sprites.each_value {|s| s.dispose}
zeus81_scroll_pictures_dispose
end
alias zeus81_scroll_pictures_update update
def update
@scroll_picture_sprites ||= {}
@scroll_picture_sprites.delete_if do |i, s|
s.dispose if result = !$game_map.scroll_pictures.has_key?(i)
result
end
for i, p in $game_map.scroll_pictures
s = @scroll_picture_sprites[i] ||= Sprite_Scroll_Picture.new(@viewport1, p)
s.update
end
zeus81_scroll_pictures_update
end
end
if defined?(Hangup) #xp
class Interpreter
def execute_command
if @index < @list.size-1
@parameters = @list[@index].parameters
method_name = "command_#{@list[@index].code}"
return send(method_name) if respond_to?(method_name)
else command_end
end
return true
end
def scroll_picture(id)
$game_map.scroll_pictures[id] ||= Game_Scroll_Picture.new(id)
end
def scroll_picture_mask() scroll_picture_setup(0) end
def scroll_picture_texture() scroll_picture_setup(1) end
def scroll_picture_setup(type)
i = @index
while(@list[i += 1].code.between?(231, 235))
@list[i].parameters << type if @list[i].code < 233
@list[i].code += 810000
end
return true
end
def command_810231
picture = scroll_picture(@parameters[0])
picture = picture.texture if @parameters[-1] != 0
x, y = @parameters[4], @parameters[5]
x, y = $game_variables[x], $game_variables[y] if @parameters[3] != 0
picture.show(@parameters[1], @parameters[2], x, y, @parameters[6],
@parameters[7], @parameters[8], @parameters[9])
return true
end
def command_810232
picture = scroll_picture(@parameters[0])
picture = picture.texture if @parameters[-1] != 0
x, y = @parameters[4], @parameters[5]
x, y = $game_variables[x], $game_variables[y] if @parameters[3] != 0
picture.move(@parameters[1]*2, @parameters[2], x, y, @parameters[6],
@parameters[7], @parameters[8], @parameters[9])
return true
end
def command_810233
scroll_picture(@parameters[0]).rotate(@parameters[1])
return true
end
def command_810234
scroll_picture(@parameters[0]).start_tone_change(@parameters[1], @parameters[2]*2)
return true
end
def command_810235
id = @parameters[0]
scroll_picture(id).erase if $game_map.scroll_pictures.has_key?(id)
return true
end
end
else #vx & vxace
class Game_Interpreter
if RUBY_VERSION == '1.8.1' #vx
def wait(duration) @wait_count = duration end
def execute_command
if @index < @list.size-1
@params, @indent = @list[@index].parameters, @list[@index].indent
method_name = "command_#{@list[@index].code}"
return send(method_name) if respond_to?(method_name)
else command_end
end
return true
end
end
def scroll_picture(id)
$game_map.scroll_pictures[id] ||= Game_Scroll_Picture.new(id)
end
def scroll_picture_mask() scroll_picture_setup(0) end
def scroll_picture_texture() scroll_picture_setup(1) end
def scroll_picture_setup(type)
i = @index
while(@list[i += 1].code.between?(231, 235))
@list[i].parameters << type if @list[i].code < 233
@list[i].code += 810000
end
end
def command_810231
picture = scroll_picture(@params[0])
picture = picture.texture if @params[-1] != 0
x, y = @params[4], @params[5]
x, y = $game_variables[x], $game_variables[y] if @params[3] != 0
picture.show(@params[1], @params[2], x, y, @params[6],
@params[7], @params[8], @params[9])
return true
end
def command_810232
picture = scroll_picture(@params[0])
picture = picture.texture if @params[-1] != 0
x, y = @params[4], @params[5]
x, y = $game_variables[x], $game_variables[y] if @params[3] != 0
picture.move(@params[2], x, y, @params[6], @params[7],
@params[8], @params[9], @params[10])
wait(@params[10]) if @params[11]
return true
end
def command_810233
scroll_picture(@params[0]).rotate(@params[1])
return true
end
def command_810234
scroll_picture(@params[0]).start_tone_change(@params[1], @params[2])
wait(@params[2]) if @params[3]
return true
end
def command_810235
id = @params[0]
scroll_picture(id).erase if $game_map.scroll_pictures.has_key?(id)
return true
end
end
end
La dll, à mettre direct dans le dossier du jeu sauf pour VXace où il faut mettre ça dans le sous-dossier System : http://www.mediafire.com/?1g4shddbhh1qh
Y'a aussi le code source pour ceux que ça intéresse, c'est un projet VC++2010 Express.
Pour les scripteurs y'a d'autres possibilités avec la fonction GrayscaleMaskBlt qui ne sont pas exploitées dans ce scripts.
GrayscaleMaskBlt .call(
bitmap.__id__<<1, #Le bitmap dans lequel on veut dessiner
bitmap_rect.__id__<<1, #Rect de la zone à remplir, si c'est tout le bitmap on peut mettre 0
mask.__id__<<1, #(Facultatif) Bitmap d'un masque en niveau de gris à appliquer au remplissage, si la taille du masque est différente de celle du bitmap il est automatiquement étiré
mask_rect.__id__<<1, #Rect de la zone du masque qu'on désire utiliser, si c'est tout le bitmap on peut mettre 0
texture.__id__<<1, #Bitmap de la texture à dessiner
texture_rect.__id__<<1, #Rect du morceau de texture à dessiner, si c'est tout le bitmap on peut mettre 0
texture_ox, #Le décalage en pixels de la texture sur x
texture_oy, #Le décalage en pixels de la texture sur y
texture_zoom_x, #L'étirement de la texture sur x, défaut 100, ne peut pas être égal à 0, si négatif la texture est inversée sur x
texture_zoom_y #L'étirement de la texture sur y, défaut 100, ne peut pas être égal à 0, si négatif la texture est inversée sur y
)
La fonction retourne aussi un message, 0 = pas d'erreur, 1 = zoom invalide, 2 = rect invalide
Dernière modification par Zeus81 le ven. mai 25, 2012 8:19 am, modifié 1 fois.
(j'ai dû mettre des liens à la place des balises images qui sont complètement buguées.)
Ha désolé, c'est uniquement avec l'hébergeur XOOIMAGE que ça fait ça, un vilain hébergeur pis voilà. (tu peux réup en utilisant le système embarqué de ce forum si tu veux, et ainsi avoir la garanti que ça ne sera pas supprimé)
Sinon le script est super, pis on ne perd pas tant de temps que ça contrairement au :
ça s'adresse à ceux qui ont plein de temps à perdre dans des détails
C'est + efficace que d'autres méthodes et ça mange pas de pain une fois qu'on en a déjà bien chié sur le reste, vu que ça représente un temps négligeable de l'ensemble de la procédure graphique.
(Considérant le cas d'un mec qui aurait mis au point ses propres ressources, et qui n'est donc pas à une poignée d'heure de boulot en rab pour en sublimer un peu l'ensemble)
A vrai dire t'as quand même raison, ce sera plutôt une perte de temps pour une écrasante majorité... Saupoudrer avec des paillettes du RTP ne changera pas ça en autre chose de moins commun et impersonnel. (et puis ok pour eux ce sera du temps en moins)
Autre point positif de cette méthode, c'est le poids.
Après je sais pas si c'est un point négatif mais le fait de devoir ajouter une DLL de plus c'est toujours ça d'ennuyeux m'enfin.
(ou alors faudrait l'exploiter en faisant plein d'autres effets, mais là encore difficile d'avoir la motivation pour bosser en sachant à qui ça va être offert -_- donc bravo pour ce courage, mais y a moyen que ça s'arrange... je tenterai de faire au mieux de mon coté malgré une grosse somme de boulot qui s'amplifie au lieu de diminuer)
Malheureusement le passage par la dll est obligatoire, question de rapidité.
Les masques devraient être implémentés directement dans les Sprite et puis dans les Viewport, ça permettrait de faire plein de choses.
Voilà j'ai réup les images, les fichiers joint c'est nul faut être connecté pour les voir. :p
Pour des raisons Gameplayesque je trouve ton input ultimate plus intéressant (si quelqu’un dépasse un jour le stade des 3 maps pour se toucher sur des concours de screen) mais on peut pas nier que ça aussi c’est vraiment super, je garde au chaud.