设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索

[已解决]区域遇敌哪种做法效果好还简单?

查看数: 3282 | 评论数: 8 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2019-8-21 22:27

正文摘要:

本帖最后由 miantouchi 于 2019-8-27 07:19 编辑 今天看了下,XP的遇敌设置不像VA那么直观,大家一般都是用什么方法实现的? 我看见柳柳有个视频使用,地形用公共事件,并且只能设置0-7,感觉不是太方便,限制太 ...

回复

SailCat 发表于 2019-8-25 11:24:10

点评

哈哈,这么多功能插件,可以把几位大大的脚本都用上,那功能真是无敌了,研究研究。  发表于 2019-8-25 12:24

评分

参与人数 1+1 收起 理由
miantouchi + 1 精品文章

查看全部评分

RyanBern 发表于 2019-8-24 22:23:31
本帖最后由 RyanBern 于 2019-8-25 09:38 编辑

我来给一个直观的实现办法。在不改编辑器的条件下我的这个办法还算比较直观。

主要原理就是将需要设置区域的地图额外复制一张,然后在新地图的第三层加铺代表“区域ID”的图块。
然后使用某种办法将原地图和新地图关联起来,使得新地图成为原地图的“区域ID层”。由于设计区域一般来讲只需要地图场景大致轮廓就可以,因此单独拿出来一个图层作为设置区域问题不大。


主要步骤:

1. 首先使用 PS 等工具(或用程序生成)在原图块的基础上创建一个新图块素材,在新图块素材的末尾绘制表示区域 ID 的图块,比方说我
改造的 001-Grassland01 图块就素材是下面这样的:



2. 在数据库中将原图块数据复制一份,新复制的图块数据的素材改为改造后的图块素材。例如在下图中我的新素材命名为 001-Grassland01-r
注:这一步也可以简化成用新图块素材覆盖原图块素材,之后不用在数据库新建。由于表示区域 ID 的图块是在最后面添加的,将素材扩大对原有数据库以及地图是不会造成影响的。



3. 将需要标区域的地图复制一份,然后在地图结构中放入下一层级。例如在下图中,MAP001 是原始地图,Mask 是新复制的地图。注意新复制的地图在原始地图层级下面。这一步实际上是将原始图和区域ID图关联起来了。最后将新地图使用的图块改为含区域ID素材的图块。



4. 在区域 ID 图的第三层进行编辑。



由于区域 ID 图和原始图的前两层完全一样,这样就是相当于可视化编辑了。

5. 接下来就是写脚本来获取区域 ID 了,1-4 的步骤仅仅是设置步。要让游戏真正识别你的区域 ID 还是需要脚本的帮助。比方说我就写了这个脚本:
RUBY 代码复制
  1. module RB
  2. end
  3.  
  4. module RB::Region
  5.   Mask_Name = "Mask"
  6.   Max_Regions = 64
  7.   def self.create_region_png(max_id = 64)
  8.     back_color = Color.new(128, 128, 128, 128)
  9.     front_color = Color.new(255, 255, 255, 128)
  10.     width = 32 * 8
  11.     height = max_id / 8 * 32
  12.  
  13.     bitmap = Bitmap.new(width, height)
  14.     bitmap.fill_rect(0, 0, width, height, back_color)
  15.     bitmap.font.size = 32
  16.     bitmap.font.color = front_color
  17.     bitmap.font.bold = true
  18.     max_id.times do |id|
  19.       x = id % 8 * 32
  20.       y = id / 8 * 32
  21.       bitmap.draw_text(x, y, 32, 32, id.to_s, 1)
  22.     end
  23.  
  24.     filename = "Graphics/Tilesets/region_id_#{max_id}.png"
  25.     bitmap.save_as_png(filename)
  26.     bitmap.dispose
  27.   end
  28.  
  29.   def self.append_region_png(tileset_filename, region_filename)
  30.     basename = File.basename(tileset_filename, ".png")
  31.     bitmap_tileset = Bitmap.new("Graphics/Tilesets/#{tileset_filename}")
  32.     bitmap_region = Bitmap.new("Graphics/Tilesets/#{region_filename}")
  33.     bitmap_out = Bitmap.new(bitmap_tileset.width, bitmap_tileset.height + bitmap_region.height)
  34.     bitmap_out.blt(0, 0, bitmap_tileset, Rect.new(0, 0, bitmap_tileset.width, bitmap_tileset.height))
  35.     bitmap_out.blt(0, bitmap_tileset.height, bitmap_region, Rect.new(0, 0, bitmap_region.width, bitmap_region.height))
  36.     bitmap_out.save_as_png("Graphics/Tilesets/#{basename}_r.png")
  37.     bitmap_out.dispose
  38.     bitmap_tileset.dispose
  39.     bitmap_region.dispose
  40.   end
  41. end
  42.  
  43. class Scene_Title
  44.   alias rb_main_20190824 main
  45.   def main
  46.     mapinfos = load_data("Data/MapInfos.rxdata")
  47.     $region_masks = {}
  48.     mapinfos.each_pair do |i, info|
  49.       if info.name == RB::Region::Mask_Name
  50.         $region_masks[info.parent_id] = i
  51.       end
  52.     end
  53.     rb_main_20190824
  54.   end
  55. end
  56.  
  57. class Game_Map
  58.   alias rb_setup_20190824 setup
  59.   def setup(map_id)
  60.     @mask_id = $region_masks[map_id]
  61.     @mask = nil
  62.     if @mask_id != nil
  63.       @mask = load_data(sprintf("Data/Map%03d.rxdata", @mask_id))
  64.       mask_tileset_bmp = RPG::Cache.tileset($data_tilesets[@mask.tileset_id].tileset_name)
  65.       @num_tiles = (mask_tileset_bmp.width) / 32 * (mask_tileset_bmp.height / 32)
  66.     end
  67.     rb_setup_20190824(map_id)
  68.   end
  69.   def region_id(x, y)
  70.     if @mask == nil
  71.       return -1
  72.     end
  73.     tile_id = @mask.data[x, y, 2]
  74.     return [-1, tile_id - 384 - (@num_tiles - RB::Region::Max_Regions)].max
  75.   end
  76. end
  77.  
  78. class Game_Character
  79.   def region_id
  80.     return $game_map.region_id(@x, @y)
  81.   end
  82. end

这个脚本的意思是说,如果一个正常地图的下一级有一个名为 Mask 的地图,那么这个地图就是原始地图的区域图。脚本会根据区域图的图块信息来自动对应出原地图的区域 ID。在游戏其他地方我们马上就可以使用下面的脚本来获取区域 ID 相关信息:
RUBY 代码复制
  1. $game_map.region_id(x, y) # 获取坐标为 (x, y) 的区域 ID
  2. $game_player.region_id # 获取主角当前坐标的区域 ID

有了这个接口之后就可以利用这个区域 ID 做很多东西了。例如根据区域不同设置敌人等。这里不再赘述。


此实现的缺点:
1. 需要额外使用一张地图来表示区域,如果地图很多是一种浪费。
2. 当原地图发生改动时,无法在其对应区域地图上进行同步。
3. 需要拼接图块等素材方面的操作(但这个操作可以用程序完成)


附一个范例。这个范例除了能实现上述功能以外,还附赠了自动生成图块素材的功能。
RUBY 代码复制
  1. # 生成一个纯区域 ID 的素材,存放在 Graphics/Tilesets 文件夹下,64 表示区域 ID 总共 64 种
  2. RB::Region.create_region_png(64)
  3. # 将纯区域 ID 素材拼接到地图图块素材后面
  4. RB::Region.append_region_png("001-Grassland01.png", "region_id_64.png")

Region.7z (1.09 MB, 下载次数: 73)

点评

道理是明白了,1号区域、遇敌列表,2号区域,遇敌列表,但是用并行事件还是代码写,在什么地方设置,还是一头雾水,好人做到底。嘿嘿  发表于 2019-8-25 12:14
好了,素材生成工具会用了,非常牛,可以无限扩展了,这么说。另外 能不能帮助下,把随机遇敌那部分代码框架补充下。  发表于 2019-8-25 12:12
可以,见脚本第6行。改完之后需要重新生成素材文件。最大区域ID必须为8的倍数。  发表于 2019-8-25 09:29
好了,我把现有工程覆盖了一下好了,我看你写到0-63,还可以继续增加吗?  发表于 2019-8-25 07:00
怎么提示工具是旧版本无法打开这个工程。打不开这个范例  发表于 2019-8-25 06:52

评分

参与人数 1+1 收起 理由
miantouchi + 1 认可答案

查看全部评分

灯笼菜刀王 发表于 2019-8-24 16:51:59
本帖最后由 灯笼菜刀王 于 2019-8-24 17:13 编辑

你没理解,  核心为"改变遇敌数组从而实现不同区域遇敌",  而那些方法都是用来改变的手段, 根据各种条件把遇敌列表分歧从而实现不同区域遇敌

然后你要做的就是根据玩家的位置, 把对应的条件满足就行了, 主要是改动变量, 确保它是你要分歧的值

给你个饭粒吧, 没仔细测试过, 应该没BUG

采用 地图ID + 变量 + 地形标志的方式, 这样就足够组合出无数个范围了, 有设置的地图就启动敌群分歧, 没设置的地图就用默认遇敌

用变量来区分区域, 用地形标志来设置不规则范围, 在跨区域的时候改变变量值就行了, 规则的界线就用范围触发, 不规则的就铺事件就行了, 再说大区域方方正正也没什么关系嘛

顺便做个小插件, 设置起来方便些

区域遇敌饭粒1.0.rar (191.63 KB, 下载次数: 81)

点评

哈哈,你的代码拓展性这么强,牛,改好了。要不是不知道怎么改好了  发表于 2019-8-28 18:37
改变量就又是另一组了呗  发表于 2019-8-28 16:02
在1号区域上空,遇到的是上空的怪物,背景  发表于 2019-8-28 15:31
如果飞行遇敌的话,用怎么改你给的数组?  发表于 2019-8-28 15:31
用你的代码改造了,结合RB大大的代码终于成功了。  发表于 2019-8-27 16:47

评分

参与人数 2星屑 +100 +2 收起 理由
miantouchi + 1 认可答案
RyanBern + 100 + 1 认可答案

查看全部评分

灯笼菜刀王 发表于 2019-8-23 10:35:37
本帖最后由 灯笼菜刀王 于 2019-8-23 11:03 编辑

  要栗子啊

1,  明雷法,  用事件当做敌人, 设置为接触启动, 然后事件内容做战斗处理, 之后暂时消失就行了

2, 改遇敌敌群法,  game map 里, 这个函数就是获得该地图的敌群数组, 只要这里开分歧就可以了
  #--------------------------------------------------------------------------
  # ● 获取遇敌列表
  #--------------------------------------------------------------------------
  def encounter_list
    if $game_switches[1] #开关1打开的时候, 采用特殊设置敌群
       case $game_variables[1] #用变量1来分歧
       when 1
         return [1,2,3,4,5]
      when 2
        return [6,7,8,9]
      else
       return [10,11]
     end
    else #开关没开的时候用默认设置
      return @map.encounter_list
    end
  end

然后, 需要特殊遇敌的时候打开开关, 改变变量就可以从对应的数组里抽敌群ID了  

当然变量也可以换成其他判定, 比如地形标志 $game_player.terrain_tag,   
比如坐标 $game_player.x > 5 and $game_player.y < 10 and $game_player.y > 5 and $game_player.y < 10,
比如 图块ID  $game_map.data[$game_player.x,$game_player.y,0]

如果选择变量分歧的话, 那就要想办法在需要的位置改变它的值,  可以用 方法2:  并行处理, 判断主角坐标来给变量赋值, 达到不同区域改变不同遇敌的目的(不想并行处理可以用我写的小插件范围触发), 这方法容易理解也容易控制, 适合复数地图和各种地形的地图使用, 缺点就是想做不工整的范围比较麻烦

3, 事件铺路法,


像这样在路口铺两个事件, 设置为接触触发, 然后内容是分别改变变量值, 这样就区分出两个区域了, 只要走过去就自然切换成对应的变量, 优点是设置方便, 缺点就是只适合狭小路口用 , 必须保证要通过就要踩中两个事件(设置两个事件是为了防止在事件上"回头"导致变量异常), 当然,如果需要大范围铺, 那还是可以用我的那个范围触发(广告~)

4, 图块ID法,  用图块ID来分歧敌群, 把地板的图块分成N个, 不同的区域用对应的地板图块, 这样就实现不同区域遇敌了,(想知道图块对应的ID, 可以做个NPC, p  $game_map.data[$game_player.x,$game_player.y,0] , 这个就是主角脚下的第一层图块的ID)图块可以是透明的不影响判定, 所以如果事先有计划的绘制地图就没影响,  此法的优点就是不需要额外设置, 不会占用资源(除了稍微增加一点图片体积,笑), 缺点就是要十分明白自己在干嘛, 否则就会出错而且很难排查, 如果我这样说你还是不能理解这个方法怎么用,那就别用它

5, 扩展地形标志, 这个有相关插件, 不过只要是魔改就不绿色, 所以想用自重, 其实不扩展也可以, 通过双重判定就可以间接扩展地形标志, 比如 用变量+地形标志的判断, 切换大区域的时候改变变量, 就等于又是8个地形标志, 而小区域用8个地形标志分歧应该就够用了吧

点评

楼下已回复,有时间帮忙看看,^_^  发表于 2019-8-24 15:26
感谢,我先挨个试试,嘿嘿。  发表于 2019-8-23 13:36
89444640 发表于 2019-8-22 13:43:38
本帖最后由 89444640 于 2019-8-22 13:45 编辑

地形标记扩展,8*8种,我用的足音系统就是,你可以替换成暗雷系统,然后再按照地图编号区分。不过足音是魔改的主程序,慎用。
感觉根据地图标号+地形编号一起脚本分歧8种也差不多够用了。

点评

好的,我先看看,想不到你当初已经和大家研究了这么多。  发表于 2019-8-23 13:19
https://rpg.blue/forum.php?mod=viewthread&tid=402029&page=1&extra=#pid2730396 请仔细看回复,我调好后就只记得编号00~77对应我地形的哪个音效了。  发表于 2019-8-23 10:15
足音系统,能给脚本链接吗?  发表于 2019-8-22 15:55
灯笼菜刀王 发表于 2019-8-22 11:39:52
本帖最后由 灯笼菜刀王 于 2019-8-22 11:42 编辑

1, 这年头很少做暗雷的了~ 用明雷直接解决, 简单绿色无添加无农药残留

2, 用并行处理, 按坐标判定来决定随机敌群

3, 用变量判断, 在区域和区域的接口处埋事件, 用来在角色移动过去的时候切换变量值, 然后通过变量值来分歧遇敌敌群组

4, 地形标志不够用, 那就用图块来判定,  $game_map.data[X,Y,层数0为第一层] 就可以获得这个坐标的图块ID, 透明图块也一样有ID, 第二行左边第一个图块ID是384,以此类推,  你只要把地面的图块做成N个, 然后去铺在第一层, 用这些图块的ID当做地形标志一样使用就可以了,  小技巧: 复制你的tileset图片, 在对应的图块上标上ID数字, 用它来编辑地图, 方便查看, 之后换回没标数字的tileset搞定收工

5, 用地形标志扩展脚本

点评

上面不是还有个1  发表于 2019-8-23 09:51
2,3,4,5项,是4种方法?眼花缭乱了,有没有例子啥的,第4种貌似很麻烦。  发表于 2019-8-22 15:57
guoxiaomi 发表于 2019-8-21 23:15:26
全地图没有遇敌,遭遇战写个并行公共事件手动判断
拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-30 15:16

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表