Sprite Reflections and Wave Effects
This is one of the first scripts I made back in 2012.Back in the early era of XP, JmsPlDnl y Rataime made a Sprite Reflection script for that maker, and it was widely used. I took that idea to make another one, but in another way. In my version, each event and player has a copy of its graphic, flipped and with a Z below 0. That means usually you don't see it, but if you define a transparent water autotile and use a panorama or a similar trick to define the background of the water, you can see the reflection in between.
Author: Wecoc
Release Date: July 2012
Last Version: January 2018
Terms of Use
- Giving credits (Wecoc) for using this script is optional, but appreciated.
- The Wave Effect Addon is an edit of a code by Zecomeia, so you should credit her.
- You can repost this code.
- You can edit this code freely, and distribute the edits as well.
- This code can be used on commercial games.
Code
Ruby:
#==============================================================================
# ** Sprite_Reflection v1.2
#------------------------------------------------------------------------------
# Author: Wecoc (no credits required)
#==============================================================================
#==============================================================================
# ** Sprite_Reflection
#==============================================================================
class Sprite_Reflection < RPG::Sprite
#--------------------------------------------------------------------------
attr_accessor :character
#--------------------------------------------------------------------------
# * Initialize
#--------------------------------------------------------------------------
def initialize(viewport=nil, character=nil)
super(viewport)
@character = character
update
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
super
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
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
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 && @character.reflection)
self.mirror = true
self.angle = 180
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 - 1
self.y = @character.screen_y
self.z = @character.screen_z(@ch) - 999
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
end
end
#==============================================================================
# ** Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Initialize
#--------------------------------------------------------------------------
attr_accessor :reflection
alias reflect_ini initialize unless $@
def initialize
reflect_ini
@reflection = true
end
end
#==============================================================================
# ** Spriteset_Map
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# * Initialize
#--------------------------------------------------------------------------
alias reflect_ini initialize unless $@
def initialize
@reflection_sprites = []
reflect_ini
for i in 0...@character_sprites.size
s = @character_sprites
sprite = Sprite_Reflection.new(@viewport1, s.character)
@reflection_sprites.push(sprite)
end
update
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
alias reflect_dis dispose unless $@
def dispose
reflect_dis
for sprite in @reflection_sprites
sprite.dispose
end
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
alias reflect_upd update unless $@
def update
reflect_upd
for sprite in @reflection_sprites
sprite.update
end
end
end
Usage
To define if the player or an event has reflection, simply use this on a script call:
Code:
$game_player.reflection = true / false
$game_map.events.reflection = true / false
Related scripts
By the same time, Zecomeia made a code for Wave Effects.
Long time ago I made some edits of that code, I'll include it here with some instructions as well.
Spoiler: Wave Effects Ruby:
#==============================================================================
# ** Wave Effect
#------------------------------------------------------------------------------
# By: Zecomeia
# Date: 01/03/2010
# Version: 1.0
# Edit by: Wecoc
# Edit Date:26/07/2017
#------------------------------------------------------------------------------
# www.colmeia-do-ze.blogspot.com
#==============================================================================
class Sprite
attr_accessor :wave_amp
attr_accessor :wave_length
attr_accessor :wave_speed
attr_accessor :wave_phase
attr_accessor :temp_bitmap
alias wave_effect_ini initialize unless $@
def initialize(viewport=nil)
@wave_amp = 0
@wave_length = 72
@wave_speed = 720
@wave_phase = 0.25
wave_effect_ini(viewport)
@temp_bitmap = nil
end
alias wave_effect_upd update unless $@
def update
# the wave effect only works if wave_amp
# propertie is a number more than zero
wave_effect if @wave_amp > 0
wave_effect_upd
end
# Return the width of image, because when use
# obj.bitmap.width the value will be more than
# the original value(because effect)
def width
return (self.bitmap.width - @wave_amp * 2)
end
def wave_effect
return if self.bitmap.nil?
@temp_bitmap = self.bitmap if @temp_bitmap.nil?
cw = @temp_bitmap.width + (@wave_amp * 2)
ch = @temp_bitmap.height
# Follow the VX wave effect, each horizontal line
# has 8 pixel of height. This device provides less
# lag in game.
divisions = @temp_bitmap.height / 8
divisions += 1 if @temp_bitmap.height % 8 != 0
self.bitmap = Bitmap.new(cw, ch)
for i in 0..divisions
x = @wave_amp * Math.sin(i * 2 * Math::PI / (@wave_length / 8).to_i +
(@wave_phase * Math::PI) / 180.0)
src_rect = Rect.new(0, i*8, @temp_bitmap.width, 8)
dest_rect = Rect.new(@wave_amp + x, i * 8, @temp_bitmap.width, 8)
self.bitmap.stretch_blt(dest_rect, @temp_bitmap, src_rect)
end
# frame rate: VX = 60 | XP = 40
# wave speed compatibility VX to XP: wave_speed * 60/40
# then: wave_speed * 1.5
@wave_phase += @wave_speed * 1.5 / @wave_length
@wave_phase -= 360 if @wave_phase > 360
@wave_phase += 360 if @wave_phase < 0
end
end
for Klass in
class Klass
attr_accessor :wave_amp
attr_accessor :wave_length
attr_accessor :wave_speed
alias wave_effect_ini initialize unless $@
def initialize(*args)
wave_effect_ini(*args)
@wave_amp = 0
@wave_length = 72
@wave_speed = 720
end
end
end
class Spriteset_Map
alias wave_effect_upd update unless $@
def update
wave_effect_upd
for i in 0...@character_sprites.size
sprite = @character_sprites
if i == @character_sprites.size - 1
sprite.wave_amp = $game_player.wave_amp
sprite.wave_length= $game_player.wave_length
sprite.wave_speed = $game_player.wave_speed
else
event = $game_map.events
next if event.nil?
sprite.wave_amp = event.wave_amp
sprite.wave_length= event.wave_length
sprite.wave_speed = event.wave_speed
end
end
for i in 0...@picture_sprites.size
picture = $game_screen.pictures
sprite = @picture_sprites
sprite.wave_amp = picture.wave_amp
sprite.wave_length= picture.wave_length
sprite.wave_speed = picture.wave_speed
end
end
end
class Spriteset_Battle
alias wave_effect_upd update unless $@
def update
wave_effect_upd
for i in 0...@enemy_sprites.size
enemy = $game_troop.enemies.reverse
next if enemy.nil? or !enemy.exist?
sprite = @enemy_sprites
sprite.wave_amp = enemy.wave_amp
sprite.wave_length= enemy.wave_length
sprite.wave_speed = enemy.wave_speed
end
for i in 0...@actor_sprites.size
actor = $game_party.actors
next if actor.nil? or !actor.exist?
sprite = @actor_sprites
sprite.wave_amp = actor.wave_amp
sprite.wave_length= actor.wave_length
sprite.wave_speed = actor.wave_speed
end
for i in 0...@picture_sprites.size
picture = $game_screen.pictures
sprite = @picture_sprites
sprite.wave_amp = picture.wave_amp
sprite.wave_length= picture.wave_length
sprite.wave_speed = picture.wave_speed
end
end
end
To use it you should use sprite.wave_amp = n, where the n is the desired amplitude and the sprite may be:
Code:
$game_player # The player
$game_map.events # Event
$game_screen.pictures # Picture
$game_party.actors # Battler (Actor, by party ID)
$game_actors # Battler (Actor, by actor ID)
$game_troop.enemies # Battler (Enemy, by troop ID)
Finally, this little AddOn uses both scripts to implement the wave effect on the reflections.
Spoiler: Sprite Reflection's Wave AddOn Ruby:
#==============================================================================
# ** Sprite Reflection's Wave AddOn
#------------------------------------------------------------------------------
# This code uses Sprite_Reflection 1.2 and Wave Effect
#==============================================================================
class Sprite_Reflection
#----------------------------------------------------------------------------
DEFAULT_WAVE_AMP = 2
DEFAULT_WAVE_LENGTH = 128
DEFAULT_WAVE_SPEED = 720
#----------------------------------------------------------------------------
alias wave_addon_ini initialize unless $@
def initialize(*args)
wave_addon_ini(*args)
@wave_amp = DEFAULT_WAVE_AMP
@wave_length = DEFAULT_WAVE_LENGTH
@wave_speed = DEFAULT_WAVE_SPEED
end
end
class Sprite
def remove_wave
@wave_amp = 0
self.bitmap = @temp_bitmap.clone
end
end
class Scene_Map
attr_reader :spriteset
end
class Spriteset_Map
attr_reader :reflection_sprites
end
class Interpreter
def reflection_sprite(event_id)
return if !$scene.is_a?(Scene_Map)
spriteset = $scene.spriteset
return if spriteset.nil?
sprites = spriteset.reflection_sprites
case event_id
when -1 # Player
sprite = sprites.select do |sprite|
sprite.character == $game_player
end
when 0 # Current Character
sprite = sprites.select do |sprite|
sprite.character == $game_map.events[@event_id]
end
else # Character ID
sprite = sprites.select do |sprite|
sprite.character == $game_map.events
end
end
return sprite
end
end
To get the sprite and apply the Wave Effect changes, use:
Code:
reflection_sprite(-1) # Player
reflection_sprite(0)# Current event
reflection_sprite(1)# Event with ID 1
For example:
reflection_sprite(-1).wave_amp = 4
If you want to remove the effect, setting the wave_amp to 0 is not enough since the current waves will still be visible.
To completely remove it use:
reflection_sprite(-1).remove_wave
That's all.
本贴来自国际rpgmaker官方论坛作者:Wecoc处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/sprite-reflections-and-wave-effects.138188/
页:
[1]