Войти на сайт

Авторизация, ждите ...
×

ТЕМА: Зельда-скроллинг

Зельда-скроллинг 7 года 4 мес. назад #95088

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Зельда-скроллинг

Информация:

Автор: DeadElf79
Версия скрипта: 1.4
Версия мейкера для использования: VX Ace
Условия использования: используйте как хотите, меня можно не указывать.

Описание:
Скрипт добавляет скроллинг карты как в зельде: карта разделяется на несколько независимых "экранов" (персонаж не всегда находится в центрне экрана), при переходе между "экранами" игровой экран смещается. Кто играл в первую легенду о зельде, тот сразу поймет, о чем этот скрипт.

Примечание:
Знаю, что в какой-то игре видел уже такой скрипт, но хоть убейте, не вспомню название. Помню, что это была третья часть (вроде как) и там была доработанная графика из ртп. Поэтому написал своё с нуля. Прошу любить и использовать без указания автора.

Установка:
1. установите скрипт как обычно
2. в note карты, на которой вы хотите использовать, добавьте слово zelda на отдельной строке.
3. убедитесь, что ваша карта имеет следующие размеры:
- по ширине карта должна быть кратна ширине графики игры, разделенной на 32 (640/32 = 20 тайлов)
- по высоте карта должна быть кратна высоте графики игры, разделенной на 32 (480/32 = 15 тайлов)
Например: для создания карты с двумя "экранами" по ширине и двумя по высоте для графики игры размером 640х480 пикселей задайте ей размер 40х30 тайлов.

Код:
# de79 zelda scrolling
# version 1.4
 
module De79Zelda
  REGEXP_MAP_NOTE = /zelda/i
  SCROLL_SPEED = 6
  WAIT_FOR_SCROLL = true
 
  def self.wait_processing
    @wait_processing |= false
  end
 
  def self.wait_processing=(value)
    @wait_processing = value
  end
end
 
class Game_Map
  alias de79setup setup
  def setup(map_id)
    de79setup(map_id)
    @zelda = is_zelda?
  end
 
  def is_zelda?
    @map.note.each_line("\n") { |line|
      return true unless (line =~ De79Zelda::REGEXP_MAP_NOTE).nil?
    }
    false
  end
 
  def zelda_map?
    @zelda
  end
 
  def modw(x)
    return (x.to_f / ($game_map.screen_tile_x)).to_i
  end
 
  def modh(y)
    return (y.to_f / ($game_map.screen_tile_y)).to_i
  end
end
 
class Game_Event
  def on_screen?
    gm = $game_map
    gp = $game_player
    if $game_map.zelda_map?
      gm = $game_map
      gp = $game_player
      screen = Rect.new(
        gm.modw(gp.x),
        gm.modh(gp.y),
        gm.screen_tile_x,
        gm.screen_tile_y
      )
    else
      screen = Rect.new(
        gp.x - gm.screen_tile_x/2,
        gp.y - gm.screen_tile_y/2,
        gm.screen_tile_x,
        gm.screen_tile_y
      )
    end
    if (screen.x * 16..screen.x * 16 + screen.width).include? @x
      if (screen.y * 16..screen.y * 16 + screen.height).include? @y
        return true
      end
    end
    false
  end
end
 
class Game_Player
  def update
    last_real_x = @real_x
    last_real_y = @real_y
    last_moving = moving?
    if De79Zelda.wait_processing
      unless $game_map.scrolling? 
         De79Zelda.wait_processing = false
      end
    else
      move_by_input
    end
    super
    if $game_map.zelda_map?
      update_zelda_scroll(last_real_x,last_real_y)
    else
      update_scroll( last_real_x, last_real_y )
    end
    update_vehicle
    update_nonmoving( last_moving ) unless moving?
    @followers.update
  end
 
  def center(x, y)
    if $game_map.zelda_map?
      new_x = modw(x)*$game_map.screen_tile_x
      new_y = modh(y)*$game_map.screen_tile_y
      $game_map.set_display_pos( new_x, new_y )
    else
      $game_map.set_display_pos(x - center_x, y - center_y)
    end
  end
 
  def update_zelda_scroll( last_x, last_y )
    ax1 = modw( last_x )
    ay1 = modh( last_y )
    ax2 = modw( @real_x )
    ay2 = modh( @real_y )
    direction = 0
    direction = 2 if ay2 > ay1
    direction = 4 if ax2 < ax1
    direction = 6 if ax2 > ax1
    direction = 8 if ay2 < ay1
    distance = case direction
               when 2,8
                 $game_map.screen_tile_y
               when 4,6
                 $game_map.screen_tile_x
               else
                 0
               end
    if direction > 0
      $game_map.start_scroll( direction, distance, De79Zelda::SCROLL_SPEED )
      De79Zelda.wait_processing = true if De79Zelda::WAIT_FOR_SCROLL
    end
  end
 
  def modw(x)
    return (x.to_f / ($game_map.screen_tile_x)).to_i
  end
 
  def modh(y)
    return (y.to_f / ($game_map.screen_tile_y)).to_i
  end
end
Последнее редактирование: 7 года 3 мес. назад от DeadElf79.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Lekste, Kerotan, Демий, Jas6666, yuryol, Paranoid

Зельда-скроллинг 7 года 4 мес. назад #95092

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Программист RubyПобедитель Сбитой кодировки2 место ГотвОраторУчитель
Я правильно понимаю, что ты грузишь карту каждый апдейт Game_Player?
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79

Зельда-скроллинг 7 года 4 мес. назад #95093

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Ты правильно понимаешь. Пойду перетащу метод проверки карты в ее родной класс.
Писал, не надеясь, что всё будет работать, поэтому, когда всё-таки заработало, я так обрадовался, что забыл поправить.

Еще из обнаруженного:
У скрипта есть некий баг при работе с картами, имеющими параметр "Scroll type: Both Loop", но я пока не наю, как поправить.

Так что я просто поправлю чтение параметра карты и оставлю дальнейшие апдейты на "когда припечёт".
UPD: как раз залил код, наслаждайтесь.
Последнее редактирование: 7 года 4 мес. назад от DeadElf79.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 4 мес. назад #95096

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
Скрипт не стопорит игру при переходе, что немного смущает.
Плюс если карта не ограничена, прокрутка продолжается и персонаж просто исчезает за пределами камеры.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 4 мес. назад #95097

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Paranoid пишет:
Скрипт не стопорит игру при переходе, что немного смущает.
если найдется человек, который знает, как заморозить игру на время прокрутки - буду рад. у меня тут есть только одна идея, как это сделать, но придется перекопать много своих старых проектов, чтобы найти похожий скрипт. займусь как будет время.
Paranoid пишет:
Плюс если карта не ограничена, прокрутка продолжается и персонаж просто исчезает за пределами камеры.
да, это баг, я о нем писал в посте выше. я пока не знаю, как это исправлять, видимо, придется пихать море условий.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 4 мес. назад #95098

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
Нашел похожий скрипты, может поможет чем-нибудь
forums.rpgmakerweb.com/index.php?/topic/...lly-cohesive-camera/
www.rpgmakercentral.com/topic/22712-zelda-scrolling/

Можно просто запустить какое-нибудь событие, на время прокрутки.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79

Зельда-скроллинг 7 года 4 мес. назад #95104

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Спасибо, гляну на то, как другие ребята реализовали этот эффект как только будет время)
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 4 мес. назад #95120

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
Вот, кстати еще один вариант скроллинга - rmrk.net/index.php?topic=47697.0
Только здесь происходит перемещение игрока.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79

Зельда-скроллинг 7 года 4 мес. назад #95176

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Исправил ошибку с задержкой во время скроллинга, а заодно добавил коротюсенький модуль настроек.

Благодаря ссылкам от Параноида (за что ему отдельное спасибо), пересмотрел несколько вариантов решений и понял, что два из них бесполезны, а последнее я посмотрел в гифке, почитал мудренный код и решил не использовать.
Но решение с использованием события во время прокрутки меня натолкнуло на мысль использовать нечто подобное. И я использовал скрипты, которые переключают состояние ожидания на вкл/выкл во время скроллинга. Также саму задержку игрока на месте на время скролла я вынес в настройки, так что можно ее выключить, если кому-то она не нужна.
UPD: Исправил еще одну ошибку, которую смог получить лишь после того, как начал перемещаться с карты на карту - при перемещении на зельдо-карту неправильно выставлялась позиция карты, отчего происходило смещение. Вот, кстати, может поэтому с картами со Scroll Type: Both была такая ошибка. Проверю, когда будет время.
Последнее редактирование: 7 года 4 мес. назад от DeadElf79.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Kerotan, Демий

Зельда-скроллинг 7 года 3 мес. назад #95690

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Добавил для ивентов специфичную проверку того, находится ли ивент на экране, мало ли кому пригодится. Обновил код в топике.
UPD: Пофиксил ту же функцию по координатам.
Последнее редактирование: 7 года 3 мес. назад от DeadElf79.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 3 мес. назад #95704

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
Что-то не нашел в коде ничего такого, можно пояснить? Я так понял, если событие на не на игровом экране, то оно не подгружается в память или что?
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 3 мес. назад #95707

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 3 местоВетеран1 место в ГотвУчительПисатель 3 местоПроект месяца 2 местоПрограммист RubyПроект месяца 1 местоОрганизатор конкурсов
Пар, добавленный метод для класса Game_Event называется "on_screen?". Сам по себе нигде не используется встроенными стандартными скриптами, но мне он нужен был, чтобы контролировать спавн ивентов, который происходит за счет фабрики событий (если событие находится на экране с игроком, то спавнить стрелы). Сделал это обновление для тех, кто тоже использует нечто подобное. Сугубо специфичная вещь ^_^
Последнее редактирование: 7 года 3 мес. назад от DeadElf79.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 3 мес. назад #95708

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
О, теперь ясно. Спасибо.
Администратор запретил публиковать записи гостям.

Зельда-скроллинг 7 года 1 мес. назад #97003

  • Paranoid
  • Paranoid аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 688
  • Спасибо получено: 350
Не знаю прочтет ли Эльф, но лучше напишу в саму тему.
Собственно возникла небольшая проблема со скриптом при использовании пиксельного перемещения от Виктора. В право и вниз скроллит нормально. А вот влево и вверх персонаж скроллится еще находясь на клетке предыдущего экрана, то бишь его не видно на новом экране.

Еще хотелось бы иметь опцию отключения графики ивентов. Типа того как было в зельде, чтобы не видеть врагов пока не закончится скролл. Ну и скриптовую команду для проверки находится игрок на одном экране с ивентом или нет. Ты уже писал выше что такая команда уже есть, но хотелось бы иметь возможность совершать проверку и внутри ивента. Чтобы, например, ивент не видел тебя пока ты не пройдешь на его экран.
Администратор запретил публиковать записи гостям.
Модераторы: NeKotZima
Время создания страницы: 0.228 секунд