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
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
however the result is the same. :(
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
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....
Haha, thanks both littledrago & f0, that worked perfect!
And remember you have to dispose ALL the sprites as well, also in a loop.
@background_images.each {|sprite| sprite.dispose }
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.
&
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) }
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
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
thank,you, very indepth ._. I couldnt have asked for a better description! on that note i got a few minor changes to make. :D