Smooth Picture Movement + Earthquake Effect
by KJ21 / Justin
Introduction:
Do you want to add smooth animations and effects to pictures in your RPG Maker XP project?

Well... This script allows you to move, zoom, adjust opacity, and apply earthquake effects to pictures, all with gradual and natural animations. Additionally, it now includes the flash_pic feature, which lets you create picture flash effects with customizable colors, transparency, and duration. Whether you're creating dynamic cutscenes, UI enhancements, or visual storytelling moments, this script provides the tools to make your pictures more engaging.
No worries—you can still use the default picture movement commands even with this script installed. This script simply adds new functionality without overriding the existing features.

Features:
- Smooth movement of pictures
- Zoom in/out with adjustable levels
- Opacity adjustment for fading effects
- Earthquake effect with customizable strength, speed and duration
- Flash effect with any color, adjustable alpha transparency, and customizable duration (New Version)
Known Issues:
- It is maybe not recommended to use smooth movement while the shake effect is active during slow-motion scenes. Movements may not align properly under these conditions.
Screenshots:
![[Image: wff3GHN.gif]](https://i.imgur.com/wff3GHN.gif)
![[Image: Mtx6VnT.gif]](https://i.imgur.com/Mtx6VnT.gif)
Script:
Code:
#==============================================================================
# ** Smooth Picture Movement + Earthquake Effect
#------------------------------------------------------------------------------
# Author: KJ21 / Justin (K-J Productions INC.)
# Version: 2.6
# Date: April 6, 2025
#==============================================================================
# Description:
# This script enables smooth movement, zoom, and opacity transitions for
# pictures, as well as an earthquake effect with smooth fading and
# a flash effect with customizable color and duration.
#
# Commands:
# smooth_pic(id, x, y, zoom_x, zoom_y, opacity, duration)
# - id: Picture ID (1-50)
# - x, y: Target position
# - zoom_x, zoom_y: Target zoom (100 = 100%, etc.)
# - opacity: Target opacity (0-255)
# - duration: Duration in frames (60 frames = 1 second)
#
# start_shake_pic(id, power, speed)
# stop_shake_pic(id, duration)
# - id: Picture ID (1-50)
# - power: Strength of the shake effect (recommended: 5-7)
# - speed: Speed of the shake effect (recommended: 30-100)
# - duration: Duration of fade-out in frames (default: 60)
#
# flash_pic(id, red, green, blue, alpha, duration)
# - id: Picture ID (1-50)
# - red, green, blue: Color values (0-255)
# - alpha: Flash color transparency (0-255)
# - duration: Duration of fade-out in frames (60 frames = 1 second)
#==============================================================================
class Game_Screen
def smooth_pic(id, x, y, zoom_x, zoom_y, opacity, duration)
picture = @pictures[id]
picture.smooth_move_zoom_and_opacity(x, y, zoom_x, zoom_y, opacity, duration) if picture
end
def start_picture_shake(id, power, speed)
picture = @pictures[id]
picture.start_shake(power, speed) if picture
end
def stop_picture_shake(id, duration = 60)
picture = @pictures[id]
picture.stop_shake(duration) if picture
end
def flash_picture(id, red, green, blue, alpha, duration)
picture = @pictures[id]
picture.start_flash(red, green, blue, alpha, duration) if picture
end
end
class Game_Picture
attr_accessor :target_x, :target_y, :target_zoom_x, :target_zoom_y, :target_opacity, :movement_duration, :movement_time
attr_accessor :start_x, :start_y, :start_zoom_x, :start_zoom_y, :start_opacity
attr_accessor :base_x, :base_y
attr_accessor :shake_stop_base_x, :shake_stop_base_y
attr_accessor :shake_power, :shake_speed, :shake_active
attr_accessor :flash_color, :flash_duration, :flash_time, :original_flash_color, :flash_active
alias smooth_pic_original_initialize initialize
def initialize(number)
smooth_pic_original_initialize(number)
@target_x = @x
@target_y = @y
@target_zoom_x = @zoom_x
@target_zoom_y = @zoom_y
@target_opacity = @opacity
@movement_duration = 0
@movement_time = 0
@start_x = @x
@start_y = @y
@start_zoom_x = @zoom_x
@start_zoom_y = @zoom_y
@start_opacity = @opacity
@base_x = @x
@base_y = @y
@shake_stop_base_x = @x
@shake_stop_base_y = @y
@shake_power = 0
@shake_speed = 0
@shake_active = false
@shake_time = 0
@original_x = @x
@original_y = @y
@shake_fade_duration = 0
@shake_fade_time = 0
@flash_color = [0, 0, 0, 0]
@original_flash_color = [0, 0, 0, 0]
@flash_duration = 0
@flash_time = 0
@flash_active = false
end
def smooth_move_zoom_and_opacity(new_x, new_y, new_zoom_x, new_zoom_y, new_opacity, duration)
@start_x = @x
@start_y = @y
@start_zoom_x = @zoom_x
@start_zoom_y = @zoom_y
@start_opacity = @opacity
@target_x = new_x
@target_y = new_y
@target_zoom_x = new_zoom_x
@target_zoom_y = new_zoom_y
@target_opacity = new_opacity
@movement_duration = duration
@movement_time = 0
end
def update_smooth_movement_zoom_and_opacity
if @movement_duration > 0
@movement_time += 1
rate = @movement_time.to_f / @movement_duration
pi_rate = Math.sin(rate * Math::PI / 2)
new_x = @start_x + (@target_x - @start_x) * pi_rate
new_y = @start_y + (@target_y - @start_y) * pi_rate
@zoom_x = @start_zoom_x + (@target_zoom_x - @start_zoom_x) * pi_rate
@zoom_y = @start_zoom_y + (@target_zoom_y - @start_zoom_y) * pi_rate
@opacity = @start_opacity + (@target_opacity - @start_opacity) * pi_rate
@base_x = new_x
@base_y = new_y
if @movement_time >= @movement_duration
@x = @target_x
@y = @target_y
@zoom_x = @target_zoom_x
@zoom_y = @target_zoom_y
@opacity = @target_opacity
@movement_duration = 0
@start_x = @x
@start_y = @y
@start_zoom_x = @zoom_x
@start_zoom_y = @zoom_y
@start_opacity = @opacity
@base_x = @x
@base_y = @y
@original_x = @x
@original_y = @y
else
@x = @base_x
@y = @base_y
end
end
end
def start_shake(power, speed)
@shake_power = power
@shake_speed = speed
@shake_active = true
@shake_time = 0
@shake_fade_duration = 0
@shake_fade_time = 0
end
def stop_shake(duration = 60)
@shake_stop_base_x = @base_x
@shake_stop_base_y = @base_y
@shake_fade_duration = duration
@shake_fade_time = 0
end
def start_flash(red, green, blue, alpha, duration)
@original_flash_color = [red, green, blue, alpha]
@flash_color = [red, green, blue, alpha]
@flash_duration = duration
@flash_time = 0
@flash_active = true
end
def update_flash
if @flash_active
@flash_time += 1
if @flash_duration > 0
progress = @flash_time.to_f / @flash_duration
fade_factor = 1.0 - progress
@flash_color[0] = (@original_flash_color[0] * fade_factor).to_i
@flash_color[1] = (@original_flash_color[1] * fade_factor).to_i
@flash_color[2] = (@original_flash_color[2] * fade_factor).to_i
@flash_color[3] = (@original_flash_color[3] * fade_factor).to_i
end
if @flash_time >= @flash_duration
@flash_color = [0, 0, 0, 0]
@flash_active = false
end
end
end
alias smooth_pic_original_update update
def update
smooth_pic_original_update
update_smooth_movement_zoom_and_opacity
update_shake
update_flash
end
def update_shake
if @shake_active
@shake_time += 1
current_power = @shake_power
if @shake_fade_duration > 0
@shake_fade_time += 1
fade_rate = 1 - (@shake_fade_time.to_f / @shake_fade_duration)
current_power *= fade_rate
if @shake_fade_time >= @shake_fade_duration
@shake_active = false
if @movement_duration > 0
@x = @shake_stop_base_x
@y = @shake_stop_base_y
else
@x = @original_x
@y = @original_y
end
return
end
end
shake_x = current_power * Math.sin(@shake_time * @shake_speed * Math::PI / 180)
shake_y = current_power * Math.cos(@shake_time * @shake_speed * Math::PI / 180)
if @movement_duration > 0
@x = @base_x + shake_x
@y = @base_y + shake_y
else
@x = @original_x + shake_x
@y = @original_y + shake_y
end
end
end
end
class Sprite_Picture < Sprite
alias smooth_pic_flash_update update
def update
smooth_pic_flash_update
if @picture
if @picture_flash_tone.nil?
@picture_flash_tone = Tone.new(0, 0, 0, 0)
end
if @picture.flash_active
r, g, b, a = @picture.flash_color
@picture_flash_tone.set(r, g, b, a)
else
@picture_flash_tone.set(0, 0, 0, 0)
end
self.tone = @picture_flash_tone
end
end
end
def smooth_pic(id, x, y, zoom_x, zoom_y, opacity, duration)
$game_screen.smooth_pic(id, x, y, zoom_x, zoom_y, opacity, duration)
end
def start_shake_pic(id, power, speed)
$game_screen.start_picture_shake(id, power, speed)
end
def stop_shake_pic(id, duration = 60)
$game_screen.stop_picture_shake(id, duration)
end
def flash_pic(id, red, green, blue, alpha, duration)
$game_screen.flash_picture(id, red, green, blue, alpha, duration)
end
Instructions:
First, you need to create a picture in the event command called "Show Picture."
How you want to set it up is entirely up to you.
Next, use the following script calls in your events:
Code:
For Movement:
smooth_pic(id, x, y, zoom_x, zoom_y, opacity, duration)
For Earthquake Effect:
start_shake_pic(id, power, speed)
stop_shake_pic(id, duration)
For Flash Effect:
flash_pic(id, red, green, blue, alpha, duration)
Parameters Explained:
- id: Picture ID (1–50).
- x, y: Target position on the screen.
- zoom_x, zoom_y: Zoom level as a percentage (e.g., 100 = 100%, 200 = 200%).
- opacity: Transparency level (0 = invisible, 255 = fully visible).
- duration: Animation time in frames (60 frames = 1 second).
- power: Strength of the shake effect (recommended range: 5–7).
- speed: Speed of the shake effect (recommended range: 30–100).
- red, green, blue: Color values (0–255) for the flash effect.
- alpha: Flash color transparency (0–255).
Examples:
Move picture 1 to (100, 200), zoom to 150%, set opacity to 50%, and animate over 1 second:
Code:
smooth_pic(1, 100, 200, 150, 150, 128, 60)
Code:
start_shake_pic(1, 5, 30)
Code:
stop_shake_pic(1, 20)
Code:
flash_pic(1, 255, 255, 255, 255, 20)
Q&A:
Q: Are you adding more features to this script?
A: If I have ideas for adding features to this script, then yeah, maybe in the next version.
Compatibility:
- Compatibility with default picture commands means you can also use the default function normally.
Terms & Conditions:
Free to use in any RPG Maker XP project (commercial or non-commercial).
Just don’t forget to credit me – I’d really appreciate it!
I create games as a hobby. I do scripting when it almost seems impossible to code.
My games are only in German, so there is no English version. :( wah...
Also:
![[Image: SP1-Scripter.png]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)
My games are only in German, so there is no English version. :( wah...
Also:
![[Image: SP1-Scripter.png]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)