Project1
标题:
脚本中的动态是如何实现的?
[打印本页]
作者:
小湖
时间:
2010-12-6 13:54
标题:
脚本中的动态是如何实现的?
本帖最后由 小湖 于 2010-12-6 20:42 编辑
例如给一个窗口类制作一个窗口移动的方法,比如每隔1帧窗口的x+1,现在我的方法是把窗口定义成全局对象,然后用公共事件做,可是扩展性太差了……想知道脚本中是如何实现的?
作者:
白鬼
时间:
2010-12-6 15:04
我记得有一个脚本,是模仿 魔兽世界 的效果的窗口类脚本。
具体的效果有点忘记了,如果没记错的话,窗口被激活后应该是动态拼组起来的,还伴有音效(好吧,这个无关紧要)
# ————————————————————————————————————
# 本脚本来自www.66rpg.com,仿魔兽式窗口。转载请保留此信息
# ————————————————————————————————————
#==============================================================================
# ■ Warcraftization
#------------------------------------------------------------------------------
# 处理魔兽式菜单切换的模块。
#==============================================================================
module Warcraftization
Dispose_effect = "Audio/SE/024-Door01" # 菜单切换时音效
Ini_efect = "Audio/SE/029-Door06" # 切换结束时音效
# 窗口移动的速度:反比,取整数,范围1-12,1最快,12最慢
Speed = 7 # 窗口移动的速度
Elasticity = true # 窗口有无弹性
#############################################################################
#############################################################################
# 处理速度的函数 (为了让直接调用 $scene = XXX.new 也生效,故每个Scene都调用)
def speed
# 速度处理 (因为像素不可活算小数(分数),所以只能取一些公约数)
# (存档处因为数字比较特殊,所以这里的速度不影响它
# 有兴趣可以自己在下面的Scene_File调)
case Speed
when 1;$speed = 1
when 2;$speed = 2
when 3;$speed = 4
when 4;$speed = 5
when 5;$speed = 8
when 6;$speed = 10
when 7;$speed = 16
when 8;$speed = 20
when 9;$speed = 32
when 10;$speed = 40
when 11;$speed = 80
when 12;$speed = 160
end
end
# 弹力处理
def elasticity (object)
if Elasticity then for i in 0 .. 5
object.y -= i * 2
Graphics.update
end;for i in 0 .. 5
object.y += i * 2
Graphics.update
end;for i in 0 .. 3
object.y -= i * 2
Graphics.update
end;for i in 0 .. 3
object.y += i * 2
Graphics.update
end;for i in 0 .. 1
object.y -= i * 2
Graphics.update
end;for i in 0 .. 1
object.y += i * 2
Graphics.update
end
end
end
end
#==============================================================================
# ■ Scene_Menu
#------------------------------------------------------------------------------
# 处理菜单画面的类。
#==============================================================================
class Scene_Menu
include Warcraftization
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
@spriteset = Spriteset_Map.new
# 生成命令窗口
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "人物状态"
s5 = "存档"
s6 = "结束游戏"
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])
@command_window.index = @menu_index
@command_window.x = -160
# 同伴人数为 0 的情况下
if $game_party.actors.size == 0
# 物品、特技、装备、状态无效化
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# 禁止存档的情况下
if $game_system.save_disabled
# 存档无效
@command_window.disable_item(4)
end
# 生成游戏时间窗口
@playtime_window = Window_PlayTime.new
@playtime_window.x = -160
@playtime_window.y = 224
# 生成步数窗口
@steps_window = Window_Steps.new
@steps_window.x = -160
@steps_window.y = 320
# 生成金钱窗口
@gold_window = Window_Gold.new
@gold_window.x = -160
@gold_window.y = 416
# 生成状态窗口
@status_window = Window_MenuStatus.new
@status_window.x = 640
@status_window.y = 0
@command_window.back_opacity = 180
@playtime_window.back_opacity = 180
@steps_window.back_opacity = 180
@gold_window.back_opacity = 180
@status_window.back_opacity = 180
# 执行过渡
Graphics.transition
for i in 1 .. $speed
@command_window.x += 160 / $speed
@playtime_window.x += 160 / $speed
@steps_window.x += 160 / $speed
@gold_window.x += 160 / $speed
@status_window.x -= 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果切换画面就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@command_window.x -= 160 / $speed
@playtime_window.x -= 160 / $speed
@steps_window.x -= 160 / $speed
@gold_window.x -= 160 / $speed
@status_window.x += 480 / $speed
Graphics.update
end
# 释放活动块
# 准备过渡
Graphics.freeze
# 释放窗口
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
end
end
#==============================================================================
# ■ Scene_Item
#------------------------------------------------------------------------------
# 处理物品画面的类。
#==============================================================================
class Scene_Item
include Warcraftization
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
@spriteset = Spriteset_Map.new
# 生成帮助窗口、物品窗口
@help_window = Window_Help.new
@help_window.y = -64
@help_window.back_opacity = 180
@item_window = Window_Item.new
@item_window.y = 480
@item_window.back_opacity = 180
# 关联帮助窗口
@item_window.help_window = @help_window
# 生成目标窗口 (设置为不可见?不活动)
@target_window = Window_Target.new
@target_window.y = -480
@target_window.visible = false
@target_window.active = false
# 执行过渡
Graphics.transition
for i in 1 .. $speed
@help_window.y += 64 / $speed
@item_window.y -= 418 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果画面切换就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@help_window.y -= 64 / $speed
@item_window.y += 418 / $speed
@target_window.y -= 480 / $speed
Graphics.update
end
# 装备过渡
Graphics.freeze
# 释放窗口
@help_window.dispose
@item_window.dispose
@target_window.dispose
end
#--------------------------------------------------------------------------
# ● 刷新画面 (物品窗口被激活的情况下)
#--------------------------------------------------------------------------
def update_item
# 按下 B 键的情况下
if Input.trigger?(Input::B)
# 演奏取消 SE
$game_system.se_play($data_system.cancel_se)
# 切换到菜单画面
$scene = Scene_Menu.new(0)
return
end
# 按下 C 键的情况下
if Input.trigger?(Input::C)
# 获取物品窗口当前选中的物品数据
@item = @item_window.item
# 不使用物品的情况下
unless @item.is_a?(RPG::Item)
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
return
end
# 不能使用的情况下
unless $game_party.item_can_use?(@item.id)
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
return
end
# 演奏确定 SE
$game_system.se_play($data_system.decision_se)
# 效果范围是我方的情况下
if @item.scope >= 3
# 激活目标窗口
@item_window.active = false
@target_window.x = (@item_window.index + 1) % 2 * 304
@target_window.visible = true
# 设置效果范围 (单体/全体) 的对应光标位置
if @item.scope == 4 || @item.scope == 6
@target_window.index = -1
else
@target_window.index = 0
end
for i in 1 .. $speed
@target_window.y += 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@target_window)
@target_window.active = true
# 效果在我方以外的情况下
else
# 公共事件 ID 有效的情况下
if @item.common_event_id > 0
# 预约调用公共事件
$game_temp.common_event_id = @item.common_event_id
# 演奏物品使用时的 SE
$game_system.se_play(@item.menu_se)
# 消耗品的情况下
if @item.consumable
# 使用的物品数减 1
$game_party.lose_item(@item.id, 1)
# 再描绘物品窗口的项目
@item_window.draw_item(@item_window.index)
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@help_window.y -= 64 / $speed
@item_window.y += 418 / $speed
Graphics.update
end
# 切换到地图画面
$scene = Scene_Map.new
return
end
end
return
end
end
#--------------------------------------------------------------------------
# ● 刷新画面 (目标窗口被激活的情况下)
#--------------------------------------------------------------------------
def update_target
# 按下 B 键的情况下
if Input.trigger?(Input::B)
# 演奏取消 SE
$game_system.se_play($data_system.cancel_se)
# 由于物品用完而不能使用的场合
unless $game_party.item_can_use?(@item.id)
# 再次生成物品窗口的内容
@item_window.refresh
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@target_window.y -= 480 / $speed
Graphics.update
end
# 删除目标窗口
@item_window.active = true
@target_window.visible = false
@target_window.active = false
return
end
# 按下 C 键的情况下
if Input.trigger?(Input::C)
# 如果物品用完的情况下
if $game_party.item_number(@item.id) == 0
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
return
end
# 目标是全体的情况下
if @target_window.index == -1
# 对同伴全体应用物品使用效果
used = false
for i in $game_party.actors
used |= i.item_effect(@item)
end
end
# 目标是单体的情况下
if @target_window.index >= 0
# 对目标角色应用物品的使用效果
target = $game_party.actors[@target_window.index]
used = target.item_effect(@item)
end
# 使用物品的情况下
if used
# 演奏物品使用时的 SE
$game_system.se_play(@item.menu_se)
# 消耗品的情况下
if @item.consumable
# 使用的物品数减 1
$game_party.lose_item(@item.id, 1)
# 再描绘物品窗口的项目
@item_window.draw_item(@item_window.index)
end
# 再生成目标窗口的内容
@target_window.refresh
# 全灭的情况下
if $game_party.all_dead?
# 切换到游戏结束画面
$scene = Scene_Gameover.new
return
end
# 公共事件 ID 有效的情况下
if @item.common_event_id > 0
# 预约调用公共事件
$game_temp.common_event_id = @item.common_event_id
# 切换到地图画面
$scene = Scene_Map.new
return
end
end
# 无法使用物品的情况下
unless used
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
end
return
end
end
end
#==============================================================================
# ■ Scene_Skill
#------------------------------------------------------------------------------
# 处理特技画面的类。
#==============================================================================
class Scene_Skill
include Warcraftization
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
# 获取角色
@actor = $game_party.actors[@actor_index]
# 生成帮助窗口、状态窗口、特技窗口
@help_window = Window_Help.new
@help_window.y = -64
@status_window = Window_SkillStatus.new(@actor)
@status_window.y = - 64
@skill_window = Window_Skill.new(@actor)
@skill_window.y = -352
# 关联帮助窗口
@skill_window.help_window = @help_window
# 生成目标窗口 (设置为不可见?不活动)
@target_window = Window_Target.new
@target_window.y = -480
@target_window.visible = false
@target_window.active = false
# 执行过渡
Graphics.transition
for i in 1 .. $speed
@help_window.y += 64 / $speed
@status_window.y += 128 / $speed
@skill_window.y += 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@skill_window)
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果画面切换的话就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@help_window.y -= 64 / $speed
@status_window.y -= 128 / $speed
@skill_window.y -= 480 / $speed
@target_window.y -= 480 / $speed
Graphics.update
end
# 准备过渡
Graphics.freeze
# 释放窗口
@help_window.dispose
@status_window.dispose
@skill_window.dispose
@target_window.dispose
end
#--------------------------------------------------------------------------
# ● 刷新画面 (特技窗口被激活的情况下)
#--------------------------------------------------------------------------
def update_skill
# 按下 B 键的情况下
if Input.trigger?(Input::B)
# 演奏取消 SE
$game_system.se_play($data_system.cancel_se)
# 切换到菜单画面
$scene = Scene_Menu.new(1)
return
end
# 按下 C 键的情况下
if Input.trigger?(Input::C)
# 获取特技窗口现在选择的特技的数据
@skill = @skill_window.skill
# 不能使用的情况下
if @skill == nil or not @actor.skill_can_use?(@skill.id)
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
return
end
# 演奏确定 SE
$game_system.se_play($data_system.decision_se)
# 效果范围是我方的情况下
if @skill.scope >= 3
# 激活目标窗口
@skill_window.active = false
@target_window.x = (@skill_window.index + 1) % 2 * 304
@target_window.visible = true
# 设置效果范围 (单体/全体) 的对应光标位置
if @skill.scope == 4 || @skill.scope == 6
@target_window.index = -1
elsif @skill.scope == 7
@target_window.index = @actor_index - 10
else
@target_window.index = 0
end
for i in 1 .. $speed
@target_window.y += 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@target_window)
@target_window.active = true
# 效果在我方以外的情况下
else
# 公共事件 ID 有效的情况下
if @skill.common_event_id > 0
# 预约调用公共事件
$game_temp.common_event_id = @skill.common_event_id
# 演奏特技使用时的 SE
$game_system.se_play(@skill.menu_se)
# 消耗 SP
@actor.sp -= @skill.sp_cost
# 再生成各窗口的内容
@status_window.refresh
@skill_window.refresh
@target_window.refresh
# 切换到地图画面
$scene = Scene_Map.new
return
end
end
return
end
# 按下 R 键的情况下
if Input.trigger?(Input::R)
# 演奏光标 SE
$game_system.se_play($data_system.cursor_se)
# 移至下一位角色
@actor_index += 1
@actor_index %= $game_party.actors.size
# 切换到别的特技画面
$scene = Scene_Skill.new(@actor_index)
return
end
# 按下 L 键的情况下
if Input.trigger?(Input::L)
# 演奏光标 SE
$game_system.se_play($data_system.cursor_se)
# 移至上一位角色
@actor_index += $game_party.actors.size - 1
@actor_index %= $game_party.actors.size
# 切换到别的特技画面
$scene = Scene_Skill.new(@actor_index)
return
end
end
#--------------------------------------------------------------------------
# ● 刷新画面 (目标窗口被激活的情况下)
#--------------------------------------------------------------------------
def update_target
# 按下 B 键的情况下
if Input.trigger?(Input::B)
# 演奏取消 SE
$game_system.se_play($data_system.cancel_se)
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@target_window.y -= 480 / $speed
Graphics.update
end
# 删除目标窗口
@skill_window.active = true
@target_window.visible = false
@target_window.active = false
return
end
# 按下 C 键的情况下
if Input.trigger?(Input::C)
# 因为 SP 不足而无法使用的情况下
unless @actor.skill_can_use?(@skill.id)
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
return
end
# 目标是全体的情况下
if @target_window.index == -1
# 对同伴全体应用特技使用效果
used = false
for i in $game_party.actors
used |= i.skill_effect(@actor, @skill)
end
end
# 目标是使用者的情况下
if @target_window.index <= -2
# 对目标角色应用特技的使用效果
target = $game_party.actors[@target_window.index + 10]
used = target.skill_effect(@actor, @skill)
end
# 目标是单体的情况下
if @target_window.index >= 0
# 对目标角色应用特技的使用效果
target = $game_party.actors[@target_window.index]
used = target.skill_effect(@actor, @skill)
end
# 使用特技的情况下
if used
# 演奏特技使用时的 SE
$game_system.se_play(@skill.menu_se)
# 消耗 SP
@actor.sp -= @skill.sp_cost
# 再生成各窗口内容
@status_window.refresh
@skill_window.refresh
@target_window.refresh
# 全灭的情况下
if $game_party.all_dead?
# 切换到游戏结束画面
$scene = Scene_Gameover.new
return
end
# 公共事件 ID 有效的情况下
if @skill.common_event_id > 0
# 预约调用公共事件
$game_temp.common_event_id = @skill.common_event_id
# 切换到地图画面
$scene = Scene_Map.new
return
end
end
# 无法使用特技的情况下
unless used
# 演奏冻结 SE
$game_system.se_play($data_system.buzzer_se)
end
return
end
end
end
#==============================================================================
# ■ Scene_Equip
#------------------------------------------------------------------------------
# 处理装备画面的类。
#==============================================================================
class Scene_Equip
include Warcraftization
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
# 获取角色
@actor = $game_party.actors[@actor_index]
# 生成窗口
@help_window = Window_Help.new
@help_window.y = -64
@left_window = Window_EquipLeft.new(@actor)
@left_window.y = -192
@right_window = Window_EquipRight.new(@actor)
@right_window.y = -192
@item_window1 = Window_EquipItem.new(@actor, 0)
@item_window1.y = -224
@item_window2 = Window_EquipItem.new(@actor, 1)
@item_window2.y = -224
@item_window3 = Window_EquipItem.new(@actor, 2)
@item_window3.y = -224
@item_window4 = Window_EquipItem.new(@actor, 3)
@item_window4.y = -224
@item_window5 = Window_EquipItem.new(@actor, 4)
@item_window5.y = -224
# 关联帮助窗口
@right_window.help_window = @help_window
@item_window1.help_window = @help_window
@item_window2.help_window = @help_window
@item_window3.help_window = @help_window
@item_window4.help_window = @help_window
@item_window5.help_window = @help_window
# 设置光标位置
@right_window.index = @equip_index
refresh
# 执行过渡
Graphics.transition
for i in 1 .. $speed
@help_window.y += 64 / $speed
@left_window.y += 256 / $speed
@right_window.y += 256 / $speed
@item_window1.y += 480 / $speed
@item_window2.y += 480 / $speed
@item_window3.y += 480 / $speed
@item_window4.y += 480 / $speed
@item_window5.y += 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@item_window)
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果画面切换的话的就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@help_window.y -= 64 / $speed
@left_window.y -= 256 / $speed
@right_window.y -= 256 / $speed
@item_window1.y -= 480 / $speed
@item_window2.y -= 480 / $speed
@item_window3.y -= 480 / $speed
@item_window4.y -= 480 / $speed
@item_window5.y -= 480 / $speed
Graphics.update
end
# 准备过渡
Graphics.freeze
# 释放窗口
@help_window.dispose
@left_window.dispose
@right_window.dispose
@item_window1.dispose
@item_window2.dispose
@item_window3.dispose
@item_window4.dispose
@item_window5.dispose
end
end
#==============================================================================
# ■ Scene_Status
#------------------------------------------------------------------------------
# 处理状态画面的类。
#==============================================================================
class Scene_Status
include Warcraftization
#--------------------------------------------------------------------------
# ● 初始化对像
# actor_index : 角色索引
#--------------------------------------------------------------------------
def initialize(actor_index = 0, equip_index = 0)
@actor_index = actor_index
end
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
# 获取角色
@actor = $game_party.actors[@actor_index]
# 生成状态窗口
@status_window = Window_Status.new(@actor)
@status_window.y = -480
# 执行过渡
Graphics.transition
for i in 1 .. $speed
@status_window.y += 480 / $speed
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@status_window)
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果画面被切换的话就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. $speed
@status_window.y -= 480 / $speed
Graphics.update
end
# 准备过渡
Graphics.freeze
# 释放窗口
@status_window.dispose
end
end
#==============================================================================
# ■ Scene_File
#------------------------------------------------------------------------------
# 存档画面及读档画面的超级类。
#==============================================================================
class Scene_File
include Warcraftization
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
speed
# 生成帮助窗口
@help_window = Window_Help.new
@help_window.y = -64
@help_window.set_text(@help_text)
# 生成存档文件查
@savefile_windows = []
for i in 0..3
@savefile_windows.push(Window_SaveFile.new(i, make_filename(i)))
@savefile_windows[i].y = -104
end
# 选择最后操作的文件
@file_index = $game_temp.last_file_index
@savefile_windows[@file_index].selected = true
# 执行过渡
Graphics.transition
for i in 1 .. 8
@help_window.y += 8
@savefile_windows[0].y += 21
@savefile_windows[1].y += 34
@savefile_windows[2].y += 47
@savefile_windows[3].y += 60
Graphics.update
end
Audio.se_play(Ini_efect, 100, 0)
elasticity (@savefile_windows[@file_index])
# 主循环
loop do
# 刷新游戏画面
Graphics.update
# 刷新输入信息
Input.update
# 刷新画面
update
# 如果画面被切换的话就中断循环
if $scene != self
break
end
end
Audio.se_play(Dispose_effect, 100, 100)
for i in 1 .. 8
@help_window.y -= 8
@savefile_windows[0].y -= 21
@savefile_windows[1].y -= 34
@savefile_windows[2].y -= 47
@savefile_windows[3].y -= 60
Graphics.update
end
# 准备过渡
Graphics.freeze
# 释放窗口
@help_window.dispose
for i in @savefile_windows
i.dispose
end
end
end
复制代码
请高手慢慢研究
作者:
禾西
时间:
2010-12-6 16:11
把窗口移動寫成方法
作者:
苏小脉
时间:
2010-12-6 21:22
沙发楼那个是我 N 年前写的处女脚本,献丑了……
总之就是:
更新窗口坐标
调用 Graphics.update
循环以上
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1