赞 | 0 |
VIP | 289 |
好人卡 | 7 |
积分 | 1 |
经验 | 7622 |
最后登录 | 2024-2-4 |
在线时间 | 400 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 65
- 在线时间
- 400 小时
- 注册时间
- 2005-10-24
- 帖子
- 634
|
- #==============================================================================
- # ■ Grids
- #------------------------------------------------------------------------------
- # 获得各种范围的模块。
- #==============================================================================
- module Grids
- #==========================================================================
- # ■ 目标范围算法
- #==========================================================================
- # 图例解析
- # ■ 范围格子
- # ● 范围格子&确定格子
- # ○ 确定格子
- # ◎ 战斗者位置
- #--------------------------------------------------------------------------
- # ● 获得菱形范围
- # range为2的范围
- # □□□□□
- # □□■□□
- # □■●■□
- # □□■□□
- # □□□□□
- #--------------------------------------------------------------------------
- def self.get_diamond_grids(grid, range)
- # 射程小于等于0的话,返回空数组
- if range <= 0
- return []
- end
- # 初始化范围格集合
- available_grids = get_squar_grids(grid, range)
- for each_grid in available_grids.clone
- if each_grid.distance(grid) >= range
- available_grids.delete(each_grid)
- end
- end
- # 添加菱形上半部分及平行部分
- #for line in 1..(range)
- # width = line * 2 - 1
- # grid_y = grid.y + range - line + 1
- # for grid_x in (grid.x - line + 1)..(grid.x + line - 1)
- # # 防止生成地图外格子
- # next if !$game_map.valid?(grid_x, grid_y)
- # distance = (grid.x - grid_x).abs + (grid.y - grid_y).abs
- # available_grids.push Grid.new(grid_x, grid_y, distance)
- # end
- #end
- # 添加菱形下半部分
- #for line in 1..(range - 1)
- # width = line * 2 - 1
- # grid_y = grid.y - (range - line + 1)
- # for grid_x in (grid.x - line + 1)..(grid.x + line - 1)
- # # 防止生成地图外格子
- # next if !$game_map.valid?(grid_x, grid_y)
- # distance = (grid.x - grid_x).abs + (grid.y - grid_y).abs
- # available_grids.push Grid.new(grid_x, grid_y, distance)
- # end
- #end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 获得正方形范围
- # range为2的范围
- # □□□□□
- # □■■■□
- # □■●■□
- # □■■■□
- # □□□□□
- #--------------------------------------------------------------------------
- def self.get_squar_grids(grid, range, valid = true)
- # 射程小于等于0的话,返回空数组
- if range <= 0
- return []
- end
- available_grids = []
- for x in (grid.x - range)..(grid.x + range)
- for y in (grid.y - range)..(grid.y + range)
- # 防止生成地图外格子
- if !$game_map.valid?(grid.x, grid.y) and valid
- next
- end
- distance = (grid.x - x).abs + (grid.y - y).abs
- available_grids.push Grid.new(x, y, distance)
- end
- end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 获得直线范围
- # range为2的范围
- # □□□□
- # ■●◎□
- # □□□□
- #--------------------------------------------------------------------------
- def self.get_linear_grids(battler_grid, target_grid, range)
- # 射程小于等于0的话,返回空数组
- if range <= 0 or target_grid.distance(battler_grid) == 0
- return []
- end
- # 初始化范围格集合
- available_grids = []
- # 获得战斗者格子与目标格子的直线函数
- funtion = Math.get_2_grids_function(battler_grid, target_grid)
- a = funtion[0]
- b = funtion[1]
- c = funtion[2]
- # 取得正方形范围
- squar_grids = self.get_squar_grids(target_grid, range, false)
- # 排序
- squar_grids = self.sort_grids(squar_grids)
- # 循环正方形范围,如果直线过格子,并且格子不和战斗者格子在同一方向的话,添加
- number = 0
- for grid in squar_grids
- # 只添加range个格子
- if number >= range
- break
- end
- if Math.overlap?(a, b, c, grid) and !Math.grids_same_side?(target_grid, battler_grid, grid)
- number += 1
- if $game_map.valid?(grid.x, grid.y)
- available_grids.push(grid)
- end
- end
- end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 获得横线范围
- # range为2的范围
- # □□□□□
- # □■●■□
- # □□◎□□
- # □□□□□
- #--------------------------------------------------------------------------
- def self.get_transverse_grids(battler_grid, target_grid, range)
- # 射程小于等于0的话,返回空数组
- if range <= 0 or target_grid.distance(battler_grid) == 0
- return []
- end
- # 初始化范围格集合
- available_grids = []
- # 获得战斗者格子与目标格子的直线函数
- funtion = Math.get_2_grids_function(battler_grid, target_grid)
- a = funtion[0]
- b = funtion[1]
- c = funtion[2]
- # 取得直线过目标格子的垂线
- funtion_90 = Math.get_90_linear(a, b, c, target_grid.center_x, target_grid.center_y)
- a = funtion_90[0]
- b = funtion_90[1]
- c = funtion_90[2]
- # 取得正方形范围
- squar_grids = self.get_squar_grids(target_grid, range, false)
- # 排序
- squar_grids = self.sort_grids(squar_grids)
- # 循环正方形范围,如果直线过格子的话,添加
- number = 0
- true_range = range * 2 - 1
- for grid in squar_grids
- # 只添加range个格子
- if number >= true_range
- break
- end
- if Math.overlap?(a, b, c, grid)
- number += 1
- if $game_map.valid?(grid.x, grid.y)
- available_grids.push(grid)
- end
- end
- end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 获得十字范围
- # range为3的范围
- # □□□□□□□
- # □□□■□□□
- # □□□■□□□
- # □■■●■■□
- # □□□■□□□
- # □□□■□□□
- # □□□□□□□
- #--------------------------------------------------------------------------
- def self.get_cross_grids(target_grid, range)
- # 射程小于等于0的话,返回空数组
- if range <= 0
- return []
- end
- # 初始化范围格集合
- available_grids = []
- # 添加平行部分
- for x in (target_grid.x - range + 1)..(target_grid.x + range - 1)
- # 防止生成地图外格子
- next if !$game_map.valid?(x, target_grid.y)
- distance = (x - target_grid.x).abs
- available_grids.push Grid.new(x, target_grid.y, distance)
- end
- # 添加垂直部分
- for y in (target_grid.y - range + 1)..(target_grid.y + range - 1)
- # 防止生成地图外格子
- next if !$game_map.valid?(target_grid.x, y)
- distance = (y - target_grid.y).abs
- # 防止重复生成
- next if distance == 0
- available_grids.push Grid.new(target_grid.x, y, distance)
- end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 获得扇形范围(范围需要比较大才看得出是扇形..)
- # range为2,正切为1的范围
- # □□□□□
- # □■■■□
- # □□●□□
- # □□◎□□
- # □□□□□
- #--------------------------------------------------------------------------
- def self.get_fan_grids(battler_grid, target_grid, tan, range)
- # 射程小于等于0的话,返回空数组
- if range <= 0 or target_grid.distance(battler_grid) == 0
- return []
- end
- # 取得半径
- radius = range * Math.cos(Math.atan(tan))
- # 初始化范围格集合
- available_grids = []
- # 获得战斗者格子与目标格子的直线函数
- funtion = Math.get_2_grids_function(battler_grid, target_grid)
- a = funtion[0]
- b = funtion[1]
- c = funtion[2]
- # 获得直线与X轴夹角
- if b == 0
- slope_radian = Math::PI / 2
- else
- slope_radian = Math.atan(-a / b.to_f)
- end
- # 获得扇形夹角的二分之一
- deflective_radian = Math.atan(tan)
- # 获得扇形靠近Y轴的边
- radian = slope_radian + deflective_radian
- slope = Math.tan(radian)
- side1 = Math.get_linear_function(target_grid.center_x, target_grid.center_y, target_grid.center_x + 1, slope + target_grid.center_y)
- side1_grids = []
- # 获得扇形靠近X轴的边
- radian = slope_radian - deflective_radian
- slope = Math.tan(radian)
- side2 = Math.get_linear_function(target_grid.center_x, target_grid.center_y, target_grid.center_x + 1, slope + target_grid.center_y)
- side2_grids = []
- # 取得正方形范围
- squar_grids = self.get_squar_grids(target_grid, radius.ceil)
- # 排序
- squar_grids = self.sort_grids(squar_grids)
- a1 = side1[0]
- b1 = side1[1]
- c1 = side1[2]
- a2 = side2[0]
- b2 = side2[1]
- c2 = side2[2]
- # 循环正方形范围
- for grid in squar_grids
- # 超出范围的不添加
- distance = (grid.center_x - target_grid.center_x) ** 2 + (grid.center_y - target_grid.center_y) ** 2
- if distance > radius ** 2
- next
- end
- # 只添加同方向格子
- if Math.grids_same_side?(target_grid, battler_grid, grid)
- next
- end
- # 添加边上的格子
- if Math.overlap?(a1, b1, c1, grid)
- side1_grids.push(grid)
- available_grids.push(grid)
- elsif Math.overlap?(a2, b2, c2, grid)
- side2_grids.push(grid)
- available_grids.push(grid)
- end
- end
- if side1_grids == [] or side2_grids == []
- return available_grids
- end
- # 循环正方形范围
- for grid in squar_grids
- # 超出范围的不添加
- distance = (grid.center_x - target_grid.center_x) ** 2 + (grid.center_y - target_grid.center_y) ** 2
- if distance > radius ** 2
- next
- end
- # 只添加同方向格子
- if Math.grids_same_side?(target_grid, battler_grid, grid)
- next
- end
- # 添加中间的格子
- if Math.same_side?(a1, b1, c1, grid, side2_grids[side2_grids.size-1]) and
- Math.same_side?(a2, b2, c2, grid, side1_grids[side1_grids.size-1])
- available_grids.push(grid)
- end
- end
- return available_grids
- end
- #--------------------------------------------------------------------------
- # ● 以grid的point由小到大进行排序
- #--------------------------------------------------------------------------
- def self.sort_grids(grids)
- grids.sort! do |a, b|
- a.point <=> b.point
- end
- return grids
- end
- #--------------------------------------------------------------------------
- # ● 通过通行列表对格子进行遮挡处理
- #--------------------------------------------------------------------------
- def self.block_grids(target_grid, grids, map_cost_list)
- fixed_grids = grids.clone
- # 循环所有格子
- for grid in grids
- # 获得战斗者格子与格子的直线函数
- funtion = Math.get_2_grids_function(target_grid, grid)
- a = funtion[0]
- b = funtion[1]
- c = funtion[2]
- delete_flag = false
- for x in 0...map_cost_list.xsize
- break if delete_flag == true
- for y in 0...map_cost_list.ysize
- break if delete_flag == true
- if (x - target_grid.x).abs + (y - target_grid.y).abs >
- (grid.x - target_grid.x).abs + (grid.y - target_grid.y).abs
- next
- end
- if map_cost_list[x, y] == 30000
- block = Grid.new(x, y)
- if Math.overlap?(a, b, c, block)
- if Math.grids_same_side?(target_grid, block, grid)
- fixed_grids.delete(grid)
- delete_flag = true
- end
- end
- end
- end
- end
- end
- return fixed_grids
- end
- end
复制代码
- #==============================================================================
- # ■ Grid
- #------------------------------------------------------------------------------
- # SLG地图格子的类。
- #==============================================================================
- class Grid
- attr_accessor :x # x坐标
- attr_accessor :y # y坐标
- attr_accessor :point # 移动用
- def initialize(x, y, point = 0)
- @x = x
- @y = y
- @point = point
- end
- #--------------------------------------------------------------------------
- # ◎中心坐标,应用到解析计算中
- #--------------------------------------------------------------------------
- def center_x
- return @x + 0.5
- end
- def center_y
- return @y + 0.5
- end
- #--------------------------------------------------------------------------
- # ◎比较坐标集
- #--------------------------------------------------------------------------
- def compare_grids(grids)
- for grid in grids
- if @x == grid.x and @y == grid.y
- return grid
- end
- end
- return false
- end
- #--------------------------------------------------------------------------
- # ◎取得距离
- #--------------------------------------------------------------------------
- def distance(other_grid_or_x, or_y = 0)
- if other_grid_or_x.is_a?(Grid)
- return ((@x - other_grid_or_x.x).abs + (@y - other_grid_or_x.y).abs)
- else
- return ((@x - other_grid_or_x).abs + (@y - or_y).abs)
- end
- end
- end
复制代码
- #==============================================================================
- # ■ Math
- #------------------------------------------------------------------------------
- # 支持浮点运算的模块。
- #==============================================================================
- module Math
- #--------------------------------------------------------------------------
- # ● 获得积点(0~1)
- # number : 目标数字
- # array : 对比的数组
- #--------------------------------------------------------------------------
- def self.rate_number(number, array)
- return 0.5 if array == [] or number.nil?
- max = array.max
- min = array.min
- return 0.5 if max - min == 0
- return (number - min)/(max - min)
- end
- #--------------------------------------------------------------------------
- # ● 返回弧度对应的角度
- #--------------------------------------------------------------------------
- def self.radian_to_angle(radian)
- return radian * 180 / PI
- end
- #--------------------------------------------------------------------------
- # ● 返回角度对应的弧度
- #--------------------------------------------------------------------------
- def self.angle_to_radian(angle)
- return angle * PI / 180
- end
- #--------------------------------------------------------------------------
- # ● 返回一次函数(ax+by+c=0)的[a,b,c]
- # x1, y1, x2, y2 : 直线上两点的坐标
- #--------------------------------------------------------------------------
- def self.get_linear_function(x1, y1, x2, y2)
- a = y2 - y1
- b = -(x2 - x1)
- c = y1 * (x2 - x1) - x1 * (y2 - y1)
- return [a, b, c]
- end
- #--------------------------------------------------------------------------
- # ● 返回过两个格子中心的一次函数(ax+by+c=0)的[a,b,c]
- # grid1,grid2 : 两个格子
- #--------------------------------------------------------------------------
- def self.get_2_grids_function(grid1, grid2)
- return self.get_linear_function(grid1.center_x, grid1.center_y,
- grid2.center_x, grid2.center_y)
- end
- #--------------------------------------------------------------------------
- # ● 已知x与一次函数(ax+by+c=0),返回y
- #--------------------------------------------------------------------------
- def self.get_y(a, b, c, x)
- return -(c + a * x) / b.to_f
- end
- #--------------------------------------------------------------------------
- # ● 返回与一次函数(ax+by+c=0)成直角,并且交于x,y的一次函数的[a,b,c]
- # y不可等于0
- #--------------------------------------------------------------------------
- def self.get_90_linear(a, b, c, x, y)
- if b == 0
- return self.get_linear_function(x, y, 0, y)
- elsif a == 0
- return self.get_linear_function(x, y, x, 0)
- else
- a2 = 1
- b2 = -a / b.to_f
- c2 = -(a2 * x + b2 * y)
- return [a2, b2, c2]
- end
- end
- #--------------------------------------------------------------------------
- # ● 判断一次函数(ax+by+c=0)是否通过grid
- #--------------------------------------------------------------------------
- def self.overlap?(a, b, c, grid)
- if b == 0
- if -c / a > grid.x and -c / a < grid.x + 1
- return true
- end
- elsif -a / b >= 0
- y1 = self.get_y(a, b, c, grid.x)
- y2 = self.get_y(a, b, c, grid.x + 1)
- if y1 < (grid.y + 1) and y2 > grid.y
- return true
- end
- elsif -a / b < 0
- y1 = self.get_y(a, b, c, grid.x)
- y2 = self.get_y(a, b, c, grid.x + 1)
- if y1 > grid.y and y2 < (grid.y + 1)
- return true
- end
- end
- return false
- end
- #--------------------------------------------------------------------------
- # ● 判断grid是否与target_grid在一次函数(ax+by+c=0)的同一方向
- #--------------------------------------------------------------------------
- def self.same_side?(a, b, c, target_grid, grid)
- if b < 0.1 and b > -0.1
- x_intercept = -c / a
- if target_grid.center_x > x_intercept and grid.center_x > x_intercept
- return true
- elsif target_grid.center_x < x_intercept and grid.center_x < x_intercept
- return true
- end
- else
- if target_grid.center_y > self.get_y(a, b, c, target_grid.center_x) and
- grid.center_y > self.get_y(a, b, c, grid.center_x)
- return true
- elsif target_grid.center_y < self.get_y(a, b, c, target_grid.center_x) and
- grid.center_y < self.get_y(a, b, c, grid.center_x)
- return true
- end
- end
- return false
- end
- #--------------------------------------------------------------------------
- # ● 判断grid是否与target_grid在同一方向
- # 分割线为target_grid与ori_grid的连线的垂线,垂线过ori_grid中心
- #--------------------------------------------------------------------------
- def self.grids_same_side?(ori_grid, target_grid, grid)
- connecting_line = self.get_2_grids_function(ori_grid, target_grid)
- a = connecting_line[0]
- b = connecting_line[1]
- c = connecting_line[2]
- parting_line = self.get_90_linear(a, b, c, ori_grid.center_x, ori_grid.center_y)
- a = parting_line[0]
- b = parting_line[1]
- c = parting_line[2]
- return self.same_side?(a, b, c, target_grid, grid)
- end
- #--------------------------------------------------------------------------
- # ● SLG用的数字增加
- #--------------------------------------------------------------------------
- def self.plus_number(number1, number2)
- if number2.is_a?(Float)
- number1 *= number2
- else
- number1 += number2
- end
- return number1.round
- end
- #--------------------------------------------------------------------------
- # ● 以(0,0)为中心,逆时针方向旋转angle度,返回旋转后的[x, y]
- #--------------------------------------------------------------------------
- def self.rotate(x, y, angle)
- r1 = angle * PI / 180
- r2 = r1 - self.atan((x/y.to_f).abs)
- radius = self.sqrt(x**2 + y**2)
- x = (radius * self.sin(r2)).round
- y = (radius * self.cos(r2)).round
- return [x, y]
- end
- #--------------------------------------------------------------------------
- # ● 获得直线(ax+by+c=0)与半径为r,中心为(0,0)的圆的交点
- # 返回两个交点的坐标的数组,无解时返回nil
- #--------------------------------------------------------------------------
- def self.solve_linear_circle(a, b, c, r)
- boo = 4*(b*c)**2 + 4*(c**2-a**2*r**2)*(a**2+b**2)
- if boo < 0
- return
- end
- y1 = (-2*b*c + self.sqrt(boo)) / (2.0 * (a**2 + b**2))
- if a == 0
- x1 = 0
- else
- x1 = - (b * y1 + c) / a
- end
- y2 = (-2*b*c - self.sqrt(boo)) / (2.0 * (a**2 + b**2))
- if a == 0
- x2 = 0
- else
- x2 = - (b * y2 + c) / a
- end
- return [x1, y1, x2, y2]
- end
- end
复制代码 系统信息:本贴由楼主认可为正确答案,66RPG感谢您的热情解答~ |
|