本帖最后由 RyanBern 于 2016-3-6 09:04 编辑
楼主这种写法是不对的。我给出一个例子,请试着模仿一下。
首先,我们必须确定这个事件生成在哪个地图上。在这里我们假定生成在当前地图上。
然后,最重要的一点,每张地图上的事件都有唯一一个指定的事件ID。这个ID原本是由地图编辑器给定。但是我们新生成的这个事件并不是编辑器指定(但是这个事件的内容要和编辑器中某事件的内容一样),因此我们需要为这个新的事件指定唯一的ID。当然我们可以手动指定,如果嫌麻烦我后面还有自动指定ID的方法。
复制事件不要用直接赋值的办法,我们必须通过调用Game_Event类的构造方法来生成它。生成的时候需要指定RPG::Event事件源。这个事件源被包在目标事件的内部,我们在外面无法获取,所以要更改类成员的读写权限。同样,事件ID这个属性也是不能直接修改,要新建一个方法来更改它。
class Game_Event attr_reader :event def set_id(new_id) @id = new_id end end
class Game_Event
attr_reader :event
def set_id(new_id)
@id = new_id
end
end
另外说一句,不要直接更改x和y属性,Game_Event类有专门的方法来处理事件的移动。$game_map.events是Hash表,不是数组,这点也需要注意。因此楼主的这个地方也有问题。
仅仅更改这个脚本是不够的,我们还需要同步地图的显示。这样做可以生成新的事件,但是无法将新事件显示在屏幕上。地图上所有的精灵对象是存放在Scene_Map里面一个名为@spriteset的变量里面,我们也要将新生成的事件所对应的精灵对象添加到这个对象中。为此我们需要再插入以下脚本:
class Spriteset_Map def add_character(ev) sprite = Sprite_Character.new(@viewport1, ev) @character_sprites << sprite end end class Scene_Map attr_reader :spriteset end
class Spriteset_Map
def add_character(ev)
sprite = Sprite_Character.new(@viewport1, ev)
@character_sprites << sprite
end
end
class Scene_Map
attr_reader :spriteset
end
有了上面的脚本后,我们可以写出复制事件的脚本(复制当前地图的1号事件到当前地图):
# 获取事件 ev = $game_map.events[1] # 事件为空的情况下返回 return if ev.nil? # 利用构造方法生成新事件 new_ev = Game_Event.new($game_map.map_id, ev.event) # 自动获取新事件的ID new_id = ((1..($game_map.events.keys.size+1)).to_a - $game_map.events.keys).min # 设置新事件的ID和坐标 new_ev.set_id(new_id) new_ev.moveto(new_x, new_y) # 将新事件放入地图中 $game_map.events[new_id] = new_ev # 同步地图显示 $scene.spriteset.add_character(new_ev) # 强制地图刷新,保证事件出现 $game_map.need_refresh = true
# 获取事件
ev = $game_map.events[1]
# 事件为空的情况下返回
return if ev.nil?
# 利用构造方法生成新事件
new_ev = Game_Event.new($game_map.map_id, ev.event)
# 自动获取新事件的ID
new_id = ((1..($game_map.events.keys.size+1)).to_a - $game_map.events.keys).min
# 设置新事件的ID和坐标
new_ev.set_id(new_id)
new_ev.moveto(new_x, new_y)
# 将新事件放入地图中
$game_map.events[new_id] = new_ev
# 同步地图显示
$scene.spriteset.add_character(new_ev)
# 强制地图刷新,保证事件出现
$game_map.need_refresh = true
|