Project1

标题: 事件加脚本:随机传送卷轴 [打印本页]

作者: timiesea    时间: 2013-12-24 22:16
标题: 事件加脚本:随机传送卷轴
很久没有发布自己探索《RMVA》的成果了,今天来点不太一样的,就是脚本。

作为事件党的我,对脚本是非常抵触的,我搞这个东西也是硬着头皮搞下去的,好歹也有了成果。突然间我发现,原来脚本是多么美好啊!这个这个。。。不扯了!开始正文。

假设游戏里需要一种物品:随机传送卷轴。它的作用是在非战斗状态下使用可以传送到该地图的随机一个地方。

要实现卷轴的功能,有以下几个要点:
1.一定不能在战斗中使用,除非是纯事件战斗或者是直接在地图上战斗的那一种游戏。
2.一定要保证坐标的随机性,所以不能预定义。
3.玩家使用该卷轴时,所处的地图编号和ID并不固定,所以不能预定义,除非游戏设定只有某些地图可以使用。
4.玩家在使用卷轴时是否乘船或者飞艇并不固定,除非游戏根本就没有船或者飞艇。
5.传送的目的地必须是可以通行的。
6.传送的目的地不能是类似于森林或者墙壁之类的地形。

基于以上要点,要实现随机传送卷轴的功能只能用脚本了。没关系,我会讲解得非常详细,做到即使是新人也一看就会。

忘了说了,在看这篇大论前,请确保有《RMVA》和对应的中文帮助文档,论坛均有提供下载。

好!开始吧。

一、由于RUBY以类为中心,所以在编写脚本时要新建一个类。类名随意。在本例中,新建的类如下:
RUBY 代码复制
  1. class Game_Others
  2. end


二、定义初始化方法(这个步骤貌似可以省去,但为防以后要用,还是写上为好),方法名不能随便乱写,如下:
RUBY 代码复制
  1. def initialize
  2.     p "初始化完成";
  3. end

注:脚本中的打印只是为了在测试中让我们知道这个类被实例化了,在完成游戏时可以将其删除。

三、编写功能方法。这个步骤非常重要。嗯。我把思想告诉大家:
首先,要获取地图的最大宽度和最大高度,用来设置随机坐标的范围,防止坐标溢出或不够。
然后,定义一个布尔变量并且初始化为false,这个布尔变量用来判定目的地是否可以通行。
接下来是循环,本例中采用while循环,条件自然是当布尔变量为false。
·在循环中,先随机取一个坐标,然后分别计算4个方向的通行性,只要有一个方向可以通行的,那么该坐标的区域就是可以通行的。
·还没完,再取该坐标的地形标识,如果等于某一个数(本例中为1),那么表示该坐标位于类似于森林里或者墙上的区域,自然也是不行的,视为不可通行。在《RMVA》中,这些区域都是可以通行的,有BUG。
只有在找到合适的坐标才能跳出循环。最后,执行传送。坐标就是正确的坐标,面向的话可以预定义(本例采用临时变量控制朝向,稍候讲解)。
脚本如下:
RUBY 代码复制
  1. #随机传送卷轴的功能
  2. def Random_Send
  3.     maxX = $game_map.width;#获取当前地图的最大宽度
  4.     maxY = $game_map.height;#获取当前地图的最大高度
  5.     x = 0;#初始化一个整数变量为0,用来表示传送目的地的x坐标
  6.     y = 0;#初始化一个整数变量为0,用来表示传送目的地的y坐标
  7.     flag = false;#初始化一个布尔变量为false,用来表示传送目的地是否可以通行
  8.     while (!flag)#如果传送目的地不可通行则循环执行
  9.       x = rand(maxX) + 1;#随机设置当前地图的X坐标
  10.       y = rand(maxY) + 1;#随机设置当前地图的Y坐标
  11.       flag2 = $game_player.map_passable?(x, y, 2);#判断在2方向是否可以通行
  12.       flag4 = $game_player.map_passable?(x, y, 4);#判断在4方向是否可以通行
  13.       flag6 = $game_player.map_passable?(x, y, 6);#判断在6方向是否可以通行
  14.       flag8 = $game_player.map_passable?(x, y, 8);#判断在8方向是否可以通行
  15.       #只要4个方向中其中一个方向可以通行那么就可以通行
  16.       if (flag2 or flag4 or flag6 or flag8)
  17.         flag = true;
  18.       end
  19.       #如果当前坐标处于地形标志为1的图块里,则设置为不可通行
  20.       if ($game_map.terrain_tag(x, y) == 1)
  21.         flag = false;
  22.       end
  23.     end
  24.     #预定传送位置,准备开始传送
  25.     $game_player.reserve_transfer($game_map.map_id, x, y, $game_variables[1]);#方向采用第一号临时变量的值,稍候讲解
  26.     $game_player.perform_transfer;#进行传送
  27. end


四、给新建的类定义一个全局变量名,并在游戏开始的时候进行初始化。在本例中,该变量名是$game_others并且在DataManager模块的create_game_objects方法进行初始化,如下所示:
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 生成各种游戏对象
  3.   #--------------------------------------------------------------------------
  4.   def self.create_game_objects
  5.     $game_temp          = Game_Temp.new
  6.     $game_system        = Game_System.new
  7.     $game_timer         = Game_Timer.new
  8.     $game_message       = Game_Message.new
  9.     $game_switches      = Game_Switches.new
  10.     $game_variables     = Game_Variables.new
  11.     $game_self_switches = Game_SelfSwitches.new
  12.     $game_actors        = Game_Actors.new
  13.     $game_party         = Game_Party.new
  14.     $game_troop         = Game_Troop.new
  15.     $game_map           = Game_Map.new
  16.     $game_player        = Game_Player.new
  17.     $game_others        = Game_Others.new#生成全局变量。
  18.   end


五、新建一个公共事件,核心的事件指令只有一个:脚本:$game_others.Random_Send。当然,你也可以进行完善。在本例中,公共事件如下图所示:

注:在第一行中,用第一号变量来记录当前玩家的朝向,以便保证在传送后保持朝向不变。在第三步骤的脚本中就有用到。

六、新建一个物品,其核心的设置是:无目标,仅菜单下使用,使用效果:公共事件,其余随意。在本例中,该物品设置如下:


七、设置地形标志。将有用到的墙壁类,森林类的地形标志设置成第三步骤对应的数字。在本例中,这些地形的标志为1,如下图所示:



注:
1.一定要将所有使用到的森林类和墙壁的地形标志都设置好,出现遗漏会有BUG。
2.不可通行的装饰物无需设置,本身就是不可通行的。

八、脚本。将这些脚本复制并且插入到Main前。请注意:DataManager模块中的create_game_objects方法可能会和其他脚本冲突。

RUBY 代码复制
  1. module DataManager
  2.   #--------------------------------------------------------------------------
  3.   # ● 生成各种游戏对象
  4.   #--------------------------------------------------------------------------
  5.   def self.create_game_objects
  6.     $game_temp          = Game_Temp.new
  7.     $game_system        = Game_System.new
  8.     $game_timer         = Game_Timer.new
  9.     $game_message       = Game_Message.new
  10.     $game_switches      = Game_Switches.new
  11.     $game_variables     = Game_Variables.new
  12.     $game_self_switches = Game_SelfSwitches.new
  13.     $game_actors        = Game_Actors.new
  14.     $game_party         = Game_Party.new
  15.     $game_troop         = Game_Troop.new
  16.     $game_map           = Game_Map.new
  17.     $game_player        = Game_Player.new
  18.     $game_others        = Game_Others.new#生成游戏对象
  19.   end
  20. end
  21. class Game_Others
  22.   #进行各种各样的初始化,主要用来初始化永久变量。临时变量在各自的方法中初始化。
  23.   def initialize
  24.     p "初始化完成";
  25.   end
  26.  
  27.   #随机传送卷轴的功能
  28.   def Random_Send
  29.     maxX = $game_map.width;#获取当前地图的最大宽度
  30.     maxY = $game_map.height;#获取当前地图的最大高度
  31.     x = 0;#初始化一个整数变量为0,用来表示传送目的地的x坐标
  32.     y = 0;#初始化一个整数变量为0,用来表示传送目的地的y坐标
  33.     flag = false;#初始化一个布尔变量为false,用来表示传送目的地是否可以通行
  34.     while (!flag)#如果传送目的地不可通行则循环执行
  35.       x = rand(maxX) + 1;#随机设置当前地图的X坐标
  36.       y = rand(maxY) + 1;#随机设置当前地图的Y坐标
  37.       flag2 = $game_player.map_passable?(x, y, 2);#判断在2方向是否可以通行
  38.       flag4 = $game_player.map_passable?(x, y, 4);#判断在4方向是否可以通行
  39.       flag6 = $game_player.map_passable?(x, y, 6);#判断在6方向是否可以通行
  40.       flag8 = $game_player.map_passable?(x, y, 8);#判断在8方向是否可以通行
  41.       #只要4个方向中其中一个方向可以通行那么就可以通行
  42.       if (flag2 or flag4 or flag6 or flag8)
  43.         flag = true;
  44.       end
  45.       #如果当前坐标处于地形标志为1的图块里,则设置为不可通行
  46.       if ($game_map.terrain_tag(x, y) == 1)
  47.         flag = false;
  48.       end
  49.     end
  50.     #预定传送位置,准备开始传送   
  51.     $game_player.reserve_transfer($game_map.map_id, x, y, $game_variables[1]);
  52.     $game_player.perform_transfer;#执行传送
  53.   end
  54. end


九、没了。

不知道我的讲解是否详细。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1