Project1

标题: Sprite_Vision 地图视野 [打印本页]

作者: kvkv97    时间: 2015-7-13 22:43
标题: Sprite_Vision 地图视野
本帖最后由 hys111111 于 2017-8-22 19:07 编辑

RUBY 代码复制
  1. #======================================   
  2. # Sprite_Vision 地图视野   
  3. # 作者: viktor   
  4. # 原创脚本。仅供讨论使用,不可以用于商用。转载请注明出处/暂时不对脚本进行更多的解释了。   
  5. # 设置视野方法:使用地图标记,原则是地图标记越大,高度越高。   
  6. #   
  7. # 最低的地面:0   
  8. # 墙:比下方的地面高1   
  9. # 竖直墙的顶部:比下方的墙高1   
  10. # 高地:与在高地下侧的竖直墙顶部高度相同。这样在高地上可以看到下面的东西   
  11. # 背后可通行的障碍物(如树木):可通行的部分与周围地面相同,底部+1   
  12. #   
  13. # 例如:   
  14. # 样例中的地面(浅绿草地):0   
  15. # 石头墙:1   
  16. # 石头墙顶部:2   
  17. # 高地(绿草地):2   
  18. # 高地上的树:树根3 树冠2   
  19. # 山顶的草:3   
  20. #======================================   
  21. #$Call_fillshadow = Win32API.new("bmp", "fill_shadow", 'lllli', 'i')   
  22. $width = 640 if $width == nil  
  23. $height = 480 if $height == nil  
  24.  
  25. class Sprite_Vision < Sprite  
  26. # 配置   
  27. # 脚本开关   
  28. SWITCH = 30  
  29. # 渐变速率   
  30. STEP = 0.1  
  31. # 平滑开关   
  32. SMOOTH = true  
  33. # 可变配置   
  34. def init_param  
  35.     # directional lighting   
  36.     # [前 侧 后]方向的最大亮度   
  37.     @lighting=[255, 160, 64]  
  38.     @directional = [[0, 1, 1, 2],  
  39.                     [1, 0, 2, 1],  
  40.                     [1, 2, 0, 1],  
  41.                     [2, 1, 1, 0]]  
  42.     # 由近到远的亮度变化率。1表示不改变(可以看到前方无限远)   
  43.     @rate = 1.0  
  44.     # 阈值:小于此亮度的格子不可见   
  45.     @threshold = 0  
  46.     # 视野阴影的z值。如果遮挡了窗口需要调整这个。   
  47.     self.z=10  
  48. end  
  49. # 直接修改init_param中的参数的方法。每秒至多调用一次因为有refresh   
  50. def set_param(param, value)  
  51.   self.instance_variable_set(param, value)  
  52.   refresh  
  53. end  
  54. # 经验公式。设置视野范围 0..1 为近..远 每秒至多调用一次因为有refresh   
  55. def set_range(param)  
  56.   @threshold = (64 * (1.0 - param)).to_i  
  57.   @rate = 0.4 + 0.6 * param  
  58.   refresh  
  59. end  
  60.  
  61.     def initialize(viewport, tilemap)  
  62.         super(viewport)  
  63.         @tilemap = tilemap  
  64.         init_param  
  65.         init_cache  
  66.  
  67.         self.bitmap = Bitmap.new(@tilemap.map_data.xsize * 32,  
  68.                                  @tilemap.map_data.ysize * 32)  
  69.         self.bitmap.fill_rect(self.bitmap.rect, @gray[255])  
  70.         # 内部亮度矩阵,存放各个角色看到的亮度的最大值   
  71.         @brightness = Table.new(@tilemap.map_data.xsize, @tilemap.map_data.ysize)  
  72.         # 显示亮度矩阵   
  73.         @disp = Table.new(@tilemap.map_data.xsize, @tilemap.map_data.ysize)  
  74.         # 玩家位置   
  75.         @cx = -1; @cy = -1  
  76.         # 跟随的玩家数量初始化为1   
  77.         init_br(1)  
  78.         # 设置绘制方法   
  79.         @update_func = SMOOTH ? self.method(:smooth_update) :   
  80.                                 self.method(:rough_update)  
  81.         # 刷新列表初始化   
  82.         @xlist=[0]*1000  
  83.         @ylist=[0]*1000  
  84.         @blist=[0]*1000  # 亮度   
  85.         @tlist=[1]*1000  # 是否要刷新。正数为需要   
  86.         @list_size = 0  
  87.  
  88.         refresh  
  89.     end  
  90.  
  91.     def dispose  
  92.         self.bitmap.dispose if self.bitmap != nil  
  93.         super  
  94.     end  
  95.  
  96.     def init_cache  
  97.         srand; [url=home.php?mod=space&uid=15507]@Gray[/url] = []  
  98.         # 颜色对象           
  99.         (0..255).each{|x|@gray.push(Color.new(46, 29, 27, x))}  
  100.         # 测试用颜色对象   
  101.         # (0..255).each{|a| @gray.push(Color.new(rand(255), rand(255), rand(255), 64))}   
  102.  
  103.         # 地图标记   
  104.         @tags = Table.new(@tilemap.map_data.xsize, @tilemap.map_data.ysize)  
  105.         for x in [email]0...@tags.xsize[/email]  
  106.             for y in [email]0...@tags.ysize[/email]  
  107.                 @tags[x, y]=$game_map.terrain_tag(x, y)  
  108.             end  
  109.         end  
  110.     end  
  111.  
  112.     def init_br(n)  
  113.         # multiple lighting   
  114.         # 初始化每个角色的亮度矩阵   
  115.         @br=Table.new(@tilemap.map_data.xsize, @tilemap.map_data.ysize, n)  
  116.         @nc = n  
  117.         [url=home.php?mod=space&uid=94117]@current[/url] = 0  
  118.     end  
  119.  
  120.     # 取某方向的最大亮度   
  121.     def base_brightness(direction)  
  122.         return @lighting[@directional[$game_player.direction/2-1][direction/2-1]]  
  123.     end  
  124.     # 计算刷新矩形   
  125.     def count_refresh_rect  
  126.         @min_x = $game_map.display_x / 128  
  127.         @min_y = $game_map.display_y / 128  
  128.         @max_x = @min_x + $width / 32  
  129.         @max_y = @min_y + $height / 32  
  130.         # 调整   
  131.         case $game_player.direction  
  132.         when 2  
  133.             @max_y += 3  
  134.         when 4  
  135.             @min_x -= 3  
  136.         when 6  
  137.             @max_x += 3  
  138.         when 8  
  139.             @min_y -= 3  
  140.         end  
  141.         # 剪裁,规范化   
  142.         @min_x = [@min_x, 0].max.to_i  
  143.         @min_y = [@min_y, 0].max.to_i  
  144.         @max_x = [@max_x, @tilemap.map_data.xsize].min.to_i  
  145.         @max_y = [@max_y, @tilemap.map_data.ysize].min.to_i  
  146.     end  
  147.  
  148.     def set_brightness(x, y)  
  149.         # 设置内部亮度值   
  150.         m=0  
  151.         (0...@nc).each{|z|  
  152.             m=[m, @br[x, y, z]].max  
  153.         }  
  154.         @brightness[x, y]=m  
  155.         # 更新刷新列表   
  156.         if m != @disp[x, y]  
  157.             @xlist[@list_size] = x  
  158.             @ylist[@list_size] = y  
  159.             @list_size += 1  
  160.         end  
  161.     end  
  162.  
  163.     def refresh  
  164.         @cx = $game_player.x  
  165.         @cy = $game_player.y  
  166.         @list_size = 0  
  167.  
  168.         count_refresh_rect  
  169.         @br[@cx, @cy, @current] = 255  
  170.         set_brightness(@cx, @cy)  
  171.         @ctag = @tags[@cx, @cy]  
  172.         # 四方向预处理   
  173.         b=base_brightness(2)  
  174.         (@cy+1...@max_y).to_a.each{|y|  
  175.             @br[@cx, y, @current] = b  
  176.             set_brightness(@cx, y)  
  177.             b *= @rate  
  178.             break if @tags[@cx, y] > @ctag  
  179.         }  
  180.  
  181.         b=base_brightness(4)  
  182.         (@min_x...@cx).to_a.reverse_each{|x|  
  183.             @br[x, @cy, @current] = b  
  184.             set_brightness(x, @cy)  
  185.             b *= @rate  
  186.             break if @tags[x, @cy] > @ctag  
  187.         }  
  188.  
  189.         b=base_brightness(6)  
  190.         (@cx+1...@max_x).to_a.each{|x|  
  191.             @br[x, @cy, @current] = b  
  192.             set_brightness(x, @cy)  
  193.             b *= @rate  
  194.             break if @tags[x, @cy] > @ctag  
  195.         }  
  196.  
  197.         b=base_brightness(8)  
  198.         ref_tag = @ctag + 1  
  199.         (@min_y...@cy).to_a.reverse_each{|y|  
  200.             @br[@cx, y, @current] = b  
  201.             set_brightness(@cx, y)  
  202.             b *= @rate  
  203.             this_tag = @tags[@cx, y]  
  204.             break if this_tag > ref_tag  
  205.             # ref_tag = [this_tag, ref_tag].max   
  206.         }  
  207.  
  208.         # 填充其他格子   
  209.         # up-right   
  210.         iterate_tiles(@cx+1...@max_x,  
  211.                       (@min_y...@cy).to_a.reverse,  
  212.                       1, -1) # rescue p @min_y, @cy   
  213.         # up-left   
  214.         iterate_tiles((@min_x...@cx).to_a.reverse,  
  215.                       (@min_y...@cy).to_a.reverse,  
  216.                       -1, -1)  
  217.         # down-left   
  218.         iterate_tiles((@min_x...@cx).to_a.reverse,  
  219.                       @cy+1...@max_y,  
  220.                       -1, 1)  
  221.         # down-right   
  222.         iterate_tiles(@cx+1...@max_x,   
  223.                       @cy+1...@max_y,  
  224.                       1, 1)  
  225.  
  226.         # 滚动   
  227.         @current = (@current + 1) % @nc  
  228.     end  
  229.  
  230.     def iterate_tiles(xarray, yarray, dx, dy)  
  231.       ref_tag = @ctag  
  232.       for y in yarray  
  233.         for x in xarray  
  234.           tag1 = @tags[x - dx, y]  
  235.           tag2 = @tags[x, y - dy]  
  236.  
  237.           # 墙判定   
  238.           br1 = tag1 > @ctag ? 0 : @br[x-dx, y, @current]  
  239.           br2 = tag2 > ref_tag ? 0 : @br[x, y-dy, @current]  
  240.  
  241.           ref_tag = tag2 if dy==-1 and ref_tag < tag2  
  242.  
  243.           # 计算亮度   
  244.           tmp = (br1 + br2) / 2  
  245.           @br[x, y, @current] = (tmp>@threshold?tmp:0)  
  246.           set_brightness(x, y)  
  247.         end  
  248.       end  
  249.     end  
  250.  
  251.     def update_bitmap(step=STEP)  
  252.         new_size=0  
  253.         for i in 0...@list_size  
  254.             x = @xlist[i]; y = @ylist[i]  
  255.             diff = @brightness[x, y] - @disp[x, y]  
  256.             if diff!=0  
  257.               @disp[x, y] += [diff.abs*step, 1].max.to_i * (diff<=>0)  
  258.               @xlist[new_size]=x; @ylist[new_size]=y;  
  259.               @blist[new_size]=@disp[x, y]  
  260.               self.bitmap.fill_rect(x*32, y*32, 32, 32, @gray[255-@blist[new_size]])  
  261.               #self.bitmap.draw_text(x*32, y*32, 32, 32, @tags[x, y].to_s, 1)   
  262.               new_size += 1  
  263.             end  
  264.         end  
  265.  
  266.         @list_size = new_size  
  267.         # puts new_size   
  268.         # 调用dll   
  269.         #$Call_fillshadow.call(self.bitmap.object_id,   
  270.         #            @xlist.object_id, @ylist.object_id, @blist.object_id,   
  271.         #            @list_size)   
  272.     end  
  273.  
  274.     def smooth_update  
  275.         # 移动时刷新视野数据   
  276.         refresh if $game_player.x != @cx or $game_player.y != @cy  
  277.         # 每一帧平滑刷新视野图形   
  278.         update_bitmap  
  279.     end  
  280.     def rough_update  
  281.         # 移动时刷新视野数据   
  282.         if $game_player.x != @cx or $game_player.y != @cy  
  283.           refresh   
  284.           update_bitmap  
  285.         end  
  286.     end      
  287.     def update  
  288.       @update_func.call  
  289.       super  
  290.     end  
  291. end  
  292.  
  293. # 接入部分   
  294. class Spriteset_Map  
  295.   attr_accessor :vision_sprite  
  296.  
  297.   def update_vision  
  298.     if @vision_sprite==nil  
  299.       @vision_sprite=Sprite_Vision.new(@viewport1, @tilemap)  
  300.       @vision_sprite.init_br($game_party.actors.size)  
  301.       @vision_sprite.opacity=0  
  302.     end  
  303.     if $game_switches[Sprite_Vision::SWITCH]  
  304.       @vision_sprite.visible=true  
  305.       @vision_sprite.opacity+=10 if @vision_sprite.opacity < 255  
  306.       @vision_sprite.ox=$game_map.display_x / 4  
  307.       @vision_sprite.oy=$game_map.display_y / 4  
  308.       @vision_sprite.update  
  309.     else  
  310.       if @vision_sprite!=nil  
  311.         @vision_sprite.opacity-=10  
  312.         @vision_sprite.visible=false if @vision_sprite.opacity<30  
  313.       end  
  314.     end  
  315.   end  
  316.  
  317.   alias viktor_vision_update update  
  318.   def update  
  319.     update_vision  
  320.     viktor_vision_update  
  321.   end  
  322.  
  323.   alias viktor_vision_dispose dispose  
  324.   def dispose  
  325.     @vision_sprite.dispose if @vision_sprite!=nil  
  326.     viktor_vision_dispose  
  327.   end  
  328. end  
  329.  
  330. class Scene_Map  
  331.   attr_accessor :spriteset  
  332. end

作者: linwsh123    时间: 2015-7-14 13:41
顶  虽然还看不懂,但是必须支持
作者: 冷峻逸    时间: 2015-7-15 11:10
提示: 作者被禁止或删除 内容自动屏蔽
作者: 锡鹏    时间: 2015-10-19 11:17
没什么用啊,
作者: 晴兰    时间: 2015-10-19 13:27
提示: 作者被禁止或删除 内容自动屏蔽
作者: 牛肉面    时间: 2015-10-20 18:43
啊,这个脚本要怎么使用呢?




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