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

Project1

 找回密码
 注册会员
搜索
查看: 3960|回复: 35

[已经解决] 怎样才能更改地图部分色调,部分不更改?

[复制链接]

Lv4.逐梦者

梦石
8
星屑
3943
在线时间
396 小时
注册时间
2017-10-11
帖子
154
发表于 2019-5-3 15:28:12 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
如果使用默认的改变色调事件,那么整个画面都会改为同一色调,我想呈现下面的效果,主角周边保持颜色,其余的地方色调改变,该如何做
QQ图片20190503151855.png

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-3 22:53:48 | 显示全部楼层
这问题我大概能解决(假如只是周边变单色)
不过可能解决的不完善 因为我对默认脚本不熟
而且用途可能比较单一
因为我不知道变换色调的算法(能瞎写)
转黑白相对还是挺好做的
我想的是在渲染游戏画面后获取相关信息(角色位置什么的)
然后对将被显示的画面进行处理
比方从某处渐变变灰
(所以基本不涉及原脚本的修改
因为是修改rgss渲染好的结果)
不过五一我回家了 电脑在学校
我明天回去试下

点评

感谢,等你的好消息  发表于 2019-5-4 02:26
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-4 22:53:23 | 显示全部楼层
本帖最后由 SixRC 于 2019-5-4 22:57 编辑

做了一个大概
我做了一个接口 就是在显示画面前会调用一个ruby方法 这个方法自己定义(注意 这个方法中不能用 Graphics.update 因为死循环了 也不能用 p 因为它也会调用渲染那段导致死循环 用 messagebox 代替)
然后提供了将被显示的位图数据地址 这时候可以用c写个dll处理画面(效率高 用ruby也不是不可以) ruby传入必要信息
因为一个原因 请用我提供的 RGSS103J.dll (具体原因是原生的渲染是一段一段的 (640*8) 导致没法整体一次性修改)
假如目标分辨率不是原生的我再改下 因为动态改这个比较麻烦 就直接改dll了
然后这是ruby里的代码
RUBY 代码复制
  1. module Graphics
  2.   module_function
  3.   CCBBSS_DLL = Win32API.new('kernel32','GetModuleHandleA','p','l').call('RGSS103J')
  4.   CCBBSS_WPMLP = Win32API.new('kernel32','WriteProcessMemory','llpll','l')
  5.   CCBBSS_WPMPL = Win32API.new('kernel32','WriteProcessMemory','lplll','l')
  6.   temp = "\0"*4
  7.   CCBBSS_WPMPL.call(-1, temp, CCBBSS_DLL + 0x12B6C4, 4, 0)
  8.   CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x134, 4, 0)
  9.   CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0xB4, 4, 0)
  10.   CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x10, 4, 0)
  11.   CCBBSS_BITMAP = temp.unpack("l")[0]
  12.   CCBBSS_RUBY_CODE = "Graphics.ccbbss_update"
  13.   CCBBSS_CODE = [0x8B, 0x54,0x24, 0x10,
  14.                  0x60, 0x68, CCBBSS_RUBY_CODE,
  15.                  0xB8, CCBBSS_DLL + 0x31D70,
  16.                  0xFF, 0xD0,
  17.                  0x83, 0xC4, 0x04, 0x61,
  18.                  0x68, 0xCC0020,
  19.                  0x6A, 0x00, 0x6A, 0x00, 0x57,
  20.                  0xBF, CCBBSS_DLL + 0x884CD,
  21.                  0xFF, 0xE7].pack("C6pClC7lC6lC2")
  22.   cc = [0xBA, CCBBSS_CODE, 0xFF, 0xE2].pack("CpC2")
  23.   CCBBSS_WPMLP.call(-1, CCBBSS_DLL + 0x884C3, cc, 7, 0)
  24.   CCBBSS_FUNC = Win32API.new("c/ccbbss","ccbbss_test2","lllll","v")
  25.   def ccbbss_update
  26.     unless $game_player
  27.       return
  28.     end
  29.     CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80)
  30.   end
  31. end

CCBBSS_RUBY_CODE 是会被执行的代码 这里指向了 Graphics.ccbbss_update
CCBBSS_BITMAP 保存了位图数据的地址 等下再说
然后我写了个dll来处理位图
C 代码复制
  1. void ccbbss_test2(unsigned char *bits, int ox, int oy, int r1, int r2){
  2.         // r1 != r2 !!!
  3.         if(r1 == r2)
  4.                 return;
  5.         int gray, xx, yy, xy, r3;
  6.         int r12 = r1*r1;
  7.         int r22 = r2*r2;
  8.         int r21 = r2 - r1;
  9.         for(int height = 479; height > -1;height--){
  10.                 for(int width = 0; width < 640; width++){
  11.                         xx = width - ox;
  12.                         yy = height - oy;
  13.                         xy = xx*xx + yy*yy;
  14.                         if(xy < r12){
  15.                                 // nothing
  16.                         }else if( xy > r22){
  17.                                 gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
  18.                                 bits[0] = bits[1] = bits[2] = gray;
  19.                         }else{
  20.                                 r3 = (int)(sqrt((double)xy) + 0.5);
  21.                                 xx = r3 - r1;
  22.                                 yy = r2 - r3;
  23.                                 gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
  24.                                 bits[0] = (bits[0] * yy + gray * xx) / r21;
  25.                                 bits[1] = (bits[1] * yy + gray * xx) / r21;
  26.                                 bits[2] = (bits[2] * yy + gray * xx) / r21;
  27.                         }
  28.                         bits += 4;
  29.                 }
  30.         }
  31. }

同时 ruby 端的调用它 CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80)
第一个参数是位图数据地址 保存形式是 bgra 从最后一行开始储存 也就是 第一个四字节数据是位于 x=0 y=479 的像素点 然后 x=1 ... ---> x=639  y=0
第二个第三个参数是渐变中心
然后两个是渐变半径 以内不变 以外全灰 中间折中
具体见代码
效果如下
xg.png
范例
ccbbss.zip (706.38 KB, 下载次数: 135)

评分

参与人数 1星屑 +200 +1 收起 理由
RyanBern + 200 + 1 太强了8

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
8
星屑
3943
在线时间
396 小时
注册时间
2017-10-11
帖子
154
 楼主| 发表于 2019-5-5 01:37:31 | 显示全部楼层
SixRC 发表于 2019-5-4 22:53
做了一个大概
我做了一个接口 就是在显示画面前会调用一个ruby方法 这个方法自己定义(注意 这个方法中不能 ...

非常感谢,基本上可以解决了,
把$game_player.x * 32 + 16, $game_player.y * 32 + 16,改为$game_player.screen_x, $game_player.screen_y,就基本流畅了。
我现在用的分辨率是1280*736,所以还是出现一些问题,把分辨率改好就完美了。

点评

好 完课去改  发表于 2019-5-5 08:46
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-5 10:39:05 | 显示全部楼层
改好了
ccbbss.zip (706.23 KB, 下载次数: 118)

点评

嗯  发表于 2019-5-5 18:29
谢谢了,并不会C,目前的效果也差不多足够了。  发表于 2019-5-5 18:28
就是在转灰度 >>20 那里改成21或更高 或者改一下前面 然后编译一下(不知道你会不会c)  发表于 2019-5-5 17:57
这个改亮度的函数,具体怎么操作?  发表于 2019-5-5 16:41

评分

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

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
8
星屑
3943
在线时间
396 小时
注册时间
2017-10-11
帖子
154
 楼主| 发表于 2019-5-15 12:58:00 | 显示全部楼层
还有一个问题,假如让两个或者多个作为中心,要怎么做。
比如一个NPC,一个玩家操纵的主角,周围都保持颜色,其他部分为黑白。
@SixRC

点评

改中  发表于 2019-5-15 14:05
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-15 16:30:13 | 显示全部楼层
好了
现在的做法是先根据需要刷新点的亮度信息
在全部刷新完后再渲染
RUBY 代码复制
  1. CCBBSS_update_alpha = Win32API.new("c/ccbbss","ccbbss_update_alpha","llll","v")
  2. CCBBSS_render1 = Win32API.new("c/ccbbss","ccbbss_render1","l","v")
  3. CCBBSS_render2 = Win32API.new("c/ccbbss","ccbbss_render2","lll","v")
  4. CCBBSS_update_alpha.call($game_player.screen_x, $game_player.screen_y - 16, 50, 100)
  5. CCBBSS_update_alpha.call(200, 200, 50, 100)
  6. CCBBSS_update_alpha.call(300, 400, 50, 100)
  7. CCBBSS_render2.call(CCBBSS_BITMAP,3,3)

CCBBSS_update_alpha(x, y, r1, r2) 就是更新信息 每次更新一个点
CCBBSS_render1(CCBBSS_BITMAP) 是刷新画面 照常
CCBBSS_render2(CCBBSS_BITMAP, a, b) 是这样操作的 第二个第三个参数是调节圈外亮度的
算式是 *a >> b
3, 3 就是亮度 *3/8
圈子和圈子的交叠的算法是 x+y - xy/k
x 和 y 是两个圈子的亮度 k 是亮度最大值 也就是x y 小的时候加的多 趋近亮度顶了就不加了 凑了半天凑出来的..看了下效果还行
ccbbss.zip (706.93 KB, 下载次数: 87)

评分

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

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
8
星屑
3943
在线时间
396 小时
注册时间
2017-10-11
帖子
154
 楼主| 发表于 2019-5-16 11:47:28 | 显示全部楼层
发现一个新问题,能不能将显示图片跟对话框单独分离出去,就是显示图片和显示对话框时不计入黑白的效果
目前的对话效果:
QQ图片20190516112452.png
期待的效果是:
QQ图片201905161124522.png

@SixRC
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-16 14:18:20 | 显示全部楼层
我以为初版的时候你就发现了然后觉得没关系
因为现在的做法是在所有位图渲染完成后再作修改的
也就是说这时候 对话框 人物 地图 的效果都已经定死了
然后才改灰度
这时候只能选择改不改 改哪里
就像一个有选择的滤镜 但各图层已经融合了
所以理论上没办法不改对话
可以考虑的是对话框盖住底 就是对话框不透明
这样只要对话框和头像不变灰就行
你考虑下?
我先有点事

点评

好  发表于 2019-5-16 19:04
只需要立绘不变化就行了  发表于 2019-5-16 18:19
相反的想法是 立绘和对话框不受影响 固定灰色 假如你有需求 请把需求说清楚一些 我不是很理解你的想法  发表于 2019-5-16 18:14
但这样另外需要改对话框的脚本和相关素材 所以只是提议  发表于 2019-5-16 18:13
所以我的意思是把对话框做成不透明的 这样会盖住底部 然后立绘和对话框不变就可以  发表于 2019-5-16 18:11
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13559
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

发表于 2019-5-16 20:30:36 | 显示全部楼层
本帖最后由 SixRC 于 2019-5-17 14:51 编辑

新增的函数
RUBY 代码复制
  1. CCBBSS_fix1 = Win32API.new("c/ccbbss","ccbbss_fix1","lll","v")
  2. CCBBSS_fix2 = Win32API.new("c/ccbbss","ccbbss_fix2","llll","v")
  3. $ccbbss_test = Sprite.new
  4. $ccbbss_test.bitmap = Bitmap.new("001-Fighter01")
  5. $ccbbss_test.x = 400
  6. $ccbbss_test.y = 400
  7. $ccbbss_test.z = 666
  8. CCBBSS_fix2.call($ccbbss_test.bitmap.id,$ccbbss_test.x,$ccbbss_test.y, 800)

说明
CCBBSS_fix1(bitmap.id, x, y) 是刷新一个位图点位的亮度到最高 必须要传入位图的 id / __id__ 根据它的透明度进行刷新 透明度不为0则更改 后面的 x 和 y 是位图的屏幕坐标 这些需要自己获取
CCBBSS_fix2 多了一个参数是自定亮度 从 0-->1024  0 是纯灰  1024 不变
ccbbss.zip (715.58 KB, 下载次数: 89)

点评

没事 和变量挂钩的时候可以固定第二个系数 只改第一个 会方便 比方改成 a,10 相当于 亮*a/1024 只调a就行了  发表于 2019-5-18 01:04
看漏了,多谢了。  发表于 2019-5-18 00:40
这个接口有啊 有两个函数 在7楼 分别是 render1 和 render2 2是自定义亮度的  发表于 2019-5-18 00:08
还有一点,黑白处的亮度,能不能游戏中弄个变量改亮改暗,如果麻烦的话,直接改回三楼那种亮度就行了。  发表于 2019-5-17 19:10
完美了,非常感激  发表于 2019-5-17 17:55

评分

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

查看全部评分

回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-18 18:42

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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