| 赞 | 15  | 
 
| VIP | 0 | 
 
| 好人卡 | 0 | 
 
| 积分 | 19 | 
 
| 经验 | 16801 | 
 
| 最后登录 | 2024-7-10 | 
 
| 在线时间 | 403 小时 | 
 
 
 
 
 
Lv3.寻梦者 
	- 梦石
 - 0 
 
        - 星屑
 - 1939 
 
        - 在线时间
 - 403 小时
 
        - 注册时间
 - 2015-8-30
 
        - 帖子
 - 395
 
 
 
 | 
	
3楼
 
 
 楼主 |
发表于 2016-4-30 21:56:00
|
只看该作者
 
 
 
 本帖最后由 有丘直方 于 2016-5-1 07:14 编辑  
- #===============================================================================
 
 - # 判断精灵触碰用的脚本
 
 - # 目前没有自行测试过。
 
 - # 注释有点乱……但是看着方便
 
 - #-------------------------------------------------------------------------------
 
 - # Sprite 精灵类
 
 - #===============================================================================
 
 - class Sprite
 
 -   #-----------------------------------------------------------------------------
 
 -   # 判断是否接触——按照矩形计算,也是最简单的算法。
 
 -   # 这个方法是自己最能想到的。
 
 -   # 返回值:true表示触碰,false表示没有触碰
 
 -   # 参数:other:判断接触的另外一个精灵
 
 -   #-----------------------------------------------------------------------------
 
 -   def touch_rect(other)
 
 -     self.ox, self.oy = 0 # 首先确保原点在左上角
 
 -     if self.x.between?(other.x = self.bitmap.width,  # 判断self的x坐标是否过于靠右
 
 -                        other.x + other.bitmap.width) # 判断self的x坐标是否过于靠左
 
 -                                                      # 如果self的x坐标适中,那么继续判断
 
 -       if self.y.between?(other.y = self.biemap.height,  # 与之前相似的办法判断y坐标
 
 -                          other.y + other.bitmap.height, # 同上……
 
 -                                                         # 如果y坐标适中,那么确定触碰
 
 -         return true                                     # 返回true
 
 -       else           # 如果y坐标的条件不满足触碰
 
 -                      # 那么确定没有触碰
 
 -         return false # 返回false
 
 -       end            # y坐标判定结束
 
 -     else           # 如果x坐标的条件不满足触碰
 
 -                    # 同样,确定没有触碰
 
 -       return false # 返回false
 
 -     end            # x坐标判定结束
 
 -   end # touch_rect方法定义结束
 
 -   #-----------------------------------------------------------------------------
 
 -   # 判断是否接触——按照圆形计算,略微有点复杂,因为涉及到四则运算之外。
 
 -   # 这个方法是结合了taroxd和冷峻逸的方法想出来的……
 
 -   # 返回值:true表示触碰,false表示没有触碰
 
 -   # 参数:other:判断接触的另外一个精灵
 
 -   #-----------------------------------------------------------------------------
 
 -   def touch_circle(other)
 
 -     self.ox, self.oy = 0 # 确保原点在左上角
 
 -     bool = nil # 先创建一个临时变量,后期返回它
 
 -     num1 = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)     # 比较参数1:勾股平方和
 
 -     num2 = self.bitmap.width / 2 + other.bitmap.width / 2 # 比较参数2:半径和平方
 
 -     bool = (num1 <= num2) # 进行比较
 
 -                           # 这里其实用到了勾股定理。
 
 -                           # num1其实是在使用勾股定理通过两条直角边来计算斜边
 
 -                           # num2则是利用圆半径永远相等的定理计算圆心的距离
 
 -                           # 那么很显然,如果num1的长度不超过num2,两个精灵就相碰了
 
 -     return bool # 返回运算结果。
 
 -                 # 令我感到很奇怪的是这个方法的定义居然比touch_rect方法短
 
 -   end # touch_circle方法定义结束
 
 -   #-----------------------------------------------------------------------------
 
 -   # 判断是否接触——按照非透明部分计算,很复杂,效率低。
 
 -   # 这个方法是冷峻逸最先提出,也是被最先否定的,因为效率太低了
 
 -   # 返回值:true表示触碰,false表示没有触碰
 
 -   # 参数:other:判断接触的另外一个精灵
 
 -   #-----------------------------------------------------------------------------
 
 -   def touch_opacity(other)
 
 -     return false unless self.touch_rect(other) # 如果没有矩形触碰则直接返回false
 
 -     self.ox, self.oy = 0 # 惯例,让原点在左上角
 
 -     tab1 = Table.new(self.bitmap.width, self.bitmap.height) # 这个二维表格是用来挨个判断不透明度用的
 
 -     for x in 0...(self.bitmap.width)            # 用循环挨个获取像素点的Color
 
 -       for y in 0...(self.bitmap.height)         # 分别用x、y两个临时变量接受像素坐标
 
 -         tab1[x, y] = (self.bitmap.get_pixel(x, y).alpha > 0) # 在这里获取像素点是否透明
 
 -       end                                       # 纵向获取结束
 
 -     end                                         # 横向获取结束
 
 -     tab2 = Table.new(other.bitmap.width, other.bitmap.height) # 这下轮到了判断触碰的精灵
 
 -     for x in 0...(other.bitmap.width); for y in 0...(other.bitmap.height) # 循环
 
 -       tab2[x, y] = (other.bitmap.get_pixel(x, y).alpha > 0) # 在这里获取像素点是否透明
 
 -     end; end # 颜色获取结束
 
 -     for x in 0...(self.bitmap.width); for y in 0...(self.bitmap.height) # 循环
 
 -       if tab1[x, y] and tab2[x, y]                                 # 如果相对于精灵的位置相同的两点都不透明
 
 -         if self.x + x == other.x + x and self.y + y == other.y + y # 如果相对于游戏程序窗口的位置也相同
 
 -                                                                    # 确定两个精灵相碰
 
 -           return true                                              # 返回true
 
 -       end; end                                                     # 分歧结束
 
 -     end # 循环结束
 
 -     return false # 如果到现在还没有return,确定还没有触碰,返回false
 
 -   end # touch_opacity方法定义结束
 
 - end # Sprite类定义结束
 
 - # 因为没有测试,所以能不能正常运行还不知道。不过应该可以了。
 
 - # 第三种方法因为用到了很多循环,所以效率很低,不建议使用。
 
  复制代码- class Sprite
 
 -   def touch_rect(other)
 
 -     self.ox, self.oy, other.ox, other.oy = 0
 
 -     return (self.x.between?(
 
 -                             other.x - self.bitmap.width, 
 
 -                             other.x + other.bitmap.width
 
 -                             ) and 
 
 -             self.y.between?(
 
 -                             other.y - self.biemap.height, 
 
 -                             other.y + other.bitmap.height
 
 -                             )
 
 -             )
 
 -   end
 
 -   def touch_circle(other)
 
 -     return false unless self.touch_rect(other)
 
 -     self.ox, self.oy, other.ox, other.oy = 0
 
 -     return (
 
 -             Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) <= 
 
 -             self.bitmap.width / 2 + other.bitmap.width / 2
 
 -             )
 
 -   end
 
 -   def touch_opacity(other)
 
 -     return false unless self.touch_rect(other)
 
 -     self.ox, self.oy, other.ox, other.oy = 0
 
 -     tab_self = Table.new(self.bitmap.width, self.bitmap.height)
 
 -     for x in 0...(self.bitmap.width)
 
 -       for y in 0...(self.bitmap.height)
 
 -         tab_self[x, y] = (self.bitmap.get_pixel(x, y).alpha > 0)
 
 -       end
 
 -     end
 
 -     tab_other = Table.new(other.bitmap.width, other.bitmap.height)
 
 -     for x in 0...(other.bitmap.width)
 
 -       for y in 0...(other.bitmap.height)
 
 -         tab_other[x, y] = (other.bitmap.get_pixel(x, y).alpha > 0)
 
 -       end
 
 -     end
 
 -     ary = []
 
 -     for self_x in 0...(self.bitmap.width)
 
 -       for self_y in 0...(self.bitmap.height)
 
 -         for other_x in 0...(other.bitmap.width)
 
 -           for other_y in 0...(other.bitmap.height)
 
 -             ary += (tab_self[self_x, self_y]             and 
 
 -                     tab_other[other_x, other_y]          and 
 
 -                     self.x + self_x == other.x + other_x and 
 
 -                     self.y + self_y == other.y + other_y
 
 -                     )
 
 -           end
 
 -         end
 
 -       end
 
 -     end
 
 -     return ary.include?(true)
 
 -   end
 
 - end
 
  复制代码- # 测试代码如下(此代码经过测试,没有BUG):
 
 - class Sprite
 
 -   def touch_rect(other)
 
 -     return (self.x.between?(
 
 -                             other.x - self.bitmap.width, 
 
 -                             other.x + other.bitmap.width
 
 -                             ) and 
 
 -             self.y.between?(
 
 -                             other.y - self.bitmap.height, 
 
 -                             other.y + other.bitmap.height
 
 -                             )
 
 -             )
 
 -   end
 
 - end
 
 - module SceneManager
 
 -   def self.first_scene_class
 
 -     return Scene_Test
 
 -   end
 
 - end
 
 - class Scene_Test < Scene_Base
 
 -   def start
 
 -     super
 
 -     @test = Sprite.new
 
 -     @test.bitmap = Bitmap.new(32, 32)
 
 -     @test.bitmap.fill_rect(0, 0, 32, 32, Color.new(255, 0, 0))
 
 -     @test.y = (640 - 32) / 2
 
 -     @sprite = Sprite.new
 
 -     @sprite.bitmap = Bitmap.new(12, 416)
 
 -     @sprite.bitmap.fill_rect(0, 0, 12, 416, Color.new(255, 255, 255))
 
 -     @sprite.x = 544 - 12 - 12
 
 -   end
 
 -   def update
 
 -     super
 
 -     @test.update
 
 -     @sprite.update
 
 -     @test.x += 1
 
 -     if @test.touch_rect(@sprite)
 
 -       p 'OK.'
 
 -       SceneManager.goto(Scene_Title)
 
 -     end
 
 -   end
 
 -   def terminate
 
 -     super
 
 -     @test.bitmap.dispose
 
 -     @sprite.bitmap.dispose
 
 -     @test.dispose
 
 -     @sprite.dispose
 
 -   end
 
 - end
 
  复制代码 |   
 
 
 
 |