已隐退的RM者
视频地址复制
Flash地址复制
Html地址复制
离线看更方便
用或其他应用扫描二维码
自制 RPG MAKER VX的RTP地图制作教程
需要用到的软件有:
Photoshop,截图软件
原视频长度为1小时半,这是加速4倍的教程视频
不喜勿喷,谢谢
广播电视节目制作经营许可证:(沪)字第1248号
网络文化经营许可证:沪网文[6号
信息网络传播视听节目许可证:0910417
互联网ICP备案:沪ICP备号-3
沪ICP证:沪B2-
违法不良信息举报邮箱:
违法不良信息举报***: 转 3RPG Maker VX地图随机气泡对话 Ver1.0 - 死线之蓝 - 博客园
最近刚看完了Ruby的《元编程》,收获颇丰。
想趁着印象深刻的时候多写点东西练练手,于是想到了这么一个功能。
在辉光翼战记中,玩家在迷宫中移动时,角色偶尔会在屏幕下方进行一些小对话。虽然对剧情本身没有什么影响,
但是这个功能不但削弱了在迷宫中移动时的烦躁感,而且还可以加深对人物性格的刻画。
RPG Maker VX的屏幕默认只有544 * 416大小,在冒险中专门取出一块地方来进行小对话会让游戏画面显得更加狭窄,由此选择了使用漂浮气泡对话。
本脚本主要使用了RPG Maker VX的跟随和村人のつぶやき两个脚本,以这两个脚本为基础,设计了一个小型DSL,这两个脚本的内容附在文章最后。
使用方法如下:
story_event "First Event" do
message [-1, 'First Message']
message [0, 'Second Message']
scope [1, 2, 3, 5]
每个小对话使用 story_event来定义,并使用一个字符串对其命名,便于区别其他的小对话
message用来声明一条信息,其中第一个参数表示说话角色,第二个参数表示信息内容。
scope用来声明作用范围,其内容为一个包含了剧情可发生地图的id数组,上例中该剧情可以在map_id为1、2、3、5的地图中发生。
通过提前设置好对话和作用范围,就可以实现玩家在地图移动时的随机对话了。
作为1.0版本,只实现了一个大致上的功能。还有一些设想中的功能没有制作,内容包括:
1. 添加一个run_switch, 内容是一个开关id数组,当run_switch中的所有开关打开时该剧情才可能发生。
2. 添加一个close_switch,其功能和run_switch相反,用来终止一个剧情的发生。
3. 每条message除了可以声明角色和信息内容以外,还可以指定气泡滞留时间,使得句子长的信息滞留更久,句子短的信息消失更快。
4. 可以通过给地图增加特殊声明来修改该地图中随机剧情的出现频度
大概会在后续版本中添加上去。
地图随机剧情脚本
#==============================================================================
通过扩展Kernel的功能实现的小型DSL
由于RMVX的问题,class_eval内的代码是被迫实现的
原版代码如下
Kernel.send :define_method, :story_event do |name, &block|
now_event = event_list[name] = Move_Talking::Story_Event.new(name)
block.call
在RMVX中,由于|name, &block|处会报语法错误,所以变成了现在的丑陋样子。
如果有人知道在RMVX中怎么通过define_method定义方法并可以传递block请告诉我。
#=============================================================================
event_list = {}
#用以储存所有小剧情事件
now_event = nil
#用以构造小剧情事件
#--------------------------------------------------------------------------
# ● 定义story_event方法
#--------------------------------------------------------------------------
Kernel.class_eval('def story_event(name, &block)
event_list = get_event_list
event_list[name] = Move_Talking::Story_Event.new(name)
now_event = event_list[name]
set_now_event(now_event)
block.call
#--------------------------------------------------------------------------
# ● 获取event_list
story_event方法专用
如果可以将story_event改回使用define_method实现,本方法可作废
#--------------------------------------------------------------------------
Kernel.send :define_method, :get_event_list do
return event_list
#--------------------------------------------------------------------------
# ● 设置now_event
story_event方法专用
如果可以将story_event改回使用define_method实现,本方法可作废
#--------------------------------------------------------------------------
Kernel.send :define_method, :set_now_event do |event|
now_event = event
#--------------------------------------------------------------------------
# ● 定义message方法
接收一个数组作为message内容
#--------------------------------------------------------------------------
Kernel.send :define_method, :message do |param|
now_event.msg_data && param
#--------------------------------------------------------------------------
# ● 定义scope方法
接收一个数组作为scope内容
#--------------------------------------------------------------------------
Kernel.send :define_method, :scope do |scope|
now_event.scope = scope
#--------------------------------------------------------------------------
# ● 定义run_switch方法
接收一个数组作为run_switch内容
#--------------------------------------------------------------------------
Kernel.send :define_method, :run_switch do |run_switch|
now_event.run_switch = run_switch
#--------------------------------------------------------------------------
# ● 获取当前地图适用的小剧情
此处只考虑map_id其他操作在scene_map中具体判别
#--------------------------------------------------------------------------
Kernel.send :define_method, :get_story_event do |map_id|
result = []
event_list.each do |key, val|
val.scope.nil?
then result.push val
elsif val.scope.include? map_id then result.push val
return result
#==============================================================================
# ■ Move_Talking
#------------------------------------------------------------------------------
# 移动中对话的主要模块
#==============================================================================
module Move_Talking
TRIGGER_COOLDOWN = 1500
#--------------------------------------------------------------------------
# ●Story_Event
用来装载小对话的类
#--------------------------------------------------------------------------
class Story_Event
attr_accessor :scope
attr_accessor :run_switch
attr_accessor :name
attr_accessor :msg_data
attr_accessor :cooldown
#--------------------------------------------------------------------------
# ● 初始化
#--------------------------------------------------------------------------
def initialize(name)
@name = name
@msg_data = []
@scope = nil
@run_switch = nil
@index = 0
@cooldown = 200
#--------------------------------------------------------------------------
每次显示一条信息
#--------------------------------------------------------------------------
player = @msg_data[@index][0]
message = @msg_data[@index][1].dup
if player == -1
$game_player.message = message
$game_party.characters[player].message = message
@index += 1
#--------------------------------------------------------------------------
# ● 判断是否全部显示完毕
#--------------------------------------------------------------------------
@index == @msg_data.size
#--------------------------------------------------------------------------
将index复位,以便重复播放
#--------------------------------------------------------------------------
@index = 0
#==============================================================================
# ■ Scene_Map
#------------------------------------------------------------------------------
# 处理地图画面的类。
#==============================================================================
class Scene_Map & Scene_Base
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
alias story_event_initialize initialize
def initialize
story_event_initialize
@story_count = 0
@message_count = 0
@story_event = nil
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
alias story_event_update update
def update
@story_count += 1
if @story_count &= 1500 && @story_event.nil?
events = get_story_event($game_map.map_id)
@story_event = events[rand(events.size)]
@story_event.reset
@story_event.run
@message_count = 0
elsif @story_event != nil
@message_count += 1
if @message_count == 200
@story_event.run
@message_count = 0
if @story_event.over?
@story_event = nil
@story_count = 0
story_event_update
地图随机剧情脚本
&村人のつぶやき
#==============================================================================
# ★ RGSS2_村人のつぶやき
# tomoaky (seek.co.jp/)
#==============================================================================
#==============================================================================
# ■ ?定?目
#==============================================================================
module TMRBT
SW_MESSAGE_STOP = 2
# ?能??化スイッチのID
MESSAGE_DURATION = 180
# メッセ?ジの表示??(フレ?ム)
MESSAGE = {}
# おじさんタイプのメッセ?ジリスト
MESSAGE["Test"] = [
'Test message'
#==============================================================================
# ■ コマンド
#==============================================================================
module TMRBT
module Commands
module_function
#--------------------------------------------------------------------------
# ● 指定したIDのイベントにメッセ?ジを?制
#--------------------------------------------------------------------------
def mes(id, text, count = 300)
event = $game_map.interpreter.get_character(id)
if event != nil
event.message = text
event.message_count = count
#--------------------------------------------------------------------------
# ● 指定したIDのイベントの村人タイプを?更
#--------------------------------------------------------------------------
def mes_type(id, type = nil)
return if id & 0
# プレイヤ?には??
event = $game_map.interpreter.get_character(id)
if event != nil
event.murabito = type
class Game_Interpreter
include TMRBT::Commands
#==============================================================================
# ■ Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# ● 公?インスタンス?数
#--------------------------------------------------------------------------
attr_accessor :message
# フキダシメッセ?ジ
attr_accessor :message_count
# メッセ?ジ待?カウント
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias tmrbt_game_character_initialize initialize
def initialize
tmrbt_game_character_initialize
@message = ""
@message_count = 60 + rand(240)
#--------------------------------------------------------------------------
# ○ メッセ?ジを表示できる状?かどうかを返す
#--------------------------------------------------------------------------
def message_can_speak?
return false if @character_name == "" and @tile_id == 0
return false if $game_switches[TMRBT::SW_MESSAGE_STOP]
return true
#==============================================================================
# ■ Game_Event
#==============================================================================
class Game_Event & Game_Character
#--------------------------------------------------------------------------
# ● 公?インスタンス?数
#--------------------------------------------------------------------------
attr_accessor :murabito
# 村人タイプ
#--------------------------------------------------------------------------
# ● オブジェクト初期化
map_id : マップ ID
: イベント (RPG::Event)
#--------------------------------------------------------------------------
alias tmrbt_game_event_initialize initialize
def initialize(map_id, event)
tmrbt_game_event_initialize(map_id, event)
@murabito = event.name =~ /&村人:(\S+?)&/i ? $1 : nil
# 村人判定
#--------------------------------------------------------------------------
# ● フレ?ム更新
#--------------------------------------------------------------------------
alias tmrbt_game_event_update update
def update
tmrbt_game_event_update
if @murabito != nil
if @message_count & 0
@message_count -= 1
if @message_count == 0
if message_can_speak?
n = TMRBT::MESSAGE[@murabito].size
@message = TMRBT::MESSAGE[@murabito][rand(n)].clone
@message_count = 270 + rand(300)
#--------------------------------------------------------------------------
# ○ 指定したIDのイベントにメッセ?ジを?制(カスタム移?用)
#--------------------------------------------------------------------------
def mes(id, text, count = 300)
TMRBT::Commands.mes(id == 0 ? @id : id, text, count)
#--------------------------------------------------------------------------
# ○ 指定したIDのイベントの村人タイプを?更(カスタム移?用)
#--------------------------------------------------------------------------
def mes_type(id, type = nil)
TMRBT::Commands.mes_type(id == 0 ? @id : id, type)
#==============================================================================
# ■ Sprite_Character
#==============================================================================
class Sprite_Character & Sprite_Base
@@bitmap_murawin = Cache.system("murawin")
@@windowskin = Cache.system("Window")
#--------------------------------------------------------------------------
# ● オブジェクト初期化
: ビュ?ポ?ト
character : キャラクタ? (Game_Character)
#--------------------------------------------------------------------------
alias tmrbt_sprite_character_initialize initialize
def initialize(viewport, character = nil)
@message_duration = 0
tmrbt_sprite_character_initialize(viewport, character)
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
alias tmrbt_sprite_character_dispose dispose
def dispose
dispose_message
tmrbt_sprite_character_dispose
#--------------------------------------------------------------------------
# ● フレ?ム更新
#--------------------------------------------------------------------------
alias tmrbt_sprite_character_update update
def update
tmrbt_sprite_character_update
update_message
if @character.message != ""
@message = @character.message
start_message
@character.message = ""
#--------------------------------------------------------------------------
# ○ 文字色取得
n : 文字色番号 (0~31)
#--------------------------------------------------------------------------
def text_color(n)
x = 64 + (n % 8) * 8
y = 96 + (n / 8) * 8
return @@windowskin.get_pixel(x, y)
#--------------------------------------------------------------------------
# ○ 特殊文字の??
#--------------------------------------------------------------------------
def convert_special_characters
if @message == nil
@message = ""
@message.gsub!(/\\L/)
{ "\x00" }
@message.gsub!(/\\V\[([0-9]+)\]/i) { $game_variables[$1.to_i] }
@message.gsub!(/\\N\[([0-9]+)\]/i) { $game_actors[$1.to_i].name }
@message.gsub!(/\\C\[([0-9]+)\]/i) { "\x01[#{$1}]" }
@message.gsub!(/\\\\/)
#--------------------------------------------------------------------------
# ○ フキダシメッセ?ジ表示の?始
#--------------------------------------------------------------------------
def start_message
dispose_message
convert_special_characters
@message_duration = TMRBT::MESSAGE_DURATION
bitmap = Bitmap.new(160, 160)
bitmap.font.name = "Verdana"
bitmap.font.size = 14
contents_x = 4
contents_y = 0
c = @message.slice!(/./m)
# 次の文字を取得
# 描画すべき文字がなければ?了
when "\x00"
w = contents_x if w & contents_x
contents_x = 4
contents_y += 16
when "\x01"
(文字色?更)
@message.sub!(/\[([0-9]+)\]/, "")
bitmap.font.color = text_color($1.to_i)
bitmap.font.color = Color.new(255, 255, 255)
bitmap.draw_edge_text(contents_x, contents_y, 40, 16, c, 0, Color.new(94, 24, 24))
c_width = bitmap.text_size(c).width
contents_x += c_width
if contents_x &= 140
# 右端にきていれば改行
w = contents_x if w & contents_x
contents_x = 4
contents_y += 16
h = contents_y + (contents_x == 4 ? 0 : 16)
w = (w & contents_x ? contents_x + 4 : w + 4)
@message_sprite = ::Sprite.new(viewport)
@message_sprite.ox = w / 2
@message_sprite.oy = h + 4
@message_sprite.bitmap = Bitmap.new(w, h + 8)
rect = Rect.new(0, 0, 8, 8)
@message_sprite.bitmap.blt(0, 0, @@bitmap_murawin, rect, 192)
rect.x += 8
@message_sprite.bitmap.blt(w - 8, 0, @@bitmap_murawin, rect, 192)
rect.y += 8
@message_sprite.bitmap.blt(w - 8, h - 8, @@bitmap_murawin, rect, 192)
rect.x -= 8
@message_sprite.bitmap.blt(0, h - 8, @@bitmap_murawin, rect, 192)
rect.set(16, 0, 8, 8)
@message_sprite.bitmap.blt(@message_sprite.ox - 4, h,
@@bitmap_murawin, rect, 192)
color = @@bitmap_murawin.get_pixel(8, 8)
color.alpha = 192
@message_sprite.bitmap.fill_rect(8, 0, w - 16, h, color)
@message_sprite.bitmap.fill_rect(0, 8, 8, h - 16, color)
@message_sprite.bitmap.fill_rect(w - 8, 8, 8, h - 16, color)
@message_sprite.bitmap.blt(0, 0, bitmap, bitmap.rect)
bitmap.dispose
update_message
#--------------------------------------------------------------------------
# ○ フキダシメッセ?ジの更新
#--------------------------------------------------------------------------
def update_message
if @message_duration & 0
@message_duration -= 1
if @message_duration == 0 or not @character.message_can_speak?
@message_duration = 0
dispose_message
@message_sprite.x = x
@message_sprite.y = y - height
@message_sprite.z = z + 200
@message_sprite.opacity = @message_duration * 24
#--------------------------------------------------------------------------
# ○ フキダシメッセ?ジの解放
#--------------------------------------------------------------------------
def dispose_message
if @message_sprite != nil
@message_sprite.dispose
@message_sprite = nil
村人のつぶやきRPG maker VX ACE 地图教程
RPG maker VX ACE 地图教程
把视频贴到Blog或BBS
该播客的其他视频