If you need a tilemap class in Ruby, do have a look at my gosu-tmx. It's not complete, but contributors are welcome and encouraged.
Right now it loads TMX maps, of course, which can be made with the open source and cross platform Tiled. If I remember correctly, it doesn't handle maps where different layers have different tile sizes, but this could be added. It also only supports orthogonal maps, but these are probably what you want.
If you do make any changes, please let me know and send them back my way. :)
Well, as your tilemap is written in full ruby it won't be faster as a one I can write. And if I have the chance to write something on my own, I will always do it ;)
* source_select, source_ignore, dest_select, dest_ignore (select exactly which source/dest pixels are affected by drawing action) * support for Gosu::Color * hopefully fixed opengl crashing problem in some linux distros (using Gosu::MAX_TEXTURE_SIZE) * rows, columns, to_blob (enables Gosu::Image to be reopened using Gosu::Image.new() and load_tiles()) * bitwise drawing modes no longer affect alpha channels * Gosu::Image.from_text now patched to automatically cache the new image * optional :color parameter (sets background color) for TexPlay.create_image, e.g TexPlay.create_image(w, 500, 500, :color => Gosu::Color::GREEN)
great job ban! I'll get back to you on how :color_mode => :gosu works out for me in skrutt... should make my code less complex, so it's a welcome addition.
Is there any way to draw parts of circles using texplay? I know this functionality is available in RMagick, but would like the usability and speed of texplay. What I mean is, is there a way to draw, say, the path of a circle from the 30 degree position to the 153 degree position (just random numbers there)?
I'm trying to draw a bar for a video game which follows a circular arc. Thus, I need to draw a specific arc length to represent the character's stats.
Also, it would be nice to be able to draw ellipses as well as circles.
Well, I could do that with Chingu (a rubygem) where ippa included a circle drawing method that I modified to make it work like a HP or MP ring for RPG's.
Here's the code (you don't need to install chingu if you don't want to, this would still work since it depends on Gosu API).
Very nice, thank you so much. I believe you and I are both trying to accomplish the same thing, oddly enough. I will make a few changes to allow for a parameter to be sent to the method for the width of the ring, or perhaps give both the inner and outer radius. Regardless, this is a very good base. Still, if this code is to be included inside a class which descends from Gosu::Window, there is no need for all the explicit self calls before each method, nor the self.window calls. I will repost the code with these modifications after I make them.
Also, small complaint, but why does the method only accept 1, 2, or 4 colors? Why not any n colors?
Because those are the amounts of colors I needed... the self originally referred to KyoBasic module, the module I create to encapsulate all of "my (own or modified)" methods.
* :tolerance option (applies to :trace and :source_select (et al) families) e.g :color => [0.5, 0.5, 0.5, 1.0], :tolerance => 0.1 turns the color point [0.5,0.5,0.5,1.0] into a color sphere centered at the point with radius 0.1 * new :transparent pseudo-color (for use with :trace, and :source_select (et al)). Matches all colors with arbitrary rgb values but 0.0 alpha
"fixes" segfault in linux by hardcoding max texture size to 1024 (this should work on most linux systems, but on a minority of systems this will fail. Still, better than a segfault)
Gosu uses the same approach to avoid the segfault on Linux now, except I always return 512. This is the lowest value I have encountered myself in the last 5 years :) Can we settle on this more pessimistic constant? Or would you say from experience that most people need more?
I'm trying to use the :transparent colour matcher in order to clear "transparent but coloured" pixels out of an image so they are uniformly "transparent black" wherever the alpha channel is 0. I need to do this so that I can know that images that appear identical to the eye are the same, even if they have different "hidden" colour information in them. I'm trying to use:
:transparent matches no pixels in my image (coloured or black, transparent or opaque), so the image is not changed in any way. Using :dest_ignore instead matches all pixels and clears the whole image.
:dest_select seems to work fine with other specific colours though. I also tried:
with similar effects, where :transparent matched no pixels in my image. I am specifically using :trace to draw an outline around an image as well as to allow me to autocrop (both actions would take forever if done with get/set_pixel), but then I realised I needed to clear out all the coloured transparent areas anyway, so I don't need to use :transparent with :trace any more).
:trace and :dest_select seem to work fine with specific colours, including :alpha.
Any thoughts on this dilemma appreciated (whether I'm doing it wrong or if there is a bug in :transparent). Oh, and thanks for giving us really fast, amazingly versatile functionality like this in Ruby. Really helping me!
ok, pushed out a new 0.2.975 gem. should hopefully fix the tolerance issue, since the bug was quite glaring.... (i was checking color1.alpha <= tolerance rather than color2.alpha <= tolerance :D)
Thanks. Yes, I think I did consider that method, but assumed it would be only an order of magnitude faster than iterating through x and y and using getpixel/setpixel. That method was taking quite a few seconds and I need to import and clean up a potentially large number of images in a realistic time (something that should take a few frames per image, not seconds). The rect/:transparent method I wanted to use, although it didn't actually work when I tried it, was virtually instant, even for large images.
Ok, i pushed a new 0.2.980 gem, that provides greater control over caching (for improved speed and efficiency)
(1) adds :caching option (to both Gosu::Image.new and TexPlay.set_options... remember it only accepts true and false) (2) gets rid of auto-caching for TexPlay.create_image() (this should be a significant boost to some games) (3) also added TexPlay#clear method, it essentially just sticks a filled rect over an image, e.g img.clear :color => :red, :dest_select => :transparent is equivalent to: img.rect 0,0, width, height, :fill => true, :color => :red, :dest_select => :transparent
I would like to thank Mr. Banister for making TexPlay. It is a great complementary tool for Gosu. In my opinion, when it becomes more refined it should come with the standard Gosu library. One of the things I most like, its the macro function. Thats just pure genious. That said, I would like to share some input. Take in consideration I have only used the program for 2 days, so I may be mistaken.
1. get_pixel() function return an array of floats. Why is that? Why not an array of numbers from 0 to 255. The ‘set color’ works like this, why not the former? Sometimes this floats can get really long.
2. I notice that there can be errors if one manipulates the ‘load_tiles’ version of an image. What I do in my currect project is reload the image with the ‘ new’ version of the image and everything works fine. Example:
@tiles = Gosu::Image.load_tiles(window, ‘tileset.png’ , 32, 32, true) #trying to manipulate @tiles[0] is a failure, but… @tiles[0] = Gosu::Image.new(window, @tiles[0] , true) #now @tiles[0] can be manipulated; no problem
Anyway, I will share more later. Thanks once again.
(1) You can get your colors back as Gosu::Color by using get_pixel x, y, :color_mode => :gosu The reason why i made the design decision to return an array of floats was because that is how colors are stored internally and converting to another format would result in a performance hit --- perhaps not for one pixel, but imagine processing thousands of pixels consecutively -- converting the floats to ints or any other format would have significantly impacted on performance (:gosu => :color_mode already is 1.5 times slower than the float approach). Also i dont konw waht you mean by the 'set_color' works like this. TexPlay's color argument accepts many different color formats - though the float array approach is the oldest and possibly most common.
(2) I've never heard of this error before, can you provide more information about the error such as the error message, or even better, a tiny code sample that reproduces the problem? (preferably with the image you used available too)
Regarding 'macro', haha, i was thinking of retiring that method since i didn't think anyone used it *and* it doesn't really provide any extra functionality over and above define_singleton_method :)
While on the topic of advancements to TexPlay I'd like to have the ability to draw ellipses and the ability to get some anti-aliasing on curved shapes. (this is why I use both TexPlay and RMagick in fact).
Also, I agree, having TexPlay be included with Gosu as some sort of dependency or something would be pretty cool.
sure i can implement some ellipse functionality, anti-aliasing is quite straight forward too (i assume). I was also thinking of implementing some spline stuff to fill in the gaps of the very limited bezier curves. I'm thinking of doing another release fairly soon so if you want certain features pls file issues on github.com/banister/texplay as i tend to forget :)
I'll just mention this issue here instead of on GitHub as I see you already closed this issue, and I'm just looking for clarification.
Did you implement Gosu::Image#== or some similar method? I tried to call it, and it did not work. The method simply uses the default implementation (defined in object I believe) which is the same as #equal?. It's simple enough to just monkey-patch it in, but I just wanted to make sure this was not a bug.
Side note: Oddly enough, the first time I ran a test for this, the address for the clone had the letters "bad" in it. Just thought that was funny.
oops, i didn't mean to close it (reopened now). Yeah it's not implemented yet, it's coming soon though. I'll also take Spooner's advice and implement it as '#==' rather than '#compare'
Reminds me. Do you still use OpenGL to get pixel data out of Gosu's images? Or do you use to_blob? Would it simplify our combined codebase if I put some effort into making to_blob faster?
My thinking was that Image#== could just compare width, height and to_blob. But if TexPlay has already cached the image's contents, there's no need to call to_blob again, so there is at least a reason to have it in TexPlay *too*.
In pure Gosu, I am not so sure about the semantics. It should be consistent with TexPlay but how do I compare for identity then, which is usually enough? .equal? .eql? Man, it was hard enough to study these three for Scheme. ;)
Point[1, 1] NOT equal? Point[1, 1] (since they're different objects, even though they have the same value)
TP is still using OpenGL to get image data; is Gosu::Image#to_blob a lot faster? Doesn't it do the same thing internally though? caching images is still one of the most expensive operations so it would be good if this could be made faster. Though to_blob data is INT right? I'd still need to convert all the image date to floats, though im sure that's not so expensive.
I think the gems should be kept separate, Ruby is powerful enough to integrate them without any noticeable rough edges.
Where it makes sense, I already "include" TexPlay though. For example, the RubyGame.app template builds a three-way universal texplay.bundle for easier OS X deployment. (The problem is, sadly, that the .app itself is 10.6 only. That should be fixed in the next time.)
Oh yeah, totally agree that the gems should be separate, just thought Gosu could install TexPlay as well. But I guess some people might not want that, so it'd be better just to let them install the gems separately? I don't know ^_^;
TexPlay.create_macro(:alpha_set) { no_color = self.get_pixel(0,0) self.rect 0, 0, width, height, :fill => true, :color => :transparent, :dest_select => no_color } #so i want to use the first pixel as the alpha color, so i can use other images with tranparency besides (.bmp)s. If i use this the image become complete transparent, but if I 'reload' the image it works like intended.
I should also say I'm using hahses as cache like this: $cache[:image_no_alpha] = @img $cache[:image_with_alpha] = @img.alpha_set
One thing that comes to mind is you really shouldn't be using :transparent, as it's a pseudo-color for use with :dest_select and friends. Try replacing it with :alpha instead. Also, since i assume just doing that wont fix your problem, could you please give me a complete code sample (one that i can execute) along with the image you're using. Try to make the code sample as small as possible so it just contains the bare minimum to reproduce your issue.
TexPlay 0.3.3 released, features a few more :alpha_blend modes
:alpha_blend => :source (default, same as :alpha_blend => true) :alpha_blend => :dest, uses destination pixels alpha instead of source's alpha for alpha blending :alpha_blend => :source_with_fixed_alpha, same as :source but doesn't affect alpha channel of destination pixel :alpha_blend => :dest_with_fixed_alpha, same as :dest but doesn't affect alpha channel of destination pixel :alpha_blend => false (no alpha blending, same as current behaviour. nil also accepted)
This version also has gem test support, do the following: gem install rubygems-test gem install texplay gem test texplay
and upload results.
THere's also a few easter eggs in thsi release, require 'texplay/alone' let's you do image manip ostensively without gosu -- (really just wraps and hides gosu stuff): TexPlay.create_image(100, 100).clear(color: :red).save("blah.png")
and require 'texplay/live' a REPL session for image editting; totally undocumented and therefore hard to use :P requires 'pry' gem
While using my paint program just now, I came up with two new (possibly) useful :alpha_blend modes. The first I call ":source_as_alpha" and the second could be called either ":copy_alpha" or just ":copy".
The first uses the grey-scale value of the pixels in the source to alter the alpha channel of the destination, without affecting the color channels. You could either do a straight copy, or an actual composite taking into account the source's alpha channel. Maybe there should be separate flags for both modes (:source_as_alpha_over?). Also, it could be split into ":red_as_alpha" etc. which would give the option of skipping the redundant computation of a grey value for a known grey pixel. (The ":copy_alpha" mode below could actually also be called ":alpha_as_alpha" for symmetry, although it's rather more cumbersome...)
The second mode (:copy_alpha) just draws the source's alpha channel to the destination's, ignoring the color channels of both images.
It's up to you whether either of these also respects the blending modes.
The one that popped into my head is a "search light" effect, where you have a black, opaque image over another image, and you splice a transparent circle into the black image to show the background through. Of course, the "darkness" doesn't have to just be black, it could just be really dim, or foggy, etc. It could even be used for "x-ray vision". Basically, anywhere you'd need to "punch holes" in another bitmap, or plug holes up, without affecting the color.
You'd use standard :multiply mode with [1, 1, 1, alpha] for that effect.
This wouldn't affect the rgb channels, but would multiply the alpha of each pixel by an amount (0 to clear, 0.5 to make it half as opaque). It doesn't set it directly, but multiplication is actually more generally useful, I think.
Oh, I wasn't aware that blend modes worked on the alpha channel, too. That's cool! But, doesn't that mess things up when you just want a straight alpha composite with multiply? e.g. a sprite with an anti-aliased edge.