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.

Splitting an Array

I need a method in Ruby that lets me split an array into same-size groups. In example:

[0, 1, 2, 3, 4, 5].split(4) => [[0, 1, 2, 3], [4, 5]]

There's a method that does exactly this called in_groups_of(n), but I can't seem to get it to work.

Please. Someone help.
 

Atoa

Member

This method don't exist in RGSS. Maybe it belongs to an updated version of ruby, or is part of an library like MALC.

In fact, MALC is something you should check, it have some cool methods for some classes like Array. I woudn't use the whole MALC, but there's some methods worth looking.
 
Actually, I redid the whole concept, and it still doesn't work, but I'm definitely closer than before.

I'm trying to make a sprite which is updated to show all the skills an actor has learned in a license board. Since obviously most of the times there will be too many skills for a single page, the sprite should be able to show different content depending on the page index. Also, since there are several classes of skills, i.e., white magic, black magic, etc., the sprite should separate these skills in different groups.

It's giving me a big headache.

This is the sprite code so far.

Ruby:
#==============================================================================

# ** Sprite_LearnedSkills

#------------------------------------------------------------------------------

#  This sprite is used to display learned skills. It observes the Scene_Board

#  class and automatically changes sprite conditions.

#==============================================================================

 

class Sprite_LearnedSkills < RPG::Sprite

  #--------------------------------------------------------------------------

  # * Invariables

  #--------------------------------------------------------------------------

  include MedinaStories                   # Medina Stories module

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_accessor :page_total               # page total

  attr_accessor :page                     # current page

  attr_accessor :active                   # active

  #--------------------------------------------------------------------------

  # * Object Initialization

  #     actor    : actor

  #     board    : board

  #     viewport : viewport

  #--------------------------------------------------------------------------

  def initialize(actor, board, viewport=nil)

    super(viewport)

    self.bitmap = LEARNED_SKILLS.dup

    @actor = actor

    @board = board

    @skills = []

    @page_total = 1

    @page = 0

    @active = false

    @item_max = 0

    refresh

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    self.bitmap.clear

    self.bitmap = LEARNED_SKILLS.dup

    

    @skills = @board.skills.sort!

    classes = get_skill_classes(@skills)

    actor_skills = organize_skills(@skills, classes)

    all_skills = get_skills_total(@board)

    all_classes = get_skill_classes(all_skills)

    total_skills = organize_skills(all_skills, all_classes)

    

    @item_max = 4

    @page_total = all_skills.length / @item_max

    

    items = 0

    self.bitmap.draw_outline(420, 80, 160, 32, "Page #{@page} .. #{@page_total}")

    for i in 0...total_skills.length

      for j in 0...total_skills[i].length

        items += 1

        if not total_skills.empty?

          pos = @page * @item_max

          if items == pos or items == pos + @item_max

            self.bitmap.draw_skill_window_icon(classes, i)

          end

          if items >= pos and items < pos + @item_max

            self.bitmap.draw_skill_window_item(

                all_skills, total_skills, i, j, @page, @item_max)

          end

        end

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Get Total Skills

  #     board : board

  #--------------------------------------------------------------------------

  def get_skills_total(board)

    skills_total = []

    for x in 0...board.xsize

      for y in 0...board.ysize

        type = board.type?(x, y)

        if type == 8

          for i in 0..3

            value = board.value?(x, y, i)

            if value > 0

              skills_total.push(value)

            end

          end

        end

      end

    end

    return skills_total.sort!

  end

  #--------------------------------------------------------------------------

  # * Get Skill Classes

  #     skills : skills

  #--------------------------------------------------------------------------

  def get_skill_classes(skills)

    skill_classes = []

    skills.each {|skill_id|

      str = BOARD_CLASS(8, skill_id, nil).strip

      skill_classes.push(str) if not skill_classes.include?(str)

    }

    return skill_classes

  end

  #--------------------------------------------------------------------------

  # * Organize Skills

  #     skills        : skills

  #     skill_classes : skill classes

  #--------------------------------------------------------------------------

  def organize_skills(skills, skill_classes)

    skill_array = []

    for i in 0...skill_classes.length

      little_array = []

      if not skills.empty?

        for j in 0...skills.length

          str = BOARD_CLASS(8, skills[j], nil).strip

          little_array.push(skills[j]) if skill_classes[i] == str

        end

      end

      skill_array.push(little_array)

    end

    return skill_array

  end

end

These are the drawing methods.

Ruby:
#==============================================================================

# ** Bitmap

#------------------------------------------------------------------------------

#  The bitmap class. Bitmaps are expressions of so-called graphics.

#  Sprites and other objects must be used to display bitmaps on the screen.

#==============================================================================

 

class Bitmap

  #--------------------------------------------------------------------------

  # * Draw Skill Window Icon

  #     classes : classes

  #     id      : class ID

  #--------------------------------------------------------------------------

  def draw_skill_window_icon(classes, id)

    bitmap = Bitmap.new(64, 64)

    rect = Rect.new(0, 0, 64, 64)

    bitmap.blt(0, 0, RPG::Cache.picture(classes[id]), rect)

    self.blt(93, 82 + 128*id, bitmap, rect)

  end

  #--------------------------------------------------------------------------

  # * Draw Skill Window Item

  #     skills       : skills

  #     actor_skills : skills

  #     i            : class ID

  #     j            : skill ID

  #     page         : page

  #     item_max     : item max

  #--------------------------------------------------------------------------

  def draw_skill_window_item(skills, actor_skills, i, j, page, item_max)

    index = skills.index(actor_skills[i][j])

    x, y = 190, 114 + (index - page * item_max) * 32

    name = BOARD_ITEM(8, actor_skills[i][j]).name

    self.draw_outline(x, y, 130, 32, name)

  end

  #--------------------------------------------------------------------------

  # * Draw Outline

  #     x     : draw spot x-coordinate

  #     y     : draw spot y-coordinate

  #     w     : draw spot width

  #     h     : draw spot height

  #     text  : text string displayed

  #     align : alignment (0..flush left, 1..center, 2..flush right)

  #     color : text string color

  #--------------------------------------------------------------------------

  def draw_outline(x, y, w, h, text, align=0, color=Color.new(255, 255, 255))

    self.font.color = Color.new(0, 0, 0)

    self.draw_text(x,     y + 1, w, h, text, align)  # U

    self.draw_text(x - 1, y + 1, w, h, text, align)  # UL

    self.draw_text(x - 1, y,     w, h, text, align)  # L

    self.draw_text(x - 1, y - 1, w, h, text, align)  # DL

    self.draw_text(x,     y - 1, w, h, text, align)  # D

    self.draw_text(x + 1, y - 1, w, h, text, align)  # DR

    self.draw_text(x + 1, y,     w, h, text, align)  # R

    self.draw_text(x + 1, y + 1, w, h, text, align)  # UR

    self.font.color = color

    self.draw_text(x, y, w, h, text, align)

  end

end

I'm not showing the refreshing of the bitmap in the scene, because that's the easiest part, and it already works.
 
First of all, in_groups_of is a Rails method, of which you could grab the source code, look for the method, copy it over and be happy.

If you don't feel like doing that, this should help (untested and untidy, so maybe not working and most likely not the best way to do it):

[rgss]class Array < Object
 
  def split_into_groups_of(size)
    groups = []
    self.each { |item|
      if !groups.empty? && groups.last.is_a?(Array) && groups.last.size < 4
        groups.last.push(item)
      else
        groups.push([item])
      end
    }
    return groups
  end
 
end
[/rgss]

Edit: Heh, forgot half of it... if you tried it before, please try again >>
 

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