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

Project1

 找回密码
 注册会员
搜索
查看: 3082|回复: 47
打印 上一主题 下一主题

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

[复制链接]

Lv4.逐梦者 (版主)

梦石
0
星屑
9497
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

1
发表于 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 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

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

GMT+8, 2024-5-22 04:59

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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