八方向像素移动 优化版
原脚本链接: https://rpg.blue/forum.php?mod=viewthread&tid=382432&highlight=%E5%83%8F%E7%B4%A0%E7%A7%BB%E5%8A%A8原作者: @Hello``Bubble
优化内容:
1. 修复了 某些情况下, 某(些)个事件当前没有满足出现条件的事件页,于是变量@page的值就是个nil导致报错的情况.
2. 提高了操作灵活性, 半自动纠正移动方向. (尤其是贴着墙走时格外明显, 原版很容易出现卡墙不走的情况)
3. 把默认的"禁止斜触发"改成了 "允许斜触发". 因为大多数情况下物品还是不要斜触发的好, 否则两个事件靠在一起时很容易一次性把两个都触发了导致bug.
关于灵活性的提高方面, 如截图所示. 蓝色方向是玩家按键方向 (→+↑); 红色方向是系统自动纠正的移动方向.
原版本里, 假如你右边是一堵墙时, 你按 →+↑, 它判定你有右上角无法通行后, 就会让你傻傻地站在原地.
现在, 同样情况下, 它判定你右上角无法通行后, 会去判断你的上方和右方是否可通行, 然后把移动方向纠正向 上 或者 右. 在迷宫场景较多的游戏里, 这个改动可以大大提高移动手感. 目前测试暂时没bug
希望这个能帮上大家~
依旧是在Main之前新建一页帖进去即生效~
RUBY 代码
class Game_Temp
attr_accessor :rgss_move, :dir_4
#alias rgss_initialize_xxxxxxxxx initialize默认值???
#def initialize
#rgss_initialize_xxxxxxxxx
#@rgss_move = false
#@dir_4 = false
#end
end
class Game_Event < Game_Character
attr_reader :touch_4
alias rgss_refresh refresh
def refresh
rgss_refresh
@touch_4 = true
if list != nil
for list in@page.list
if list.code == 108or list.code == 408
if list.parameters =~ /允许斜触发/
@touch_4 = false
break
end
end
end
end
end
end
class Game_Player < Game_Character
def x(f=nil)
return !f ? @x.to_i : @x
end
def y(f=nil)
return !f ? @y.to_i : @y
end
def to_i
@x = @x.to_iif@x.is_a?(Float)
@y = @y.to_iif@y.is_a?(Float)
end
def player_passable?(dir = @direction, px = @x, py = @y)
case dir
when8
(py - 0.5).to_i == py.to_ior(passable?(px.to_i, py.to_i, 8)and
passable?((px + 0.5).to_i, py.to_i, 8))
when2
passable?(px.to_i, py.to_i, 2)and
passable?((px + 0.5).to_i, py.to_i, 2)
when4
(px - 0.5).to_i == px.to_ior(passable?(px.to_i, py.to_i, 4)and
passable?(px.to_i, (py + 0.5).to_i, 4))
when6
passable?(px.to_i, py.to_i, 6)and
passable?(px.to_i, (py + 0.5).to_i, 6)
when1
(player_passable?(4)and player_passable?(2, @x - 0.5))or
(player_passable?(2)and player_passable?(4, @x, @y + 0.5))
when3
(player_passable?(6)and player_passable?(2, @x + 0.5))or
(player_passable?(2)and player_passable?(6, @x, @y + 0.5))
when7
(player_passable?(4)and player_passable?(8, @x - 0.5))or
(player_passable?(8)and player_passable?(4, @x, @y - 0.5))
when9
(player_passable?(6)and player_passable?(8, @x + 0.5))or
(player_passable?(8)and player_passable?(6, @x, @y - 0.5))
end
end
#--------------------------------------------------------------------------
# ● 接触事件启动判定
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
result = false
# 事件执行中的情况下
if$game_system.map_interpreter.running?
return result
end
# 全事件的循环
for event in$game_map.events.values
if event.touch_4
if(x - 0.5).to_i == x.to_ior
(y - 0.5).to_i == y.to_i
next
end
end
# 事件坐标与目标一致的情况下
if event.x == x.to_iand event.y == y.to_iand.include?(event.trigger)
# 跳跃中以外的情况下、启动判定是正面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
end
return result
end
def player_check_event_trigger_touch(dir)
case dir
when8
check_event_trigger_touch(@x, @y - 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 1, @y - 1)
end
when2
check_event_trigger_touch(@x, @y + 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 1, @y + 1)
end
when4
check_event_trigger_touch(@x - 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x - 1, @y + 1)
end
when6
check_event_trigger_touch(@x + 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x + 1, @y + 1)
end
when1
check_event_trigger_touch(@x - 1, @y + 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 1 - 1, @y + 1)
end
check_event_trigger_touch(@x, @y + 1)
check_event_trigger_touch(@x - 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x - 1, @y + 1)
end
when3
check_event_trigger_touch(@x + 1, @y + 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 2, @y + 1)
end
check_event_trigger_touch(@x, @y + 1)
check_event_trigger_touch(@x + 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x + 1, @y + 1)
end
when7
check_event_trigger_touch(@x - 1, @y - 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 1 - 1, @y - 1)
end
check_event_trigger_touch(@x, @y - 1)
check_event_trigger_touch(@x - 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x - 1, @y - 1)
end
when9
check_event_trigger_touch(@x + 1, @y - 1)
if(@x + 0.5).to_i != @x.to_i
check_event_trigger_touch(@x + 2, @y - 1)
end
check_event_trigger_touch(@x, @y - 1)
check_event_trigger_touch(@x + 1, @y)
if(@y + 0.5).to_i != @y.to_i
check_event_trigger_touch(@x + 1, @y - 1)
end
end
end
#--------------------------------------------------------------------------
# ● 同位置的事件启动判定
#--------------------------------------------------------------------------
def check_event_trigger_here(triggers)
result = false
# 事件执行中的情况下
if$game_system.map_interpreter.running?
return result
end
# 全部事件的循环
for event in$game_map.events.values
# 事件坐标与目标一致的情况下
if triggers.include?(event.trigger)and
((event.x == @x.to_iand event.y == @y.to_i)or
(!event.touch_4and event.x == (@x + 0.5).to_iand event.y == @y.to_i)or
(!event.touch_4and event.x == @x.to_iand event.y == (@y + 0.5).to_i))
# 跳跃中以外的情况下、启动判定是同位置的事件
ifnot event.jumping? and event.over_trigger?
event.start
result = true
end
end
end
return result
end
#--------------------------------------------------------------------------
# ● 正面事件的启动判定
#--------------------------------------------------------------------------
def check_event_trigger_there(triggers)
result = false
# 事件执行中的情况下
if$game_system.map_interpreter.running?
return result
end
# 计算正面坐标
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# 全部事件的循环
for event in$game_map.events.values
if event.touch_4
if(new_x - 0.5).to_i == new_x.to_ior
(new_y - 0.5).to_i == new_y.to_i
next
end
end
# 事件坐标与目标一致的情况下
if !player_passable? and triggers.include?(event.trigger)and
((event.x == new_x.to_iand event.y == new_y.to_i)or
(!event.touch_4and event.x == (new_x + 0.5).to_iand event.y == new_y.to_i)or
(!event.touch_4and event.x == new_x.to_iand event.y == (new_y + 0.5).to_i))
# 跳跃中以外的情况下、启动判定是正面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
nextif event.touch_4
case@direction
when2
if triggers.include?(event.trigger)and
((event.x == @x.to_i - 1and event.y == @y.to_i + 1)or
(event.x == @x.to_i + 1and event.y == @y.to_i + 1))
# 跳跃中以外的情况下、启动判定是斜面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
when4
nextif@x.to_i != (@x + 0.5).to_i
if triggers.include?(event.trigger)and
((event.x == @x.to_i - 1and event.y == @y.to_i - 1)or
(event.x == @x.to_i - 1and event.y == @y.to_i + 1))
# 跳跃中以外的情况下、启动判定是斜面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
when6
nextif@x.to_i != (@x + 0.5).to_i
if triggers.include?(event.trigger)and
((event.x == @x.to_i + 1and event.y == @y.to_i - 1)or
(event.x == @x.to_i + 1and event.y == @y.to_i + 1))
# 跳跃中以外的情况下、启动判定是斜面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
when8
if triggers.include?(event.trigger)and
((event.x == @x.to_i - 1and event.y == @y.to_i - 1)or
(event.x == @x.to_i + 1and event.y == @y.to_i - 1))
# 跳跃中以外的情况下、启动判定是斜面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
end
end
# 找不到符合条件的事件的情况下
if result == false
# 正面的元件是柜台的情况下
if$game_map.counter?(new_x, new_y)
# 计算 1 元件里侧的坐标
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# 全事件的循环
for event in$game_map.events.values
if event.touch_4
if(new_x - 0.5).to_i == new_x.to_ior
(new_y - 0.5).to_i == new_y.to_i
next
end
end
# 事件坐标与目标一致的情况下
if triggers.include?(event.trigger)and
((event.x == new_x.to_iand event.y == new_y.to_i)or
(!event.touch_4and event.x == (new_x + 0.5).to_iand event.y == new_y.to_i)or
(!event.touch_4and event.x == new_x.to_iand event.y == (new_y + 0.5).to_i))
# 跳跃中以外的情况下、启动判定是正面的事件
ifnot event.jumping? andnot event.over_trigger?
event.start
result = true
end
end
end
end
end
return result
end
#--------------------------------------------------------------------------
# ● 向上移动
# turn_enabled : 本场地位置更改许可标志
#--------------------------------------------------------------------------
def move_up(turn_enabled = true)
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 面向上
if turn_enabled
turn_up
end
# 可以通行的情况下
if player_passable?(8)
# 面向上
turn_up
# 更新坐标
@y -= 0.5
# 歩数増加
increase_steps
# 不能通行的情况下
else
# 接触事件的启动判定
player_check_event_trigger_touch(8)
end
end
#--------------------------------------------------------------------------
# ● 向下移动
# turn_enabled : 本场地位置更改许可标志
#--------------------------------------------------------------------------
def move_down(turn_enabled = true)
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 面向下
if turn_enabled
turn_down
end
# 可以通行的场合
if player_passable?(2)
# 面向下
turn_down
# 更新坐标
@y += 0.5
# 增加步数
increase_steps
# 不能通行的情况下
else
# 接触事件的启动判定
player_check_event_trigger_touch(2)
end
end
#--------------------------------------------------------------------------
# ● 向左移动
# turn_enabled : 本场地位置更改许可标志
#--------------------------------------------------------------------------
def move_left(turn_enabled = true)
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 面向左
if turn_enabled
turn_left
end
# 可以通行的情况下
if player_passable?(4)
# 面向左
turn_left
# 更新坐标
@x -= 0.5
# 增加步数
increase_steps
# 不能通行的情况下
else
# 接触事件的启动判定
player_check_event_trigger_touch(4)
end
end
#--------------------------------------------------------------------------
# ● 向右移动
# turn_enabled : 本场地位置更改许可标志
#--------------------------------------------------------------------------
def move_right(turn_enabled = true)
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 面向右
if turn_enabled
turn_right
end
# 可以通行的场合
if player_passable?(6)
# 面向右
turn_right
# 更新坐标
@x += 0.5
# 增加步数
increase_steps
# 不能通行的情况下
else
# 接触事件的启动判定
player_check_event_trigger_touch(6)
end
end
#--------------------------------------------------------------------------
# ● 向左下移动
#--------------------------------------------------------------------------
def move_lower_left
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 没有固定面向的场合
unless@direction_fix
# 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
# 下→左、左→下 的通道可以通行的情况下
if player_passable?(1)
# 更新坐标
@x -= 0.5
@y += 0.5
# 增加步数
increase_steps
else
# 接触事件的启动判定
player_check_event_trigger_touch(1)
#向左或下绕路
if player_passable?(4)
move_left
elsif player_passable?(2)
move_down
end
#------------------
end
end
#--------------------------------------------------------------------------
# ● 向右下移动
#--------------------------------------------------------------------------
def move_lower_right
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 没有固定面向的场合
unless@direction_fix
# 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
# 下→右、右→下 的通道可以通行的情况下
if player_passable?(3)
# 更新坐标
@x += 0.5
@y += 0.5
# 增加步数
increase_steps
else
# 接触事件的启动判定
player_check_event_trigger_touch(3)
#向右或下绕路
if player_passable?(6)
move_right
elsif player_passable?(2)
move_down
end
#------------------
end
end
#--------------------------------------------------------------------------
# ● 向左上移动
#--------------------------------------------------------------------------
def move_upper_left
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 没有固定面向的场合
unless@direction_fix
# 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
# 上→左、左→上 的通道可以通行的情况下
if player_passable?(7)
# 更新坐标
@x -= 0.5
@y -= 0.5
# 增加步数
increase_steps
else
# 接触事件的启动判定
player_check_event_trigger_touch(7)
#向左或上绕路
if player_passable?(4)
move_left
elsif player_passable?(8)
move_up
end
#------------------
end
end
#--------------------------------------------------------------------------
# ● 向右上移动
#--------------------------------------------------------------------------
def move_upper_right
if$game_temp.rgss_movethen
to_i ; super ; return
end
# 没有固定面向的场合
unless@direction_fix
# 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
# 上→右、右→上 的通道可以通行的情况下
if player_passable?(9)
# 更新坐标
@x += 0.5
@y -= 0.5
# 增加步数
increase_steps
else
# 接触事件的启动判定
player_check_event_trigger_touch(9)
#向右或下绕路
if player_passable?(6)
move_right
elsif player_passable?(8)
move_up
end
#------------------
end
end
#--------------------------------------------------------------------------
# ● 画面更新
#--------------------------------------------------------------------------
alias rgss_update update
def update
if$game_temp.dir_4
rgss_update
return
end
# 本地变量记录移动信息
last_moving = moving?
# 移动中、事件执行中、强制移动路线中、
# 信息窗口一个也不显示的时候
unless moving? or$game_system.map_interpreter.running? or
@move_route_forcingor$game_temp.message_window_showing
# 如果方向键被按下、主角就朝那个方向移动
case Input.dir8
when1
move_lower_left
when2
move_down
when3
move_lower_right
when4
move_left
when6
move_right
when7
move_upper_left
when8
move_up
when9
move_upper_right
end
end
# 本地变量记忆坐标
last_real_x = @real_x
last_real_y = @real_y
super
# 角色向下移动、画面上的位置在中央下方的情况下
if@real_y > last_real_y and@real_y - $game_map.display_y > CENTER_Y
# 画面向下卷动
$game_map.scroll_down(@real_y - last_real_y)
end
# 角色向左移动、画面上的位置在中央左方的情况下
if@real_x < last_real_x and@real_x - $game_map.display_x < CENTER_X
# 画面向左卷动
$game_map.scroll_left(last_real_x - @real_x)
end
# 角色向右移动、画面上的位置在中央右方的情况下
if@real_x > last_real_x and@real_x - $game_map.display_x > CENTER_X
# 画面向右卷动
$game_map.scroll_right(@real_x - last_real_x)
end
# 角色向上移动、画面上的位置在中央上方的情况下
if@real_y < last_real_y and@real_y - $game_map.display_y < CENTER_Y
# 画面向上卷动
$game_map.scroll_up(last_real_y - @real_y)
end
# 不在移动中的情况下
unless moving?
# 上次主角移动中的情况
if last_moving
# 与同位置的事件接触就判定为事件启动
result = check_event_trigger_here()
# 没有可以启动的事件的情况下
if result == false
# 调试模式为 ON 并且按下 CTRL 键的情况下除外
unless$DEBUGand Input.press?(Input::CTRL)
# 遇敌计数下降
if@encounter_count > 0
@encounter_count -= 1
end
end
end
end
# 按下 C 键的情况下
if Input.trigger?(Input::C)
# 判定为同位置以及正面的事件启动
check_event_trigger_here()
check_event_trigger_there()
end
end
end
end
本帖来自P1论坛作者龙夫三拳tan,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=410504若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页:
[1]