查看: 6264|回复: 35

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

[复制链接]
梦石
8
星屑
3963
在线时间
397 小时
注册时间
2017-10-11
回帖
114
发表于 2019-5-3 15:28:12 | 显示全部楼层 |阅读模式

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

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

×
如果使用默认的改变色调事件,那么整个画面都会改为同一色调,我想呈现下面的效果,主角周边保持颜色,其余的地方色调改变,该如何做
QQ图片20190503151855.png
梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

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

点评

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

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

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里的代码
[pre lang="ruby"]module Graphics
  module_function
  CCBBSS_DLL = Win32API.new('kernel32','GetModuleHandleA','p','l').call('RGSS103J')
  CCBBSS_WPMLP = Win32API.new('kernel32','WriteProcessMemory','llpll','l')
  CCBBSS_WPMPL = Win32API.new('kernel32','WriteProcessMemory','lplll','l')
  temp = "\0"*4
  CCBBSS_WPMPL.call(-1, temp, CCBBSS_DLL + 0x12B6C4, 4, 0)
  CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x134, 4, 0)
  CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0xB4, 4, 0)
  CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x10, 4, 0)
  CCBBSS_BITMAP = temp.unpack("l")[0]
  CCBBSS_RUBY_CODE = "Graphics.ccbbss_update"
  CCBBSS_CODE = [0x8B, 0x54,0x24, 0x10,
                 0x60, 0x68, CCBBSS_RUBY_CODE,
                 0xB8, CCBBSS_DLL + 0x31D70,
                 0xFF, 0xD0,
                 0x83, 0xC4, 0x04, 0x61,
                 0x68, 0xCC0020,
                 0x6A, 0x00, 0x6A, 0x00, 0x57,
                 0xBF, CCBBSS_DLL + 0x884CD,
                 0xFF, 0xE7].pack("C6pClC7lC6lC2")
  cc = [0xBA, CCBBSS_CODE, 0xFF, 0xE2].pack("CpC2")
  CCBBSS_WPMLP.call(-1, CCBBSS_DLL + 0x884C3, cc, 7, 0)
  CCBBSS_FUNC = Win32API.new("c/ccbbss","ccbbss_test2","lllll","v")
  def ccbbss_update
    unless $game_player
      return
    end
    CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80)
  end
end[/pre]
CCBBSS_RUBY_CODE 是会被执行的代码 这里指向了 Graphics.ccbbss_update
CCBBSS_BITMAP 保存了位图数据的地址 等下再说
然后我写了个dll来处理位图
[pre lang="c"]void ccbbss_test2(unsigned char *bits, int ox, int oy, int r1, int r2){
        // r1 != r2 !!!
        if(r1 == r2)
                return;
        int gray, xx, yy, xy, r3;
        int r12 = r1*r1;
        int r22 = r2*r2;
        int r21 = r2 - r1;
        for(int height = 479; height > -1;height--){
                for(int width = 0; width < 640; width++){
                        xx = width - ox;
                        yy = height - oy;
                        xy = xx*xx + yy*yy;
                        if(xy < r12){
                                // nothing
                        }else if( xy > r22){
                                gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
                                bits[0] = bits[1] = bits[2] = gray;
                        }else{
                                r3 = (int)(sqrt((double)xy) + 0.5);
                                xx = r3 - r1;
                                yy = r2 - r3;
                                gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
                                bits[0] = (bits[0] * yy + gray * xx) / r21;
                                bits[1] = (bits[1] * yy + gray * xx) / r21;
                                bits[2] = (bits[2] * yy + gray * xx) / r21;
                        }
                        bits += 4;
                }
        }
}[/pre]
同时 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)
走起路来灰圈圈动的不协调是因为角色坐标的更新没那么平滑

然后 上面的是例子 不是最终
因为我不太熟悉原生的脚本 没法写的很详细 连这个角色坐标转实际坐标都是现场瞎蒙的...
这个可能要麻烦别人写判断了 比方什么时候启用效果 什么时候关闭 打开菜单的时候关闭 等等等等
我会根据需要修改背后的东西 也可以写写dll啥的(现查现写)
有什么问题都可以问我
(先去睡觉了 明天早课 还一堆考试)

评分

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

查看全部评分

回复

使用道具 举报

梦石
8
星屑
3963
在线时间
397 小时
注册时间
2017-10-11
回帖
114
 楼主| 发表于 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
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

发表于 2019-5-5 10:39:05 | 显示全部楼层
改好了
ccbbss.zip (706.23 KB, 下载次数: 118)
改了分辨率 然后改了下函数导出名(ccbbss_effect1)

可以改着那个函数玩
像是转灰度 假如多位移一位(亮度减半)
就变这样了
2.png
就有晕圈的感觉了 效果好很多欸
其他可以根据需要来调整 像是色调 或是渐变算法什么的
或是别的特效

最早这做法是黄鸡想出来的
[RMVA]游戏画面滤镜(目前有马赛克/浮雕/雪花屏)

去复习了

点评

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

查看全部评分

回复

使用道具 举报

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

点评

改中  发表于 2019-5-15 14:05
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

发表于 2019-5-15 16:30:13 | 显示全部楼层
好了
现在的做法是先根据需要刷新点的亮度信息
在全部刷新完后再渲染
[pre lang="ruby"]CCBBSS_update_alpha = Win32API.new("c/ccbbss","ccbbss_update_alpha","llll","v")
CCBBSS_render1 = Win32API.new("c/ccbbss","ccbbss_render1","l","v")
CCBBSS_render2 = Win32API.new("c/ccbbss","ccbbss_render2","lll","v")
CCBBSS_update_alpha.call($game_player.screen_x, $game_player.screen_y - 16, 50, 100)
CCBBSS_update_alpha.call(200, 200, 50, 100)
CCBBSS_update_alpha.call(300, 400, 50, 100)
CCBBSS_render2.call(CCBBSS_BITMAP,3,3)[/pre]
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, 下载次数: 88)
s.png

评分

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

查看全部评分

回复

使用道具 举报

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

@SixRC
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

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
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

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

新增的函数
[pre lang="ruby"]CCBBSS_fix1 = Win32API.new("c/ccbbss","ccbbss_fix1","lll","v")
CCBBSS_fix2 = Win32API.new("c/ccbbss","ccbbss_fix2","llll","v")
$ccbbss_test = Sprite.new
$ccbbss_test.bitmap = Bitmap.new("001-Fighter01")
$ccbbss_test.x = 400
$ccbbss_test.y = 400
$ccbbss_test.z = 666
CCBBSS_fix2.call($ccbbss_test.bitmap.id,$ccbbss_test.x,$ccbbss_test.y, 800)
[/pre]
说明
CCBBSS_fix1(bitmap.id, x, y) 是刷新一个位图点位的亮度到最高 必须要传入位图的 id / __id__ 根据它的透明度进行刷新 透明度不为0则更改 后面的 x 和 y 是位图的屏幕坐标 这些需要自己获取
CCBBSS_fix2 多了一个参数是自定亮度 从 0-->1024  0 是纯灰  1024 不变
ccbbss.zip (715.58 KB, 下载次数: 90)

现在根据透明度向原来储存的亮度信息渐变 透明度255是满亮度/自己选择的亮度 0是不变
假如CCBBSS_fix2.call这句写在最后面 就是最后刷新立绘色彩 那么角色移动到立绘旁边不会影响它的亮度   
假如写在开头 也就是先刷新它的亮度 那之后角色移动过去刷新亮度的时候会影响到它
具体效果因为我没立绘不太清楚 你试试

n.png

点评

没事 和变量挂钩的时候可以固定第二个系数 只改第一个 会方便 比方改成 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 认可答案

查看全部评分

回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部