Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

HBGames

This is a class for scripters who for whatever reason want to have a command window display in a ring, obviously you could make a ring menu system, but with some creative thinking you could for example make a safe opening minigame without too much difficulty.

Anyway here's the script:
Code:
class Window_Ring_Command < Window_Base
  
  attr_accessor :index
  
  Turn_Frames = 20
  
  def initialize(x_pos, y_pos, commands, radius = 150.0)
    super(0, 0, 640, 480)
    @x_pos = x_pos
    @y_pos = y_pos
    @commands = commands
    @index = 0
    @moving = 0
    @radius = radius
    @radius = radius
    self.contents = Bitmap.new(width-32, height-32)
    self.opacity = 0
    refresh
  end
  
  def update
    super
    if @moving != 0
      refresh
    end
  end
  
  def refresh
    self.contents.clear
    if @moving != 0
      @moving = (Math.abs(@moving) - 1) * (@moving/Math.abs(@moving))
    end
    max_item = @commands.size
    pi_part = (2 * Math::PI) / max_item
    for i in 0...max_item
      x = (@radius * Math.sin((i * pi_part) + (@moving * (pi_part/Turn_Frames)))) + @x_pos
      x = x.to_i
      y = (@radius * Math.cos((i * pi_part) + (@moving * (pi_part/Turn_Frames)))) + @y_pos
      y = y.to_i
      draw_item(x, y, i)
    end
  end
  
  def draw_item(x, y, i)
    k = i + @index
    if k >= @commands.size
      k -= @commands.size
    end
    self.contents.draw_text(x, y, 150, 32, @commands[k])
  end
  
  def move_right
    @index += 1
    if @index >= @commands.size
      @index -= @commands.size
    end
    @moving += Turn_Frames
  end
  
  def move_left
    @index -= 1
    if @index < 0
      @index += @commands.size
    end
    @moving -= Turn_Frames
  end
  
  def moving?
    return @moving != 0
  end
  
end

module Math
  
  def self.abs(x)
    if x >= 0
      return x
    else
      return -1 * x
    end
  end
  
end

To use the constant Turn_Frames is how many frames or whatever you want to call them it takes to rotate to the next option in the command window.
The paranthesis when initialising are:

x_pos - The x co-ordinate of the ring/circle (CENTRE)
y_pos - The y co-ordinate of the ring/circle (CENTRE)
commands - The commands you want in the rung
radius = 150.0 - Basically you don't have to bother with this unless you want a smaller or larger ring/circle.

The methods you need to know:
update - call it as you would a normal command window
moving? - use this if you want to check if the menu is rotating (ie to stop them pushing left again)
move_left - moves the menu left (equivelent of up on a normal command window)
move_right - moves the menu left (equivelent of down on a normal command window).

I hope this is of use to someone, I'm willing to help and maybe make a few examples of how to use this if needed, but I'm busy with college work at the moment so don't expect speedy responces.

Add-Ons
Choices in a ring menu.

Script:
Code:
class Game_Temp
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :choices
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  alias choices_initialize initialize
  def initialize
    choices_initialize
    @choices = []
  end
end


class Interpreter
  #--------------------------------------------------------------------------
  # * Setup Choices
  #--------------------------------------------------------------------------
  def setup_choices(parameters)
    # Set choice item count to choice_max
    $game_temp.choice_max = parameters[0].size
    # Set choice to message_text
    $game_temp.choices = []
    for text in parameters[0]
      $game_temp.choices.push(text)
    end
    # Set cancel processing
    $game_temp.choice_cancel_type = parameters[1]
    # Set callback
    current_indent = @list[@index].indent
    $game_temp.choice_proc = Proc.new { |n| @branch[current_indent] = n }
  end
end


class Window_Message < Window_Selectable
  #--------------------------------------------------------------------------
  # * Terminate Message
  #--------------------------------------------------------------------------
  alias choices_terminate terminate_message
  def terminate_message
    choices_terminate
    if @choice_window != nil
      @choice_window.dispose
      @choice_window = nil
    end
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    self.contents.font.color = normal_color
    x = y = 0
    @cursor_width = 0
    # Indent if choice
    if $game_temp.choice_start == 0
      x = 8
    end
    # If waiting for a message to be displayed
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # Control text processing
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
      end
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      # Get 1 text character in c (loop until unable to get text)
      while ((c = text.slice!(/./m)) != nil)
        # If \\
        if c == "\000"
          # Return to original text
          c = "\\"
        end
        # If \C[n]
        if c == "\001"
          # Change text color
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
            self.contents.font.color = text_color(color)
          end
          # go to next text
          next
        end
        # If \G
        if c == "\002"
          # Make gold window
          if @gold_window == nil
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else
              @gold_window.y = self.y >= 128 ? 32 : 384
            end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          # go to next text
          next
        end
        # If new line text
        if c == "\n"
          # Update cursor width if choice
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          # Add 1 to y
          y += 1
          x = 0
          # Indent if choice
          if y >= $game_temp.choice_start
            x = 8
          end
          # go to next text
          next
        end
        # Draw text
        self.contents.draw_text(4 + x, 32 * y, 40, 32, c)
        # Add x to drawn text width
        x += self.contents.text_size(c).width
      end
    end
    # If choice
    if $game_temp.choice_max > 0
      
      # EDIT
      
      
      @choice_window = Window_Ring_Command.new(280, 180, $game_temp.choices,60)
      
      # /EDIT
      
    end
    # If number input
    if $game_temp.num_input_variable_id > 0
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If fade in
    if @fade_in
      self.contents_opacity += 24
      if @input_number_window != nil
        @input_number_window.contents_opacity += 24
      end
      if self.contents_opacity == 255
        @fade_in = false
      end
      return
    end
    # If inputting number
    if @input_number_window != nil
      @input_number_window.update
      # Confirm
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        $game_variables[$game_temp.num_input_variable_id] =
          @input_number_window.number
        $game_map.need_refresh = true
        # Dispose of number input window
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    
    
    # EDIT
    
    if @choice_window != nil
      @choice_window.update
      if Input.trigger?(Input::LEFT)
        unless @choice_window.moving?
          @choice_window.move_left
        end
      end
      if Input.trigger?(Input::RIGHT)
        unless @choice_window.moving?
          @choice_window.move_right
        end
      end
    end
    
    
    # /EDIT
    
    
    
    # If message is being displayed
    if @contents_showing
      # If choice isn't being displayed, show pause sign
      if $game_temp.choice_max == 0
        self.pause = true
      end
      # Cancel
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      end
      # Confirm
      if Input.trigger?(Input::C)
        if $game_temp.choice_max > 0
          $game_system.se_play($data_system.decision_se)
          
          
          # EDIT
          
          
          $game_temp.choice_proc.call(@choice_window.index)
          
          
          # /EDIT
          
        end
        terminate_message
      end
      return
    end
    # If display wait message or choice exists when not fading out
    if @fade_out == false and $game_temp.message_text != nil
      @contents_showing = true
      $game_temp.message_window_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      if @input_number_window != nil
        @input_number_window.contents_opacity = 0
      end
      @fade_in = true
      return
    end
    # If message which should be displayed is not shown, but window is visible
    if self.visible
      @fade_out = true
      self.opacity -= 48
      if self.opacity == 0
        self.visible = false
        @fade_out = false
        $game_temp.message_window_showing = false
      end
      return
    end
  end
  
end


Background Windows add-on

Code:
class Window_Ring_Command < Window_Base
  
  alias background_windows_initialize initialize
  def initialize(x_pos, y_pos, commands, radius = 150.0)
    @windows = []
    background_windows_initialize(x_pos, y_pos, commands, radius = 150.0)
  end
  
  def refresh
    self.contents.clear
    unless @windows == []
      for i in 0...@windows.size
        @windows[i].dispose
        @windows[i] = nil
      end
      @windows = []
    end
    if @moving != 0
      @moving = (Math.abs(@moving) - 1) * (@moving/Math.abs(@moving))
    end
    max_item = @commands.size
    pi_part = (2 * Math::PI) / max_item
    for i in 0...max_item
      x = (@radius * Math.sin((i * pi_part) + (@moving * (pi_part/Turn_Frames)))) + @x_pos
      x = x.to_i
      y = (@radius * Math.cos((i * pi_part) + (@moving * (pi_part/Turn_Frames)))) + @y_pos
      y = y.to_i
      @windows[@windows.size] = Window_Base.new(x, y, 158, 50)
      draw_item(x, y, i)
    end
  end
  
  def dispose
    unless @windows == []
      for i in 0...@windows.size
        @windows[i].dispose
        @windows[i] = nil
      end
      @windows = []
    end
    super
  end
  
end

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top