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.

creating a new array from pieces of another [resolved]

ok, so i have this array: Sub::Towns and i want to pull out all of the items in that array that have the trait Sub::Towns.upper_level = "String" and put them into a new array. to be honest i have no idea where to even start.
 
If you want to delete items from one array, and move to the other,
don't do this:
Code:
for item in my_arr

 my_arr.delete(item) if (some_condition)

end

It'll destroy the flow of the loop and some items will never be checked.
Do something like:
Code:
   for item in arr1

    items_to_relocate.push(item) if (some_condition)

  end

  for item in items_to_relocate

    arr1.delete(item)

    arr2.push(item)

  end
 
i dont want to delete the data for i will be using it again later for something else. maybe if i supply my data structure that will help.
Code:
class Data::Object

  @@ids = {}

  @@containers = {}

  attr_accessor :id

  def initialize

    @@ids[self.class] = 0 unless @@ids.has_key?(self.class)

    @@ids[self.class] += 1

    @id = @@ids[self.class]

    if @@containers.has_key?(self.class)

      @@containers[self.class][@id] = self

    end

  end

  def self.add_container(class_name, container)

    @@containers[class_name] = container

  end

end
Code:
class Sub::Town < Data::Object

  Data::Object.add_container(self, Sub::Towns)

  attr_reader :screen_x

  attr_reader :screen_y

  attr_reader :map_id

  attr_reader :map_x

  attr_reader :map_y

  attr_reader :direction

  attr_reader :icon

  attr_reader :town_name

  attr_reader :switch

  attr_reader :upper_level

  def initialize(screen_x, screen_y, map_id, map_x, map_y, direction, icon, town_name, switch, upper_level)

   super()

    @screen_x = screen_x

    @screen_y = screen_y

    @map_id = map_id

    @map_x = map_x

    @map_y = map_y

    @direction = direction

    @icon = icon

    @town_name = town_name

    @switch = switch

    @upper_level = upper_level

  end

  def self.screen_x

    return @screen_x

  end 

  def self.screen_y

    return @screen_y

  end 

  def self.map_id

    return @map_id

  end 

  def self.map_x

    return @map_x

  end 

  def self.map_y

    return @map_y

  end 

  def self.direction

    return @direction

  end 

  def self.icon

    return @icon

  end 

  def self.town_name

    return @town_name

  end 

  def self.switch

    return @switch

  end 

  def self.upper_level

    return @upper_level

  end 

end
so what im trying to do, is pull out the data i need temporarily and put it into a new array so i can use it to draw all the info to the screen. the reason i need a new array is because i only want to draw the data based on which "upper_level" im looking at. that make more sense?
 
I'm confused.
What exactly is the problem? You don't have to delete anything, Just follow my example without the line: arr1.delete(item)
Also you don't need all the methods below initialize. The attr_reader lines give you access to screen_x, screen_y, map_id, map_x, map_y and upper_level. currently, your methods do nothing.
 
thanks for the info about the methods, but im still dont understand your logic for my arrays. the way i understand it all i need is:
Code:
 

for i in 1...Sub::Towns.size+1

   if Sub::Towns[i].upper_level == @upper

     @section.push(Sub::Towns[i])

   end  

end
but that doesnt work...bleh. i really appreciate the help. i have to go to work now. hopefully when i get home it will all make sense :) if u know what im doing wrong let me know please :) have a good day/night
 
so here is the method as im using it:
Code:
 

def make_section

    for i in 1...Sub::Towns.size+1

      if Sub::Towns[i].upper_level == @upper

        @section.push(Sub::Towns[i])

        print(@section.size.to_s)

      end  

    end  

end
i added print so i could see it add each section. but in another method down the line i get the: "undefined method 'size' for nil:NilClass" error. here is that method:
Code:
 

def draw_towns

    for i in [email=1...@section.size]1...@section.size[/email] #line i get error on

      <draw_towns logic>

    end

  end
any advice? :)
 
its quite long and i havent started to switch the format of any other methods, but here it is:
Code:
 

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

# ** Sub_Map 

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

#  Script by            :   Plague180

#  Last Update          :   April 26, 2010

#  Version              :   1.0

#  Contact Information  :   plague180([url=http://www.hbgames.org]http://www.hbgames.org[/url])

#  Contact Information  :   [email=plague180@yahoo.com]plague180@yahoo.com[/email]

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

# May 9, 2010 - Version 1.0 Release

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

 

class Sub_Map < World_Map

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

  # * Object Initialization

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

  def initialize(upper="")

    super()

    @section = []

    self.contents = Bitmap.new(640-32, 480-32)

    self.z = 2010

    self.opacity = 0

    @upper = upper

    @draw_player = true

    @start = $game_map.map_id

    @pindex = first_check

    @cursor = Sprite_Cursor.new()

    @cursor.bitmap = RPG::Cache.icon(Map_Items::CURSOR)

    @cursor.z = 2020 

    if Map_Items::CURSOR_TYPE == 2

     @cursor.x = Sub::Towns[@pindex].screen_x + RPG::Cache.icon(Sub::Towns[@pindex].icon).width/4

     @cursor.y = Sub::Towns[@pindex].screen_y + RPG::Cache.icon(Sub::Towns[@pindex].icon).height

     @cursor.z = 2020

   end  

  if second_check != true

    @draw_player = false

  end  

  make_section

  refresh

end

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

  # * find map to start on(for cursor)

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

  def make_section

    for i in 1...Sub::Towns.size+1

      if Sub::Towns[i].upper_level == @upper

        @section.push(Sub::Towns[i])

        print(@section.size.to_s)

      end  

    end  

  end 

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

  # * find map to start on(for cursor)

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

  def first_check

    for i in 1...Sub::Towns.size+1

      if $game_switches[Sub::Towns[i].switch] == true 

        return i

      end 

    end  

  end 

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

  # * Check to see if the player is on a valid map(inside of Sub::Towns)

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

  def second_check

    for i in 1...Sub::Towns.size+1

      if Sub::Towns[i].map_id == $game_map.map_id 

        if $game_switches[Sub::Towns[i].switch] == true 

          return true

        end  

      end  

    end  

  end 

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

  # * Move Player To New Map

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

  def move(index=0)

      $game_system.se_play(Map_Items::MOVE_SE)

      if Map_Items::CURSOR_TYPE == 1

        index = @pindex

      end

      Audio.bgm_fade(800)

      Audio.bgs_fade(800)

      Audio.me_fade(800)

      $game_temp.player_new_map_id = Sub::Towns[index].map_id

      $game_temp.player_new_x = Sub::Towns[index].map_x

      $game_temp.player_new_y = Sub::Towns[index].map_y

      $game_temp.player_new_direction = Sub::Towns[index].direction

      $game_temp.player_transferring = true

      $game_map.autoplay

      $scene = Scene_Map.new

  end 

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

  # * Check if can move(and do it if you can)

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

  def move_if_can

    for i in 1...Sub::Towns.size+1

      if @cursor.x > Sub::Towns[i].screen_x-Map_Items::PIXEL_OFFSET && @cursor.x < Sub::Towns[i].screen_x + RPG::Cache.icon(Sub::Towns[i].icon).width + Map_Items::PIXEL_OFFSET

        if @cursor.y > Sub::Towns[i].screen_y-Map_Items::PIXEL_OFFSET && @cursor.y < Sub::Towns[i].screen_y + RPG::Cache.icon(Sub::Towns[i].icon).height + Map_Items::PIXEL_OFFSET

          move(i)

        end

      end 

    end  

  end  

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

  # * Check if you can click on town, if so show name

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

  def check_name

      for i in 1...Sub::Towns.size+1

      if @cursor.x > Sub::Towns[i].screen_x - Map_Items::PIXEL_OFFSET && @cursor.x < Sub::Towns[i].screen_x + RPG::Cache.icon(Sub::Towns[i].icon).width + Map_Items::PIXEL_OFFSET

        if @cursor.y > Sub::Towns[i].screen_y - Map_Items::PIXEL_OFFSET && @cursor.y < Sub::Towns[i].screen_y + RPG::Cache.icon(Sub::Towns[i].icon).height + Map_Items::PIXEL_OFFSET

          self.contents.clear

          refresh 

          self.contents.font.size = 18

          self.contents.font.color = text_color(Map_Items::TOWN_TEXT_COLOR)

          cx = contents.text_size(Sub::Towns[i].town_name).width

          if $game_switches[Sub::Towns[i].switch] == true #unlocked?

            self.contents.draw_text(@cursor.x-cx/2,@cursor.y,cx,32,Sub::Towns[i].town_name)

          end   

        end

      end 

    end 

  end  

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

  # * Check if you can click on town, if so show name window

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

  def check_name_window

    for i in 1...Sub::Towns.size+1

      if @cursor.x > Sub::Towns[i].screen_x - Map_Items::PIXEL_OFFSET && @cursor.x < Sub::Towns[i].screen_x + RPG::Cache.icon(Sub::Towns[i].icon).width + Map_Items::PIXEL_OFFSET

        if @cursor.y > Sub::Towns[i].screen_y-Map_Items::PIXEL_OFFSET && @cursor.y < Sub::Towns[i].screen_y + RPG::Cache.icon(Sub::Towns[i].icon).height + Map_Items::PIXEL_OFFSET

          if $game_switches[Sub::Towns[i].switch] == true #unlocked?

            return Sub::Towns[i].town_name

          end

        end  

      end 

    end 

    return ""

  end 

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

  # * Move Cursor Right

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

  def move_cursor_right

      @pindex += 1

      if @pindex > Sub::Towns.size

        @pindex = 1

      end

      for i in 1...Sub::Towns.size+1

        if $game_switches[Sub::Towns[@pindex].switch] == false

          @pindex += 1

          if @pindex > Sub::Towns.size

            @pindex = 1

          end

        end 

      end

     refresh

   end 

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

  # * Move Cursor Left

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

  def move_cursor_left

      @pindex -= 1

      if @pindex < 1

        @pindex = Sub::Towns.size

      end 

      for i in 1...Sub::Towns.size+1

        if $game_switches[Sub::Towns[@pindex].switch] == false

          @pindex -= 1

           if @pindex < 1

             @pindex = Sub::Towns.size

           end 

        end

      end

      refresh

  end  

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

  # * Move Cursor Up

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

  def move_cursor_up

      @pindex += 1

      if @pindex > Sub::Towns.size

        @pindex = 1

      end

      for i in 1...Sub::Towns.size+1

        if $game_switches[Sub::Towns[@pindex].switch] == false

          @pindex += 1

          if @pindex > Sub::Towns.size

            @pindex = 1

          end

        end 

      end

     refresh

  end

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

  # * Move Cursor Down

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

  def move_cursor_down

      @pindex -= 1

      if @pindex < 1

        @pindex = Sub::Towns.size

      end 

      for i in 1...Sub::Towns.size+1

        if $game_switches[Sub::Towns[@pindex].switch] == false

          @pindex -= 1

           if @pindex < 1

             @pindex = Sub::Towns.size

           end 

        end

      end

      refresh

  end

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

  # * Draw Player

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

  def draw_player

      bitmap = RPG::Cache.icon(Map_Items::PLAYER_ICON) 

      @player_offset_x = Sub::Towns[@start].screen_x + ((RPG::Cache.icon(Sub::Towns[@start].icon).width / 2) - (bitmap.width / 2))

      @player_offset_y = Sub::Towns[@start].screen_y - bitmap.height

      self.contents.blt(@player_offset_x,@player_offset_y, bitmap, Rect.new(0,0,RPG::Cache.icon(Map_Items::PLAYER_ICON).height,RPG::Cache.icon(Map_Items::PLAYER_ICON).width)) 

  end 

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

  # * Draw Towns

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

  def draw_towns

    for i in [email=1...@section.size]1...@section.size[/email]

      if $game_switches[@section[i].switch] == true #unlocked?

        bitmap = RPG::Cache.icon(@section[i].icon) 

        self.contents.blt(@section[i].screen_x, @section[i].screen_y, bitmap, Rect.new(0,0,bitmap.width,bitmap.height))

      end 

    end

  end 

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

  # * Draw Cursor(i know this could be done better, will fix in update)

  #   been waiting too long to release this.

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

  def draw_cursor

     if Map_Items::CURSOR_TYPE == 1

        bitmap = @cursor.bitmap

        if $game_switches[Sub::Towns[@pindex].switch] == true

          if Sub::Towns[@pindex].icon != nil

            x = Sub::Towns[@pindex].screen_x + (RPG::Cache.icon(Sub::Towns[@pindex].icon).width/2)-(bitmap.width/2)

            y = Sub::Towns[@pindex].screen_y + (RPG::Cache.icon(Sub::Towns[@pindex].icon).height+3)

          end

        if Sub::Towns[@pindex].icon != nil

          self.contents.blt(x, y, bitmap, Rect.new(0,0,bitmap.height,bitmap.width))

        else

          self.contents.blt(Sub::Towns[@pindex].screen_x, Sub::Towns[@pindex].screen_y+bitmap.width, bitmap, Rect.new(0,0,bitmap.height,bitmap.width))

        end

        if Map_Items::NAME_STYLE == 1

          self.contents.font.size = 18

          cx = contents.text_size(Sub::Towns[@pindex].town_name).width

          x = Sub::Towns[@pindex].screen_x+(RPG::Cache.icon(Sub::Towns[@pindex].icon).width/2)-cx/2

          self.contents.font.color = text_color(Map_Items::TOWN_TEXT_COLOR)

          self.contents.draw_text(x,y,cx,32,Sub::Towns[@pindex].town_name)

        end

       end 

      end 

      if Map_Items::CURSOR_TYPE == 2

         bitmap = @cursor.bitmap

         self.contents.blt(@cursor.x, @cursor.y, bitmap, Rect.new(0,0,bitmap.height,bitmap.width))

      end  

    end 

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

  # * Check cursor bounds so it doesnt go off screen

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

  def check_cursor_bounds

     if @cursor.x < 0

       @cursor.x = 0

     end

     if @cursor.x > 640 - RPG::Cache.icon(Map_Items::CURSOR).width - 32

       @cursor.x = 640 - RPG::Cache.icon(Map_Items::CURSOR).width - 32

     end  

     if @cursor.y < 0

       @cursor.y = 0

     end

     if @cursor.y > 480 - RPG::Cache.icon(Map_Items::CURSOR).height - 32

       @cursor.y = 480 - RPG::Cache.icon(Map_Items::CURSOR).height - 32

     end 

  end  

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

  # * Refresh

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

  def refresh

    self.contents.clear

    check_cursor_bounds

    #draws player

    if Map_Items::SHOW_PLAYER == true

      if @draw_player == true

        draw_player

      end  

    end 

    #draws all towns

    draw_towns

    #draw cursor

    draw_cursor

    

  end

end #class
please ignore any mistakes in comments, working on getting this last bug out for release :)
 
It's weird you get the error only in make_section. initialize calls first_check before it calls make_section, and in line 57 first_check also refers to Sub::Towns.size
if Sub::Towns is nil, why don't you get an error on line 57?
Anyway, if the problem is doing .size on array set to nil, create a method (in Sub class) called self.towns_size that returns 0 when Towns is nil, and Towns.size otherwise.
Also, shouldn't you call make_section before calling first_check?
 
sub::Towns isnt nil it has 6 objects. i agree doing first_check first is smart, but doesnt effect the code in question. first check just finds if the town i start on is valid(because the overall script is a world_map script obviously and if the script only knows maps 1-7 and your on 8 it needs to know how to process this) hmmm, shall continue to play with code(moving make_section around and see if that helps, eta)
 
after aton of time spent researching, i think that the problem im getting is because of the class i inherit from because it calls refresh of the parent class before it calls make_section. so thats why it doesnt think that my array has any items, it hasent been filled yet. im switching over to Window_Base just as the parent class and gonna change everything and see if that helps, so far it seems to be working :( i feel so dumb ive only been tracing the last four moves before it crashed..going back 8 shows me the problem.

edit: tho that does bring up another issue. should i be able to do this: "@section[1].town_name" because it doesnt work... i hopw im just missing something
 
so we agree this is correct?
Code:
   #--------------------------------------------------------------------------

   # * find map to start on(for cursor)

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

   def make_section

     for i in 1...Sub::Towns.size+1

       if Sub::Towns[i].upper_level == @upper

         @section.push(Sub::Towns[i])

       end  

     end  

   end
but how would i access them?
if the norm is Sub::Towns[index].town_name
wouldnt the new format be: @section[index].town_name
that would be my thought. my next thought is
@section[Sub::Towns.town_name] but i know that logic is wrong, best case scenario it gives me the wrong index
but i assume it wont work anyways. btw im rebuilding the script i lost it. but if u need it let me know. im close to having it back to where it was (all 2000 lines, i know u posted on my rant post. so far its only taken about 10 hours. plus i left some of the hard part in a email to my freind for help :))
 
Actually, you need Sub::Towns.size, not Sub::Towns.size + 1. This is because the size will actually be 0 when there are no elements in an array, and will be 1 with one element, 2, with two elements, etc. With a for loop, it actually goes from the first number to one before the last number, when you feed it a range as the second argument. So for i in 0...10 will cycle through the loop ten times, where i starts out as 0 in the first iteration, and ends up as 9 in the last iteration.
 
that still doesnt fix the problem(and i use "+1" by habit because more then half my script i need such a loop) im still confused as to how to use the objects i put in the new array

edit: glitch u posted on my other post about this script im working on :) if i can start getting use out of this code, my script will be done :) i so cant wait to show u all(allthough my graphics for demo suck, anyone know a quick artist?)
 
yes im still getting that error, when i use the new code(even though ive proven it has 3 objects when its created) anyways im not 100% sure ive added everything back since the script crashed but it seems to be working stable(just the subsections dont work(properly), because i havent converted it to use the new code because i cant get draw_towns to work when i do) if u have any questions let me know, this is my last problem :) http://www.megaupload.com/?d=MCRQ8H0O

p.s. please note that when u load it there are 6 items in the subsection of map 1 or 2, there should only be 3 for each, thats why im trying to pull pieces out of the array
 

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