| 赞 | 0 |
| VIP | |
| 好人卡 | |
| 积分 | 2 |
| 经验 | |
| 最后登录 | 2025-2-12 |
| 在线时间 | 13 小时 |
- 梦石
- 0
- 星屑
- 170
- 在线时间
- 13 小时
- 注册时间
- 2022-8-3
- 回帖
- 1
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 Atea 于 2023-2-2 23:43 编辑
在游戏中,当玩家在一个事件到达不了的位置时,游戏会变的很卡顿
有大佬知道怎么解决吗?
[fold=A*寻路]#==================================================================#
# AStar Core v1.01 by 禾西
#==================================================================#
class AStar
Point = Struct.new(:x, :y)
public
def initialize(map)
@map_width = map.width
@map_height = map.height
@g_data = Table.new(@map_width, @map_height)
@f_data = Table.new(@map_width, @map_height)
@p_data = Table.new(@map_width, @map_height)
@ox = 0; @oy = 0
@tx = 0; @ty = 0
@openList = []
@g = 0
@search_done = false
@execute_character = nil
end
def set_origin(ox, oy)
@ox = ox; @oy = oy
if is_Overmap(ox, oy)
raise RuntimeError, "Origin location is overmap!"
end
end
def set_target(tx, ty)
@tx = tx; @ty = ty
if is_Overmap(tx, ty)
raise RuntimeError, "Target location is overmap!"
end
end
def set_character(character)
@execute_character = character
end
def do_search
x = @ox; y = @oy
@g_data[x, y] = 2; @f_data[x, y] = 1
@openList << [x, y]
t = 0
begin
t += 1
point = @openList.shift
return [] if point == nil
check_4dir point[0], point[1]
end until @search_done
if @g_data[@tx, @ty] == 1
@tx = point[0]; @ty = point[1]
end
make_path
return @path
end
private
def check_4dir(x, y)
@g = @g_data[x, y] + 1
mark_point(x, y - 1, 8)
mark_point(x, y + 1, 2)
mark_point(x - 1, y, 4)
mark_point(x + 1, y, 6)
end
def mark_point(x, y, dir)
if is_Overmap(x, y)
return
end
if @g_data[x, y] > 1
return
end
if check_passibility(x, y, dir)
f = _f(x, y)
@g_data[x, y] = @g
@f_data[x, y] = f
point = @openList[0]
if point.nil?
@openList.push [x, y]
elsif (f <= @f_data[point[0], point[1]])
@openList.unshift [x, y]
else
@openList.push [x, y]
end
else
@g_data[x, y] = 1
@f_data[x, y] = _f(x, y)
end
if x == @tx && y == @ty
@search_done = true
end
end
def make_path
x = @tx;y = @ty
@path = []
stack_depth = 0
while !(x == @ox && y == @oy)
stack_depth += 1
break if stack_depth >= 0xff
@g = @g_data[x, y]
@best_f = 0
dir = 0
dir = make_step(x, y - 1, 2)||dir
dir = make_step(x, y + 1, 8)||dir
dir = make_step(x - 1, y, 6)||dir
dir = make_step(x + 1, y, 4)||dir
@path.unshift(dir)
case dir
when 2 then y -= 1;
when 8 then y += 1;
when 6 then x -= 1;
when 4 then x += 1;
end
@p_data[x, y] = 1
end
end
def make_step(x, y, dir)
if @g_data[x, y].nil? || @p_data[x, y] == 1
return nil
end
if (@g - @g_data[x, y]) == 1 || @g == 1
f = @f_data[x, y]
if f > 0 && (@best_f == 0 || f < @best_f)
@best_f = f
return dir
end
end
return nil
end
def check_passibility(x, y, dir)
case dir
when 2 then y -= 1;
when 8 then y += 1;
when 4 then x += 1;
when 6 then x -= 1;
end
return @execute_character.passable?(x, y, dir)
end
def is_Overmap(x, y)
return (x|y|(@map_width - x - 1)|(@map_height - y - 1)) < 0
end
def _f(x, y)
return ((x - @tx).abs + (y - @ty).abs) + @g
end
end
class Game_Character
alias old_move_toward_character move_toward_character
def move_toward_character(character)
astr = AStar.new($game_map)
astr.set_origin(@x, @y)
astr.set_target(character.x, character.y)
astr.set_character(self)
path = astr.do_search
pass = [2, 4, 6, 8].any? {|d| self.passable?(character.x, character.y, d) }
if path.empty? || !pass
old_move_toward_character(character)
else
move_straight(path.shift)
end
end
end
[/fold]
|
-
|