-
caveman
-
-
Вне сайта
-
Архитектор Миров
-
- Сообщений: 1274
- Спасибо получено: 1307
-
-
|
Иногда события бывают большими из-за их графики и занимают собой несколько клеток. Как с ними взаимодействовать?
Можно ставить кучу невидимых событий вокруг, которые делают то же самое, но для движущихся событий (например, огромный дракон) это не прокатит - дракон даже не двинется, невидимые события не пустят.
Поковырявшись в гугле, нашел вот это:
www.rpgmakervx.net/index.php?showtopic=53123
Но это VX, а не XP и, имхо он имеет некоторые недостатки (а именно, недостаточно типов распространения большести - только в одну сторону, либо ромбом)
# 0 for normal large
# X0 | X00
# 00 | 000 ETC
# | 000
# 1 for reverse large
# 00 | 000
# X0 | 000 ETC
# | X00
# 2 for flood based large ( cases 1 and 2 size shown below )
# 0 | 0
# 0X0 | 000
# 0 | 00X00 ETC
# | 000
# | 0
#
Пришлось снова залезть в скрипты и написать следующий скрипт, который можно поместить перед main, обозвав его BIG_Events. Это тестовая версия, без ромбов, но с прямоугольниками, которая, может, еще дополнится
# BIG events script
# автор: caveman
# версия 1.2.0 Добавлено задание Bounding Box в комментах события
# версия 1.2.1. Исправлено несрабатывание события, когда оно лежит на непроходимом участке карты
# Скрипт считает большие по размеру евенты как маленькие и позволяет
# сталкиваться и взаимодействовать с ними адекватно
class Game_Character
# новые параметры - сдвиги относительно клетки события,
# исходя из которых надо расчитывать столкновения
#
# []
# []E[]
# []
#
attr_accessor :x_sub
attr_accessor :x_add
attr_accessor :y_sub
attr_accessor :y_add
alias bigevent_initialize initialize
def initialize
@x_sub=0
@x_add=0
@y_sub=0
@y_add=0
bigevent_initialize
end
def setup_boxes(dispose)
unless dispose && @list.nil?
for command in @list
if command.code == 108 && command.parameters[0].include?("[bbox")
command.parameters[0].gsub(/\[[Bb][Bb][Oo][Xx]\|(.+?)\|(.+?)\|(.+?)\|(.+?)\]/) do
@x_sub = $1.to_s.to_i
@x_add = $2.to_s.to_i
@y_sub = $3.to_s.to_i
@y_add = $4.to_s.to_i
end
end
end
end
end
def set_touch_shifts(x_sub, x_add, y_sub, y_add)
@x_sub=x_sub
@x_add=x_add
@y_sub=y_sub
@y_add=y_add
return
end
def event_touch(x, y)
for i in @x - x_sub..@x + x_add
for j in @y - y_sub..@y + y_add
if x == i && y == j
return true
end
end
end
return false
end
# так как положение события не всегда совпадает с местом столкновения -
# то передадим координаты столкновения
def over_trigger1?(x,y)
if @character_name != "" and not @through
return false
end
unless $game_map.passable?(x, y, 0)
return false
end
return true
end
alias bigevent_passable? passable?
def passable?(x, y, d)
# 21 4
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if @through
return true
end
unless $game_map.passable?(x, y, d, self)
return false
end
unless $game_map.passable?(new_x, new_y, 10 - d)
return false
end
for event in $game_map.events.values
if event.event_touch(new_x, new_y)
unless event.through
if self != $game_player
return false
end
if event.character_name != ""
return false
end
end
end
end
if $game_player.x == new_x and $game_player.y == new_y
unless $game_player.through
if @character_name != ""
return false
end
end
end
return true
end
end
# ===================================================================== #
class Game_Player
#--------------------------------------------------------------------------
alias big_event_check_event_trigger_here check_event_trigger_here
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 event.event_touch(@x, @y) and triggers.include?(event.trigger)
if not event.jumping? and event.over_trigger1?(@x,@y)
event.start
result = true
end
end
end
return result
end
#--------------------------------------------------------------------------
alias big_event_check_event_trigger_there check_event_trigger_there
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.event_touch(new_x, new_y) and
triggers.include?(event.trigger)
if not event.jumping? and not event.over_trigger1?(@x,@y)
event.start
result = true
end
end
end
if result == false
if $game_map.counter?(new_x, new_y)
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.event_touch(new_x, new_y) and triggers.include?(event.trigger)
if not event.jumping? and not event.over_trigger1?(@x,@y)
event.start
result = true
end
end
end
end
end
return result
end
#--------------------------------------------------------------------------
alias big_event_check_event_trigger_touch check_event_trigger_touch
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.event_touch(x, y) and [1,2].include?(event.trigger)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
return result
end
end
# ===================================================================== #
class Game_Map
alias bigevent_passable? passable?
def passable?(x, y, d, self_event = nil)
unless valid?(x, y)
return false
end
bit = (1 << (d / 2 - 1)) & 0x0f
for event in events.values
if event.tile_id >= 0 and event != self_event and
event.event_touch(x, y) and not event.through
if @passages[event.tile_id] & bit != 0
return false
elsif @passages[event.tile_id] & 0x0f == 0x0f
return false
elsif @priorities[event.tile_id] == 0
return true
end
end
end
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & bit != 0
return false
elsif @passages[tile_id] & 0x0f == 0x0f
return false
elsif @priorities[tile_id] == 0
return true
end
end
return true
end
#--------------------------------------------------------------------------
alias bigevent_check_event check_event
def check_event(x, y)
for event in $game_map.events.values
if event.event_touch(x, y)
return event.id
end
end
end
# Метод для назначения сдвигов столкновений
def set_touch_shifts(ev_id, x_sub, x_add, y_sub, y_add)
events[ev_id].set_touch_shifts(x_sub, x_add, y_sub, y_add)
return
end
end
Скрипт позволяет в коде в событии (например авторан карты) задать прямоугольник другого события.
game_map.set_touch_shifts(ev_id, x_sub, x_add, y_sub, y_add), где параметры: номер события, сдвиг влево, сдвиг вправо, сдвиг вверх, сдвиг вниз - от настоящего местоположения события.
Например, для
метод такой game_map.set_touch_shifts(ev_id, 1, 1, 2, 0)
аналог комментария в событии - строка "[bbox|1|1|2|0]"
Тут приложена демка, где используется этот метод.
yadi.sk/d/9RxLx48h4WZ04
|