=begin
╔════╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═════╗
║ ╔══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╗ ║
╠─╣ 强化镜头功能 ╠─╣
╠─╣ by RPG Maker Source. ╠─╣
╠─╣ [url]www.rpgmakersource.com[/url] ╠─╣
║ ╚══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╝ ║
╠════╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═╤═╩═════╣
║ ┌────┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴─────┐ ║
╠─┤ Version 1.0.1 13/12/14 DD/MM/YY ├─╣
║ └────┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┘ ║
╠══════╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══════╣
║ ║
║ This work is protected by the following license: ║
║ ╔══════════════════════════════════════════════════════════════════╗ ║
║ │ │ ║
║ │ Copyright ? 2014 Maker Systems. │ ║
║ │ │ ║
║ │ This software is provided 'as-is', without any kind of │ ║
║ │ warranty. Under no circumstances will the author be held │ ║
║ │ liable for any damages arising from the use of this software. │ ║
║ │ │ ║
║ │ Permission is granted to anyone to use this software on their │ ║
║ │ free or commercial games made with a legal copy of RPG Maker │ ║
║ │ VX Ace, as long as Maker Systems - RPG Maker Source is │ ║
║ │ credited within the game. │ ║
║ │ │ ║
║ │ Selling this code or any portions of it 'as-is' or as part of │ ║
║ │ another code, is not allowed. │ ║
║ │ │ ║
║ │ The original header, which includes this copyright notice, │ ║
║ │ must not be edited or removed from any verbatim copy of the │ ║
║ │ sotware nor from any edited version. │ ║
║ │ │ ║
║ ╚══════════════════════════════════════════════════════════════════╝ ║
║ ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ 1. VERSION HISTORY. ▼ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ? Version 1.0.0, 08/12/14 - (DD/MM/YY). ║
║ ║
║ ? Version 1.0.1, 13/12/14 - (DD/MM/YY). ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
╠══════════════════════════════════════════════════════════════════════════════╣
║ 2. USER MANUAL. ▼ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌──────────────────────────────────────────────────────────────────────────┐ ║
║ │ ■ 说明. │ ║
║ └┬┬┬┬──────────────────────────────────────────────────────────────────┬┬┬┬┘ ║
║ ║
║ 功能如下:
1、镜头平滑移动
2、镜头跟随事件
3、镜头固定 ║
║ ║
║ ┌──────────────────────────────────────────────────────────────────────────┐ ║
║ │ ■ Configuration. │ ║
║ └┬┬┬┬──────────────────────────────────────────────────────────────────┬┬┬┬┘ ║
║ ║
║ "How do I change the strength of the deceleration effect?" ║
║ Right click anywhere in the script editor and select "Find" (or CTRL + F) ║
║ search for "Deceleration_Value" (without quotation marks). ║
║ ║
║ You will see something like "Deceleration_Value = 22" ║
║ ║
║ Set the number after the equality sign to any numer you like, bigger or ║
║ equal than 1. The bigger the number, the stronger the deceleration effect ║
║ and thus the slower the camera movement when following the player. Small ║
║ numbers result in a faster deceleration, default value is 22. ║
║ ║
║ ┌──────────────────────────────────────────────────────────────────────────┐ ║
║ │ ■ 具体功能. │ ║
║ └┬┬┬┬──────────────────────────────────────────────────────────────────┬┬┬┬┘ ║
║ ║
║ 可用脚本: ║
║ ║
║ ┌───────────────────────────────┐ ║
║ │ ms_pro_cam_wait_for_scrolling │ ║
║ ├───────────────────────────────┴────────────────────────────────────────┐ ║
║ │ 开启:等待直至镜头移动结束
意思是镜头移动结束后,才会执行下一个事件指令
对默认的地图滚动、本脚本中镜头移动的呼出脚本两者都有效. │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌────────────────────────────────────┐ ║
║ │ ms_pro_cam_center_at(x, y, 时间) │ ║
║ ├────────────────────────────────────┴───────────────────────────────────┐ ║
║ │ 镜头中心移动到(x,y)坐标处,时间的单位是帧
║ │ │ ║
║ │ 注意: 同样适用于循环地图. 通常情况下,如果你从地图左上角移动镜头到左下角,
镜头会经过画面中心处. │ ║
║ │ 但如果你的地图是循环地图,镜头会寻找最短的移动路径,不经过画面中心 │ ║
║ │ │ ║
║ │ 例子: 镜头中心移动到(44,44)处,用时6秒 │ ║
║ │ │ ║
║ │ ms_pro_cam_center_at(44, 44, 360) │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌───────────────────────────────────────┐ ║
║ │ ms_pro_cam_center_at_char(id, 时间) │ ║
║ ├───────────────────────────────────────┴────────────────────────────────┐ ║
║ │ 移动到目标处 │ ║
║ │ │ ║
║ │ (*) id = -1 时代表玩家, 0 代表当前事件, 1 或以上代表事件id. │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌──────────────────────────────────────────┐ ║
║ │ ms_pro_cam_focus_on(id, 可取消?, 按键) │ ║
║ ├──────────────────────────────────────────┴─────────────────────────────┐ ║
║ │ 镜头跟随目标 │ ║
║ │ │ ║
║ │ 例子,镜头跟随22号事件: ms_pro_cam_focus_on(22) │ ║
║ │ │ ║
║ │ 镜头跟随玩家: │ ║
║ │ ms_pro_cam_focus_on(-1) │ ║
║ │ │ ║
║ │ (*) "可取消" 替换为 true 或 false,代表能否通过一个按键取消镜头跟随,并
自动将镜头目标跟随回玩家│ ║
║ │ │ ║
║ │ (*) "按键"是取消跟随镜头的按键,仅在"可取消?"设定为true时有效,默认为 :CTRL │ ║
║ │ │ ║
║ │ 默认可用按键: │ ║
║ │ │ ║
║ │ :DOWN :LEFT :RIGHT :UP (方向键) │ ║
║ │ :A :B :C :X :Y :Z :L :R │ ║
║ │ :SHIFT :CTRL :ALT │ ║
║ │ :F5 :F6 :F7 :F8 :F9 │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌─────────────────────────────────────┐ ║
║ │ ms_pro_cam_character_on_screen?(id) │ ║
║ ├─────────────────────────────────────┴──────────────────────────────────┐ ║
║ │ 检查事件是否在画面中. │ ║
║ │ │ ║
║ │ 可以用于分支条件中,例如检查代表小偷的事件是否在画面中,如果不在玩家
抓贼失败这样
当然,id和之前一样,也可以代表玩家. │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌──────────────────────┐ ║
║ │ ms_pro_cam_reset_str │ ║
║ ├──────────────────────┴─────────────────────────────────────────────────┐ ║
║ │ 设定镜头移动的速度为默认值 │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌───────────────────────┐ ║
║ │ ms_pro_cam_str(数值) │ ║
║ ├───────────────────────┴────────────────────────────────────────────────┐ ║
║ │ 设定镜头移动加速度 │ ║
║ │ │ ║
║ │ 数值越小,移动速度越快 (1 为默认速度) │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌──────────────────────────────────────┐ ║
║ │ ms_pro_cam_ignore_player(true/false) │ ║
║ ├──────────────────────────────────────┴─────────────────────────────────┐ ║
║ │ 镜头是否固定在地图上,不跟随玩家移动 │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌────────────────────────┐ ║
║ │ ms_pro_cam_lock_camera │ ║
║ ├────────────────────────┴───────────────────────────────────────────────┐ ║
║ │ 锁定镜头 │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ┌──────────────────────────┐ ║
║ │ ms_pro_cam_unlock_camera │ ║
║ ├──────────────────────────┴─────────────────────────────────────────────┐ ║
║ │ 解锁镜头 │ ║
║ └────────────────────────────────────────────────────────────────────────┘ ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
╠══════════════════════════════════════════════════════════════════════════════╣
║ 3. NOTES. ▼ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ Have fun and enjoy! ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
╠══════════════════════════════════════════════════════════════════════════════╣
║ 4. CONTACT. ▼ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ Keep in touch with us and be the first to know about new releases: ║
║ ║
║ [url]www.rpgmakersource.com[/url] ║
║ [url]www.facebook.com/RPGMakerSource[/url] ║
║ [url]www.twitter.com/RPGMakerSource[/url] ║
║ [url]www.youtube.com/user/RPGMakerSource[/url] ║
║ ║
║ Get involved! Have an idea for a system? Let us know. ║
║ ║
║ Spread the word and help us reach more people so we can continue creating ║
║ awesome resources for you! ║
║ ║
╚══════════════════════════════════════════════════════════════════════════════╝)
=end
#==============================================================================
# ** Maker Systems
#------------------------------------------------------------------------------
# Module for our Systems.
#==============================================================================
module MakerSystems
#============================================================================
# ** Enhanced Camera
#----------------------------------------------------------------------------
# Contains configurable values for the camera systems.
#============================================================================
module EnhancedCamera
#------------------------------------------------------------------------
# * 默认镜头滚动加速度. [OPT]
#------------------------------------------------------------------------
Deceleration_Value = 8
end
end
#==============================================================================
# ** Game_Interpreter
#------------------------------------------------------------------------------
# Added methods to use in Script Call Event Command.
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# * Reset Deceleration Strength. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_reset_str
# Set camera deceleration strength back to default.
$game_map.ms_ecam_str =
MakerSystems::EnhancedCamera::Deceleration_Value.to_f
end
#--------------------------------------------------------------------------
# * Deceleration Strength. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_str(value)
# Set camera deceleration strength.
$game_map.ms_ecam_str = value.to_f
end
#--------------------------------------------------------------------------
# * Ignore Player Toggle. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_ignore_player(value)
# Set ignore player flag.
$game_map.ms_ecam_ignore_player = value
end
#--------------------------------------------------------------------------
# * Lock Camera. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_lock_camera
# Turns on camera lock flag.
$game_map.ms_ecam_locked = true
end
#--------------------------------------------------------------------------
# * Unlock Camera. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_unlock_camera
# Turns off camera lock flag.
$game_map.ms_ecam_locked = false
end
#--------------------------------------------------------------------------
# * Character on Screen? [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_character_on_screen?(id)
# Get character based on provided number (id).
character = get_character(id)
# Inside screen boundaries?
character.screen_x > 0 && character.screen_x < Graphics.width &&
character.screen_y > 0 && character.screen_y < Graphics.height
end
#--------------------------------------------------------------------------
# * Focus on Character. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_focus_on(id, can_cancel = false, key = :CTRL)
# Get character based on provided number (id).
character = get_character(id)
# Special handling if Player is the target.
if character.is_a?(Game_Player)
# Clears special character focus variable.
$game_map.ms_ecam_target = nil
# Turns off ignore player flag.
$game_map.ms_ecam_ignore_player = false
# Moves camera back to player.
$game_map.ms_ecam_center(character.real_x, character.real_y)
else
# Sets camera target to its new target character.
$game_map.ms_ecam_target = character
# Sets cancel focus flag.
$game_map.ms_ecam_cancel = can_cancel
# Sets cancel focus key.
$game_map.ms_ecam_cancel_key = key
end
end
#--------------------------------------------------------------------------
# * Wait for Scrolling. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_wait_for_scrolling
# Yield until scrolling is completed.
Fiber.yield while $game_map.scrolling? || $game_map.ms_ecam_iterations
end
#--------------------------------------------------------------------------
# * Center Camera at Position. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_center_at(x, y, frames)
# Set camera location target.
$game_map.ms_ecam_go_to(x, y, frames)
end
#--------------------------------------------------------------------------
# * Center Camera at Character. [NEW]
#--------------------------------------------------------------------------
def ms_pro_cam_center_at_char(id, frames)
# Get character based on provided number (id).
character = get_character(id)
# Set camera location target.
$game_map.ms_ecam_go_to(character.x, character.y, frames)
end
end
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# Edited update_scroll and initialize.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables. [NEW]
#--------------------------------------------------------------------------
attr_accessor :ms_ecam_target, :ms_ecam_iterations, :ms_ecam_str,
:ms_ecam_ignore_player, :ms_ecam_locked, :ms_ecam_cancel,
:ms_ecam_cancel_key
#--------------------------------------------------------------------------
# * Alias Initialize. [NEW]
#--------------------------------------------------------------------------
alias_method(:ms_ecam_original_initialize, :initialize)
#--------------------------------------------------------------------------
# * Initialize. [MOD]
#--------------------------------------------------------------------------
def initialize
# Original method.
ms_ecam_original_initialize
# Initializes deceleration strength.
@ms_ecam_str = MakerSystems::EnhancedCamera::Deceleration_Value.to_f
end
#--------------------------------------------------------------------------
# * Center Position. [NEW]
#--------------------------------------------------------------------------
def ms_ecam_center(target_real_x, target_real_y, hard = false)
# Target position, centered.
@ms_ecam_real_x = target_real_x - screen_tile_x / 2
@ms_ecam_real_y = target_real_y - screen_tile_y / 2
# Position correction for no horizontally looped maps.
unless loop_horizontal?
# Limit for the X axis.
limit_x = width - screen_tile_x
limit_x = 0 if limit_x < 0
# Keeps target position inside correct boundaries.
@ms_ecam_real_x = 0 if @ms_ecam_real_x < 0
@ms_ecam_real_x = limit_x if @ms_ecam_real_x > limit_x
end
# Position correction for no vertically looped maps.
unless loop_vertical?
# Limit for the Y axis.
limit_y = height - screen_tile_y
limit_y = 0 if limit_y < 0
# Keeps target position inside correct boundaries.
@ms_ecam_real_y = 0 if @ms_ecam_real_y < 0
@ms_ecam_real_y = limit_y if @ms_ecam_real_y > limit_y
end
# Ensures correct target values in case of looping any axis.
@ms_ecam_real_x %= width
@ms_ecam_real_y %= height
# No smooth movement?
if hard
# Sets display position now, without any smooth deceleration effect.
@display_x = @ms_ecam_real_x
@display_y = @ms_ecam_real_y
end
end
#--------------------------------------------------------------------------
# * Prepares Camera Target. [NEW]
#--------------------------------------------------------------------------
def ms_ecam_go_to(target_x, target_y, period = 60.0)
# Prevents execution of any kind of camera movement if locked flag is on.
return if @ms_ecam_locked
# Sets correct target positions.
ms_ecam_center(target_x, target_y)
# Gets correct X distance.
@ms_ecam_x_amplitude = ms_ecam_correct_amplitude(@display_x,
@ms_ecam_real_x, width, loop_horizontal?)
# Gets correct Y distance.
@ms_ecam_y_amplitude = ms_ecam_correct_amplitude(@display_y,
@ms_ecam_real_y, height, loop_vertical?)
# Initializes iteration counter.
@ms_ecam_iterations = 0.0
# Saves the original, starting position.
@ms_ecam_x_original = @display_x
@ms_ecam_y_original = @display_y
# Sets period (time).
@ms_ecam_period = period.to_f
end
#--------------------------------------------------------------------------
# * Correct Amplitude. [NEW]
#--------------------------------------------------------------------------
def ms_ecam_correct_amplitude(current, target, limit, condition)
# Checks if looping in the desired axis.
if condition
# Returns shortest distance, crossing map borders if needed.
if ((target - current) % limit) < ((current - target) % limit)
(target - current) % limit
else
-((current - target) % limit)
end
else
# Returns normal distance.
target - current
end
end
#--------------------------------------------------------------------------
# * Alias Update Scroll. [NEW]
#--------------------------------------------------------------------------
alias_method(:ms_ecam_original_update_scroll, :update_scroll)
#--------------------------------------------------------------------------
# * Update Scroll. [MOD]
#--------------------------------------------------------------------------
def update_scroll
# Prevents execution of any kind of camera movement if locked flag is on.
return if @ms_ecam_locked
# If non player target for camera.
if @ms_ecam_target
# If can be cancelled by player input and the key is triggered.
if @ms_ecam_cancel && Input.trigger?(@ms_ecam_cancel_key)
# Clears target flag.
@ms_ecam_target = nil
# Moves camera back to player.
ms_ecam_center($game_player.real_x, $game_player.real_y)
else
# Centers camera on target.
ms_ecam_center(@ms_ecam_target.real_x, @ms_ecam_target.real_y, false)
end
end
# Iterations pending?
if @ms_ecam_iterations
# Calculates period.
period = (@ms_ecam_iterations / @ms_ecam_period) * 1.57
# Sets new display positions.
@display_x = @ms_ecam_x_original + @ms_ecam_x_amplitude * Math.sin(period)
@display_y = @ms_ecam_y_original + @ms_ecam_y_amplitude * Math.sin(period)
# Ensures correct display values.
@display_x %= $game_map.width
@display_y %= $game_map.height
# If target positions were reached.
if period == 1.57
# Sets target position flag off.
@ms_ecam_iterations = nil
# Updates target positions.
@ms_ecam_real_x = @display_x
@ms_ecam_real_y = @display_y
else
# Updates iteration count.
@ms_ecam_iterations += 1.0
end
else
# Camera being moved by event commands?
if scrolling?
# Target position is actual display position.
@ms_ecam_real_x = @display_x
@ms_ecam_real_y = @display_y
else
# Moves camera. Correct step value with deceleration effect. X Axis.
@display_x += ms_ecam_correct_amplitude(@display_x,
@ms_ecam_real_x, width, loop_horizontal?) / @ms_ecam_str
# Moves camera. Correct step value with deceleration effect. Y Axis.
@display_y += ms_ecam_correct_amplitude(@display_y,
@ms_ecam_real_y, height, loop_vertical?) / @ms_ecam_str
# Keeps map display values inside correct boundaries.
@display_x %= width
@display_y %= height
end
end
# Original method.
ms_ecam_original_update_scroll
end
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# Replaced update_scroll and center.
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# * Update Scroll. [REP]
#--------------------------------------------------------------------------
def update_scroll(last_real_x, last_real_y)
# Check if it is good to go.
unless $game_map.ms_ecam_target || $game_map.ms_ecam_iterations ||
$game_map.ms_ecam_ignore_player || !moving?
# Updates the camera centering.
$game_map.ms_ecam_center(@real_x, @real_y)
end
end
#--------------------------------------------------------------------------
# * Center. [REP]
#--------------------------------------------------------------------------
def center(x, y)
# Don't center if the camera is anchored to its position.
return if $game_map.ms_ecam_locked
# Center camera display position at once.
$game_map.ms_ecam_center(x.to_f, y.to_f, true)
end
end