Auteur : rataime
Bon, comme on aime tous avoir des effets qui tuent dans nos jeux, j'avais suivi le tuto de Genzai Kawakami http://genzaik.suidzer0.org/?p=22&t=ombres sur la création d'ombres. En gros, ça permet d'avoir une ombre qui suit le héros et d'autres event au choix. J'avais envie de me mettre au Ruby, donc j'ai essayé d'adapter le scrîpt pour faire des ombres dynamiques. Petit apercu du résultat :
http://arthur.porre.free.fr/gwen/ombres.gif
Il y a 1 fichier à modifier, et un à créer :
Sprite_Character :
- Code : Tout sélectionner
#==============================================================================
# ¦ Sprite_Character modifié (voir Sprite_Ombre)
#------------------------------------------------------------------------------
# ??????????????????Game_Character ???????????
# ????????????????????????
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# ? ??????????
#--------------------------------------------------------------------------
attr_accessor :character # ??????
#--------------------------------------------------------------------------
# ? ?????????
# viewport : ??????
# character : ?????? (Game_Character)
#--------------------------------------------------------------------------
def initialize(viewport, character = nil)
super(viewport)
@character = character
@ombrelist=[]
if (character.is_a?(Game_Event) and character.list!=nil and character.list[0].code == 108 and character.list[0].parameters == ["s"])
if (character.list[1]!=nil and character.list[1].code == 108)
@anglemin=character.list[1].parameters.to_s
end
if (character.list[2]!=nil and character.list[2].code == 108)
@anglemax=character.list[2].parameters.to_s
end
if (character.list[3]!=nil and character.list[3].code == 108)
@distancemax=character.list[3].parameters.to_s
end
for i in $game_map.events.keys.sort
if ($game_map.events[i].is_a?(Game_Event) and $game_map.events[i].list!=nil and $game_map.events[i].list[0].code == 108 and $game_map.events[i].list[0].parameters == ["o"])
@ombrelist[i+1] = Sprite_Ombre.new(viewport, $game_map.events[i],self,@anglemin,@anglemax,@distancemax)
end
end
@ombrelist[1] = Sprite_Ombre.new(viewport, $game_player,self,@anglemin,@anglemax,@distancemax)
end
update
end
#--------------------------------------------------------------------------
# ? ??????
#--------------------------------------------------------------------------
def update
super
# ??? ID?????????????????????????
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
# ??? ID ????????????
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
# ??? ID ????????
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
# ??? ID ????????
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
# ???????
self.visible = (not @character.transparent)
# ????????????????
if @tile_id == 0
# ?????????
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# ???????????
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
# ?????????????????
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
# ???????
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
if @ombrelist!=[]
for i in 1..@ombrelist.size
if @ombrelist[i]!=nil
@ombrelist[i].update
end
end
end
end
end
Puis créer un scrîpt Sprite_Ombre (juste en dessous du précédent par exemple):
- Code : Tout sélectionner
#==============================================================================
# ¦ Sprite_Ombre
# Base par Genzai Kawakami, dynamisme par Rataime, améliorations par Boushy
#------------------------------------------------------------------------------
# ??????????????????Game_Character ???????????
# ????????????????????????
#==============================================================================
class Sprite_Ombre < RPG::Sprite
#--------------------------------------------------------------------------
# ? ??????????
#--------------------------------------------------------------------------
attr_accessor :character # ??????
#--------------------------------------------------------------------------
# ? ?????????
# viewport : ??????
# character : ?????? (Game_Character)
#--------------------------------------------------------------------------
def initialize(viewport, character = nil,source = nil,anglemin=0,anglemax=0,distancemax=0)
super(viewport)
@anglemin=anglemin.to_f
@anglemax=anglemax.to_f
@distancemax=distancemax.to_f
@character = character
@source = source
update
end
#--------------------------------------------------------------------------
# ? ??????
#--------------------------------------------------------------------------
def update
super
# ??? ID?????????????????????????
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
# ??? ID ????????????
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
# ??? ID ????????
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
# ??? ID ????????
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
# ???????
self.visible = (not @character.transparent)
# ????????????????
if @tile_id == 0
# ?????????
sx = @character.pattern * @cw
@direct=@character.direction
if self.angle>90 or angle<-90
if @direct== 6
sy = ( 4- 2) / 2 * @ch#@character.direction
end
if @direct== 4
sy = ( 6- 2) / 2 * @ch
end
if @direct != 4 and @direct !=6
sy = (@character.direction - 2) / 2 * @ch
end
else
sy = (@character.direction - 2) / 2 * @ch
end
self.src_rect.set(sx, sy, @cw, @ch)
end
# ???????????
self.x = @character.screen_x
self.y = @character.screen_y-5
self.z = @character.screen_z(@ch)-1
# ?????????????????
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
# ???????
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
@deltax=@source.x-self.x
@deltay= @source.y-self.y
self.angle = 57.3*Math.atan2(@deltax, @deltay )
@angle_trigo=self.angle+90
if @angle_trigo<0
@angle_trigo=360+@angle_trigo
end
self.color = Color.new(0, 0, 0)
@distance = ((@deltax ** 2) + (@deltay ** 2))
self.opacity = 1200000/(@distance+6000)
@distance = @distance ** 0.5
if @distancemax !=0 and @distance>=@distancemax
self.opacity=0
end
if @anglemin !=0 or @anglemax !=0
if @angle_trigo<@anglemin or @angle_trigo>@anglemax
self.opacity=0
end
end
end
end
Le mode d'emploi est pas compliqué :
- Pour creer une source, mettez comme premiere ligne d'un event un commentaire avec la lettre s
- Pour ombrer un event, mettez comme premiere ligne de celui ci un commentaire avec la lettre o
D'après ce que j'ai vu, ça bouffe même pas trop de mémoire
NB : La version FR de RmXP contient une version buguée de la librairie du jeu (problèmes de superposition des events).
Solution : http://www.enterbrain.co.jp/tkool/rpgxp/RGSS100a.EXE à extraire et à rempacer dans c:\windows\system32 (ou \system pour les windows <XP). Vous devez fermer RmXP avant de remplacer le dll.
Au passage, c'est ce qui faisait que l'ombre foirait aux alentours de 180° dans la version originale
Reste à faire :
- retourner l'ombre du perso quand l'angle > +-90°. Si quelqu'un connait la commande...Parce que là l'ombre regarde dans le sens inverse du perso. Pas tres crédible !
Voilà , et que ça servent de leçon à ceux qui hésitent à se lancer dans le scripting : y'a 5 jours, je savais pas ce qu'était le Ruby icon_biggrin
Et encore merci à Genzai Kawakami pour l'idée originale !
EDIT : Version 1.1 !
Changelog :
- Sens de l'ombre fixée (boushy)
- Grosse amélioration de l'evolution de l'opacité en fonction de la distance (rataime
- Ajout d'angle min et max facultatifs, à spécifier dans un 2eme commentaire (min) et 3eme commentaire(max) (boushy)
Ces angles suivent le sens trigo en degré (pour les nuls : pareil qu'un rapporteur lu de droite à gauche)
- Ajout d'une distance max en 4eme commentaire pour faire disparaitre l'ombre. Distance en pixels (genre 500 ou 1000) (boushy)
- Quelques bug fixés (rataime)