Показано с 1 по 10 из 23

Тема: Big events

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию Big events

    BIG Events script (XP, VX ACE)
    Автор: caveman
    Версия: 1.1
    Тип: Упрощение работы с событиями




    Описание:

    Cкрипт для облегченного создания событий с большой графикой.

    Особенности:

    • Позволяет задать для события Bounding Box (в тайлах) как методом, так и в комментарии к событию
    • Проверяет взаимодействие с событием исходя из заданного Bounding Box
    • Легкость в использовании


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

    Поковырявшись в гугле, нашел вот это:
    www.rpgmakervx.net/index.php?showtopic=53123

    Но это VX, а не XP и, имхо, он имеет некоторые недостатки (а именно, недостаточно типов распространения большести - только в одну сторону, либо ромбом)
    Спойлер ascii картинки:

    Код:
    #  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


    Поэтому я написал небольшой скрипт, который позволяет задать ограничивающий прямоугольник события в любую сторону:

    Скрипт XP:
    Спойлер Код:

    Код:
    # BIG events script XP
    # author: caveman
    # version 1.2.2
    # This script allows you to make big events with rectangle bounding box (bbox)
    # around its. It calculate collisions correctly also for turns any direction
    # 
    # Use this script to make teleport blocks or events with gross graphics 
    # (for example, Big Monsters)
    #
    # Examples:
    # $game_map.set_touch_shifts(ev_id, 1, 1, 2, 0) set by method
    # [bbox|1|1|2|0] - comment in event page as analog
     
    class Game_Character
      # all new attributes are "shifts" from initial event tile 
      # (left, right, up, down), if event "looking" down.
      #
      #            x
      #           xEx
      #            x
      #
      attr_accessor :x_sub # shift to left
      attr_accessor :x_add # shift to right
      attr_accessor :y_sub # shift to up
      attr_accessor :y_add # shift to down
     
      alias bigevent_initialize initialize
      def initialize
        @x_sub=0
        @x_add=0
        @y_sub=0
        @y_add=0
        bigevent_initialize
      end
      
      # parse comment from event page to setup the bbox 
      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
      
      # setting bbox manually
      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
      
      # new method for calculate collision
      def event_touch(x, y)
        case @direction
        when 2
          x_s = x_sub
          x_a = x_add
          y_s = y_sub
          y_a = y_add
        when 4
          x_s = y_add
          x_a = y_sub
          y_s = x_sub
          y_a = x_add
        when 6
          x_s = y_sub
          x_a = y_add
          y_s = x_add
          y_a = x_sub
        when 8
          x_s = x_add
          x_a = x_sub
          y_s = y_add
          y_a = y_sub
        end
        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
     
      alias bigevent_passable? passable?
      def passable?(x, y, d)
        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.id != @id
            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
        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_Event
      alias big_event_refresh refresh
      def refresh
        big_event_refresh
        setup_boxes(@page.nil?)
      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_trigger?
              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_trigger?
              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_trigger?
                  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
     
      # setting bbox manually
      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


    Скрипт VX ACE:
    Спойлер Код:

    Код:
    # BIG events script VX ACE
    # author: caveman
    # version 1.1
    # This script allows you to make big events with rectangle bounding box (bbox)
    # around its. It calculate collisions correctly also for turns any direction
    # 
    # Use this script to make teleport blocks or events with gross graphics 
    # (for example, Big Monsters)
    #
    # Examples:
    # $game_map.set_touch_shifts(ev_id, 1, 1, 2, 0) set by method
    # [bbox|1|1|2|0] - comment in event page as analog
     
    
    # =========================================================
    #                          Game_CharacterBase
    # =========================================================
    class Game_CharacterBase
      # all new attributes are "shifts" from initial event tile 
      # (left, right, up, down), if event "looking" down.
      #
      #            x
      #           xEx
      #            x
      #
      attr_accessor :x_sub # shift to left
      attr_accessor :x_add # shift to right
      attr_accessor :y_sub # shift to up
      attr_accessor :y_add # shift to down
     
      # alias init
      alias bigevent_initialize initialize
      def initialize
        @x_sub=0
        @x_add=0
        @y_sub=0
        @y_add=0
        bigevent_initialize
      end
     
      # parse comment from event page to setup the bbox 
      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
     
      # setting bbox manually
      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
     
      # new method to calculate collision
      def pos?(x, y)
        case @direction
        when 2
          x_s = x_sub
          x_a = x_add
          y_s = y_sub
          y_a = y_add
        when 4
          x_s = y_add
          x_a = y_sub
          y_s = x_sub
          y_a = x_add
        when 6
          x_s = y_sub
          x_a = y_add
          y_s = x_add
          y_a = x_sub
        when 8
          x_s = x_add
          x_a = x_sub
          y_s = y_add
          y_a = y_sub
        end
        
        for i in @x - x_s..@x + x_a
          for j in @y - y_s..@y + y_a
            if x == i && y == j
              return true
            end
          end
        end
        return false
      end
      
      def collide_with_events?(x, y)
        $game_map.events_xy_nt(x, y).any? do |event|
          event.id != @id && (event.normal_priority? || self.is_a?(Game_Event))
        end
      end
    end
     
    # =========================================================
    #                          Game_Event
    # =========================================================
    class Game_Event
      alias big_event_refresh refresh
      def refresh
        big_event_refresh
        setup_boxes(@page.nil?)
      end
    end
     
    # =========================================================
    #                          Game_Map
    # =========================================================
    class Game_Map
      # setting bbox manually
      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



    Использование:

    Скрипт позволяет в коде (например авторана карты) или прямо в комментарии события задать Bounding Box.
    1) game_map.set_touch_shifts(ev_id, x_sub, x_add, y_sub, y_add), где параметры: номер события, сдвиг влево, сдвиг вправо, сдвиг вверх, сдвиг вниз - от настоящего местоположения события.
    2) [bbox|x_sub|x_add|y_sub|y_add] - аналог комментарием прямо в нужном событии

    Например, для
    tut2.png

    метод такой: game_map.set_touch_shifts(ev_id, 1, 1, 2, 0)
    аналог комментария в событии - строка [bbox|1|1|2|0]

    Тут приложена демка, где используется этот метод.

    http://yadi.sk/d/JwHY-u1cJmzFE для XP
    http://yadi.sk/d/hBpzydDE65O3E для VX ACE
    http://yadi.sk/d/KWHPHwp5Jj7om версия 1.1 для VX ACE
    Последний раз редактировалось caveman; 02.03.2014 в 11:44. Причина: версия для xp 1.2.2
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 3 (пользователей: 0 , гостей: 3)

Метки этой темы

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  
Big events