for i in x loop[Resolved]

Started by chaucer, August 03, 2014, 10:01:11 pm

Previous topic - Next topic

chaucer

August 03, 2014, 10:01:11 pm Last Edit: August 03, 2014, 10:16:45 pm by chaucer
Hello, I've recently been working on a hud, and I didnt want to write out the same methods over and over, so I'm trying to use
Spoiler: ShowHide
for i in x

loop to draw out save some space, however I seem to be getting a small problem. Here's the code I used

for i in (0..4)
     @background_image = Sprite.new
     @background_image.bitmap = Bitmap.new(78,30)
     @background_image.bitmap.fill_rect(0, 0, 78, 30, Color.new(0, 0, 0,128))
     @background_image.x = NewHUD::HUD_X
     @background_image.y = NewHUD::HUD_Y + (30 + 1) * i
     @background_image.z = 1000
   end

it works, for a few seconds, and then everything except the last iteration is deleted from the screen, I'm not sure why, hope someone could help explain this to me am I missing something here? I also tried
(0..4).each do |i|

however the result is the same. :(

LiTTleDRAgo

it should be


@background_image = []
for i in (0..4)
  @background_image[i] = Sprite.new   
  @background_image[i].bitmap = Bitmap.new(78,30)
  @background_image[i].bitmap.fill_rect(0, 0, 78, 30, Color.new(0, 0, 0,128))
  @background_image[i].x = NewHUD::HUD_X
  @background_image[i].y = NewHUD::HUD_Y + (30 + 1) * i
  @background_image[i].z = 1000
end

ForeverZer0

Because you are just setting the same @background_image every time in the loop. You need to make it an array of background images, and then do something like this:

@background_images = []

(0..4).each {|i|
 @background_images[i] = Sprite.new
 @background_images[i].bitmap = Bitmap.new(78,30)
 @background_images[i].bitmap.fill_rect(0, 0, 78, 30, Color.new(0, 0, 0,128))
 @background_images[i].x = NewHUD::HUD_X
 @background_images[i].y = NewHUD::HUD_Y + (30 + 1) * i
 @background_images[i].z = 1000
}



EDIT: Too slow....
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

chaucer

Haha, thanks both littledrago & f0, that worked perfect!

ForeverZer0

And remember you have to dispose ALL the sprites as well, also in a loop.

@background_images.each {|sprite| sprite.dispose }
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

chaucer

ty again i was just wondering about disposing of them too, also if it's not too off topic to ask what is the difference between these 2 loops, they both seem to have the same function, and i cant tell any difference i read quite a  bit into them but I still don't get it.

(x..xx).each do |i|


&

for i in (x..xx)

Cremno

for i in 1..3 do end
p i  #=> 3
(1..3).each do |j| end
p j # => NameError: undefined local variable or method `j' for main:Object


You can also write (which is much clearer than for-loops and #each):
1.upto(3) { |i| do_something(i) }

ForeverZer0

There are some very minor differences.

In a for..end loop, variables created within will still exist within the outer scope of the loop after the loop ends.

for i in (1..3) 
  variable = 6
end

# "variable" can be used here, even though it was FIRST created in the loop.


The same would not work in a block.

(1..3).each {|i| variable = 6 }

# "variable" is undefined here.


Typically this is never an issue, and you can use the two interchangeably. If the above scenario ever did occur, you could still use a block in thsi way.

variable = nil
(1..3).each {|i| variable = 6 }

# "variable" is now 6


I personally prefer the the block, it's cleaner in my opinion, and easier to match the braces than with all the other "end" in a Ruby file.

There is also one other matter of precedence:
QuoteBraces have a high precedence; do has a low precedence. If the method invocation has parameters that are not enclosed in parentheses, the brace form of a block will bind to the last parameter, not to the overall invocation. The do form will bind to the invocation.


http://phrogz.net/ProgrammingRuby/language.html#blocksclosuresandprocobjects
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ryex

August 04, 2014, 01:15:33 am #8 Last Edit: August 04, 2014, 01:19:43 am by Ryex
it's worth noting that as far as ruby is concerned both versions map to exactly the same method. The `for i in x` construct is just syntax sugar for the `x.each { |i| }` method call.

that is if you made an object and properly implemented an iterator named  `each` it would be called when you use `for i in x`

for example

class MyRange
   attr_accessor :min, :max
   def initialize(min, max)
       self.min = min
       self.max = max
   end
   def each
       i = self.min
       while i < self.max
           yield i
           i += 1
       end
   end
end

#create a custom non-inclusive range class
r = MyRange.new(0, 5)

for i in r
   print i
end
=> 01234

r.each {|i| print i }
=> 01234


in both cases the each method of `r` is called and passed a block to print out every `i` yielded to the block.
the difference is whether or not a new scope is declared
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

chaucer

thank,you, very indepth ._. I couldnt have asked for a better description! on that note i got a few minor changes to make. :D