Forum
Hah, I was about to reply to you with "The text is copied from one of banister's posts", but lo, that's you!
Anyways, reported it saying as much, but I suspect you've already done too.
Well, the Mac port was called cfxr, presumably for Cocoa. Maybe the b is for browser?
64-bit is the present and future, my friend. :)
I'd love the ability just to test my graphics without having to bother with exporting, especially since Pixelmator makes it kind of a pain (have to select the format and confirm saving over the old version every time). I wouldn't want to distribute with PSD files, of course, so 32-bit users wouldn't really need that support. Still, really cool feature.
Now try @enemies = Dir["/Applications/*Microsoft*/**.app"].map { |filename| ... }
:D
How did I miss this update? Using NSImage as a backend on OS X was a brilliant move!
Nice—but wow, Google Code's source browser is primitive. ;)
It's good seeing Gosu get some real-world mileage beyond Julian's own project. I just wish my Spanish vocabulary was bigger—I've got a lot of Latin roots from my AP English course in high school but I think I'm in over my head!
Question: when you say "we", did you implement this game during the span of the workshop? In what way did your audience participate in the development? I'm curious to know how something like this is done as a workshop. :)
Without knowing anything about the context of this code snippet, one small part kind of jumps out at me as probably wrong:
@image.draw_rot((@points[0].x+@points[1].x)/2,(@points[0].y+@points[2].y)/2,1,@contacts[0].angle)
Is this copy-pasted from the actual source or did you retype it? Are you sure 2 is the correct index here, when 1 is used for the x? :)
GitHub has a pretty decent RESTful API (with
library interfaces for several languages), and the wikis themselves are independent git repositories, so you could probably hack something together when you're feeling ambitious!
My adaptation of the algorithm was meant to provide a faster, backwards-compatible implementation of Chingu's draw_circle
; if I were going to be writing code that required arbitrary primitives, I'd probably use the "layer caching" thing with TexPlay that I mentioned above. I thought it was pretty clever. I like your solution too, though. :D
Most modern systems (apart from video game consoles and mobiles, I guess) have an FPU for fast floating point math, and they're used behind the scenes with OpenGL anyway. Integer math might give you a bigger performance boost in Ruby since integers are immediate values while floats are objects, but I feel like there's a good balance here between mental cycles and CPU cycles.
I have encountered Bresenham's circle algorithm but somehow it totally slipped my mind because it doesn't initially seem appropriate for OpenGL. Reading about it again, I realise that it could easily be thought of as connecting points on a grid, so it's totally applicable. I'll give it consideration, but I think I'm content for now to use trigonometric functions sparingly.
I think Julian's solution is really clever, and probably has us both beat if you know you're gonna be reusing the same circle. I have a little piece of code that uses TexPlay to generate raster images on demand and caches the results for future use and I think it would work pretty famously as an alternate implementation.
Drawing a circular target might look something like this, for instance:
class Target
include Drawing
...
def draw
left, top, size = @x - @radius, @y - @radius, @radius * 2
# Draw the :target layer; the painting operations only get called when the
# layer needs to be repainted.
paint_layer(:target, left, top, size, size, :z => 0) do |canvas|
cx = cy = @radius # for clarity below
canvas.circle cx, cy, @radius, :color => :red, :fill => true
canvas.circle cx, cy, @radius * 0.8, :color => :white, :fill => true
canvas.circle cx, cy, @radius * 0.6, :color => :red, :fill => true
canvas.circle cx, cy, @radius * 0.4, :color => :white, :fill => true
canvas.circle cx, cy, @radius * 0.2, :color => :red, :fill => true
end
end
def radius= new_radius
@radius = Float(new_radius)
# The :target layer must be redrawn when the radius changes.
invalidate_layer_cache! :target
end
end
I've tested this system in a small widget library I probably won't finish and it makes drawing pretty fast.
Haha, my first reaction was "oh my god, what happened", but it slowly dawned on me what was going on. Glad to see you on GitHub! I'll probably be more inclined to have a go at any features I'd like to see in Gosu now—although that still depends on my ability to implement them in C++. ;)
Meanwhile, there's a
GitHub Issues app on Heroku that's a little nicer than the web interface. There's even a
downloadable Mac version and extensions for Safari and Chrome. I think the Mac app complements Tower nicely.
Since the posted example is mostly about drawing a circle efficiently, I figured I'd share this:
An Efficient Way to Draw Approximate Circles in OpenGL. I adapted this algorithm for Chingu and it works great. You only have to calculate sin and cos at the beginning and the rest is essentially matrix multiplication, so it's much faster.
The way I implemented it uses blocks to avoid duplicated code so it may have additional overhead, but I'm not sure how well Ruby optimises those block calls. :)
Ach, fair enough! The guide still indicates that using paint { ... }
for multiple operations is faster, but I assume that's out of date now. Great library, by the way, other than that gen_eval
weirdness. :)
I'd like to know more about that edge case meanwhile, just for curiosity's sake. How are ivars implemented in Ruby 1.9 and how is it different to 1.8?
Funny you should mention texplay—I just started playing with it this evening. I managed to cause several mysterious segfaults and a series of exceptions pertaining to unexpected nil
s, attempting to dup
false and even invoking methods on garbage collected objects! ...none of which can I reproduce since they seem to have mysteriously stopped after I changed a couple of completely unrelated lines of code. Actually, most of those errors were found by changing seemingly unrelated code and I almost suspect that which one I got depended entirely on what memory addresses the objects were at or what kind of shoes the stack pointer was wearing. And I think that means I should have gone to bed a couple of hours ago.
I think the gen_eval
thing is a little too magical. I really like the library (banister's a clever fellow), but I'd rather have to write something like image.paint { |gfx| gfx.fill 0, 0, :color => :red }
if it meant I wouldn't have clever code creating hidden instance variables with illegal names and doing unspeakable things to my objects' implementation details. :D
Oh yes, and what I actually meant was "are there any plans to allow macros to be rendered to textures?" to which you have indirectly answered yes. Or rather, I assume that render { @macro.draw x, y, z }
will work just as well as render { @image.draw x, y, z }
once you have implemented it. :)
When you do add it, I think that render should accept height and width arguments for the image to render. They should be optional, where the default is whatever the window size is. I'd get the most use out of it if areas where the black background show through were transparent on the product, but either way it would be a pretty powerful feature. :D
> an example screenshot
The problem's even more complex than I thought—It seems to mysteriously self-correct if anything non-macro has ever been drawn. Could you have overlooked some important OpenGL state setup in the vertex array drawing code? Here's a demo program that lets you see the effect more easily, with screen shots for good measure.
I can't be sure, but the transparent part is probably turned opaque black too. Rendering
images like this under the same circumstances seems to draw the transparent parts without the alpha channel, so the "true" color of the pixels shows through. I can post a screen shot tomorrow when I'm not about to fall asleep.
My discovery is a total edge case; I doubt anyone would ever encounter it in the wild unless they were writing test code like mine. Totally weird behavior.
Attachment:
macro.png - drawing text with a recorded macro before anything else has been drawn (23k)
Attachment:
normal.png - drawing text the normal way (24k)
Attachment:
macro_again.png - drawing that same macro again after having drawn it the "normal" way (24k)
Attachment:
damn-macros.rb.txt - Demo program shown in the screen shots. Press space to switch between macro and draw_text. (703B)
Yeah, I suppose the absence of record
from the documentation should have tipped me off. I've just noticed that the alpha for fonts is kind of messed up too, although it's not entirely missing like the image alpha.
This has potential to be an extremely useful feature. Seems like it would be a great way to implement the behind-the-scenes caching that Chingu::Text currently does using Image#from_text
.
Since we're on the subject, though: are there any plans for macros to be saveable in the future like images are? It would be pretty awesome to be able to save them to files or even convert them to real raster images. Supposedly it's not too difficult to render to an OpenGL texture, although I can't say I know anything for sure.
Also, since it's not clear from the example given: the crash occurs after the block exits, probably during the building of the vertex array. I confirmed using simple print statements; everything after the offending function call is executed just fine, but then there's the crash.
That should hopefully narrow down the source of the problem a little.
Yeah, got an interesting problem.
I was trying to implement a cached drawing system so complex but infrequently changing drawing operations could be compiled to Gosu macros inline when I hit a bit of a wall.
Seems using a primitive drawing method (draw_line, draw_quad, draw_triangle) inside of a record
block causes one of those new fangled dreaded segmentation faults the kids are always talking about. There's some weirdness with alpha transparency too, but the crashing bug is a bit more of a big deal.
Let me show you:
require 'gosu'
class Window < Gosu::Window
def initialize
super 480, 240, false
@draw_cache = { }
@image = Gosu::Image.new self, 'test.png', false
@font = Gosu::Font.new self, 'Helvetica', 16
end
def draw
draw_cache(:peachy_keen) do
# Appears to work without a hitch.
@font.draw "Hello, World!", 64, 0, 0
end
draw_cache(:reasonably_fine) do
# Transparency is rendered white even though it works as expected
# outside of a record
ed macro.
@image.draw 64, 16, 0
end
draw_cache(:this_causes_an_error) do
# OH NO SEGFAULT
draw_quad( 0, 0, Gosu::Color::WHITE,
0, 64, Gosu::Color::WHITE,
64, 64, Gosu::Color::WHITE,
64, 0, Gosu::Color::WHITE, 0)
end
end
def draw_cache id, z = 0, &block
unless @draw_cache.include? id
@draw_cache[id] = record(&block)
end
@draw_cache[id].draw 0, 0, z
end
end
Window.new.show
This is the stack trace, complete with a mysteriously empty "C level backtrace information" section:
crash.rb:38: [BUG] Segmentation fault
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.6.0]
-- control frame ----------
c:0008 p:---- s:0025 b:0025 l:000024 d:000024 CFUNC :record
c:0007 p:0037 s:0022 b:0020 l:000019 d:000019 METHOD crash.rb:38
c:0006 p:0037 s:0014 b:0014 l:000218 d:000218 METHOD crash.rb:26
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 FINISH
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :show
c:0003 p:0051 s:0006 b:0006 l:0018b8 d:0014a8 EVAL crash.rb:45
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0018b8 d:0018b8 TOP
---------------------------
-- Ruby level backtrace information ----------------------------------------
crash.rb:45:in <main>'
crash.rb:45:in
show'
crash.rb:26:in draw'
crash.rb:38:in
draw_cache'
crash.rb:38:in `record'
-- C level backtrace information -------------------------------------------
Is that weird or what? Or is it just me?
For the record, I seem to encounter bus errors on OS X in situations that could have caused a segfault on Linux. Usually invalid memory access or so, but also whatever it is that happens when you call Gosu from another thread. If you're doing that, then it's almost certainly the cause of your woes.
Oh yeah, I'm pretty familiar with irfanview; I used it quite a bit when I was using Windows. I generally use ImageMagick for my image conversion needs on my Mac, but then I kind of live in the terminal.
I do kinda miss Paint Shop Pro 8 from Windows. Tried it under Wine and it just wasn't the same. Old versions of Photoshop for Mac are hard to come by for whatever reason, and the new version is terrible.
Aha, I see now after looking at the PNG specification that alpha is explicitly optional. I wonder, though, if most software that saves PNGs actually supports saving them without it? There are so many variations, I'm kind of not surprised that support for the format is frequently broken or incomplete.
:dest_alpha_mask
? The much more terrible and obscure :source_atop
from Cocoa? :D
Maybe let us define our own? :)
Well, can you determine from libpng whether a PNG image has an alpha channel or not? Is it actually possible for a PNG to not have the channel, or is it there whether it's used or not?
I think the default color key should be applied only to images completely lacking an alpha channel if this is possible.
Haha, I wish I could take credit. Except for the parts that suck, like the documentation. :D
Thanks for finding that blog post, though—the textual descriptions are (to me) pretty confusing and hard to follow. Now I can know at a glance which constant I want to use, or more likely, that there isn't one that does what I want after all~
D*(1-Sa) isn't my devising, of course; I just copy-pasted the documentation of the constant that sounded most like what was described for the sake of comparison. I think Apple's NSCompositingOperation constants are kind of confusing and not very powerful, though.
I think Apple calls this
NSCompositeSourceAtop
but I think it's a terrible name:
> Source image wherever both images are opaque, destination image wherever destination image is opaque but source image is transparent, and transparent elsewhere. (R = S*Da + D*(1 - Sa))
> R => The premultiplied result color.
> S => The source color
> D => The destination color
> Sa => The alpha value of the source color
> Da => The alpha value of the destination color
I suppose you could look at the
NSCompositingOperation
constants anyway to get some inspiration.
On which subject: If I ever release something under [L]GPL that you think would be useful, just ask and I'm willing to make an exception for you. Consider it fair is fair for making this great library for your commercial game available under a permissive license.
I suppose it's kind of a useless offer since I've been leaning towards BSD-style licenses myself, but I do feel that LGPL is sometimes appropriate. A static-linking-is-ok-too version of LGPL would be really nice since all I really care about is ensuring that any improvements to my code come back to me.
Jumping into the Gosu run loop actually causes a hard crash (SIGSEGV? I forget) on OS X. Actually, might have been something to do with a mutex being unlocked too many times. Definitely not inviting.
clip_to
works with the other transformations like rotate
and translate
if that helps at all. If you could show a wee snippet of code for what you're trying to do, I might be able to figure out what needs to be done about it. If you're using a fixed perspective (no rotation or parallax) then it should be as simple as clipping to the coordinates of the tile that the player is over.
I have fortunately not dealt with Ruby on Windows. Homebrew and RVM make my life easy.
Good god, trying to use Ubuntu and Ruby together is like trying to dress a cat. ;___;
Huh? Minor? Being able to schedule OpenGL calls like other draw operations is pretty major. Awesome release!
> I played minecraft
I'm surprised you've still got time for other things. :D
Good on you then if you can fix it without adding a mechanic you don't want. I eagerly await version 1.2. :)
I shared a link to Terava on Facebook and tweeted about both it and Gosu. Also recommended the game to my roommates. :)
Yeah, I did see the letters, although I haven't had a chance to get them all yet.
Maybe limited bonus content in the Lite version with some sort of promise of more in the full game. You could allow unlocking of everything that you could unlock in the full version up to that point, but only let us actually use maybe one of the unlockables.
> iOS *does* record stuff like that btw. After syncing, the logs end up in: ~/Library/Logs/CrashReporter/MobileDevice/...
> And, as far as I can tell (App Store n00b here), they get uploaded to Apple, who puts them into my inbox to see. However, I am not sure if this includes memory-related crashes or not. They are easy to spot in Xcode because they have the exit code of 0.
I need to sync my iPod more often I think. It tends to happen once or twice a month. I'll have a look in the logs tomorrow (Christmas today and all) and see if it actually recorded anything.
> Heh, there is an if() just for this problem and I tried it exactly where it happened to you. The game *should* move the enemies out of place just enough for you to jump.
Well, I suppose the monster isn't exactly where I was standing, but it's walking towards the door at that moment so it ends up there as soon as I am in control, heh. If you have a reliable way to make sure they aren't walking towards the player too, that might be a better solution than the invincible flicker trick. I have to admit your initial solution is pretty clever. :)
> BTW- since you apparently took a break between finishing Lite and jumping to full. What is your intuitive behavior? Just let the game linger on the device? Or would you actually consider replaying it?
I'm a bit of a hoarder so it's hard to get rid of a game I like, and I hate to delete a saved game too. It will stick around on my device for sure. I also have a tendency to go back and try to get all the secrets I might have missed once I've mostly "finished" a game, Metroid style, so I'll be playing it some more. I actually noticed the respawn bug while replaying that level. I'd kind of like to fight that raptor again, though. Boss rush mode, anybody? ;)
I'm happy to give feedback of course, especially since you're responsible for probably the best and most intuitive game library I've come across. I owe you at least that much, don't I? :) So, thank you for your excellent library and for letting us use it for free.
Oh and merry Christmas to you and the forum!
I like it and I think I'll be buying the full version. I do have a couple of minor whines though!
* The game seems to crash a lot on my iPod touch (second generation) while loading levels or after un-suspending it. I suspect it's running out of memory since having it suspended also makes everything else really slow and prone to crashing. I wish iOS would give error reports instead of silently quitting apps.
* In the Flatlands map, after leaving the building on the left with low health, I got stuck in a loop where hitting retry would have me respawn at the door only to be immediately killed by one of those armored dog guys that was standing in the same place. A brief invincibility after respawning (the Sonic flicker) is a time-honored solution (or workaround) to this problem.
* I think the movement regions are a little too narrow for my giant thumbs and I keep finding myself running one way or another when I mean to jump because I've missed the screen. Could we have a setting to adjust the size for gorilla hands like mine? :)
Given that two of these complaints involve the hardware as much as the software, I'm betting the iPad version is nearly perfect, so don't feel discouraged. :)
Oh yeah, and I should mention a few things that I like, too:
* The controls are ingenious I think. I haven't played an iOS game with decent platformer controls until now, so you're definitely on to something.
* The ability to jump on enemies is welcome as somebody who grew up with games like Sonic the Hedgehog. I don't care what Castlevania says—if I jump on Dracula's head, he's gonna feel it more than I am!
* It's challenging to me, but not ridiculously. I'm looking forward to seeing how the difficulty curve continues in the full version.
* Even though it seems to starve my device of memory, I haven't noticed any slowdowns yet! The game runs quite smoothly within the constraints of the device.
Just grabbed the lite version and suggested it to my roommate as well. I'll try to play it sometime tomorrow. Here's hoping it runs at a decent speed on my iPod touch.
Wow! I wish for this sort of thing fairly often, and now you've gone and done it. Thanks, good sir. :)
I'd recommend
imgur over Image Shack. :)
Ha! For that matter, I should probably learn a little too because I live in a city with a sizeable minority of Spanish speakers.
I'd be interested in having a look. I don't really have a working knowledge of Spanish, but I remember a little grammar from school and I have a sizeable vocabulary of Greek and Latin roots that might help me stumble through it. :)
Sometimes explaining something to somebody else is the best way to make sure you know it yourself.
Seems that this is a known fact (not a bug) and isn't likely to change. In the mean time, you can either se up your objects to be ready to draw in initialize
or just issue a call to update
before it returns so everything's set up.
I think you accidentally the wrong link! Did you mean
this topic?
It turns out that "ö"
and "\u00F6"
display and calculate correctly on OS X; the decomposed form, "o\u0308"
, renders an o followed by a blank space and calculates the width "correctly" for that incorrect rendering. Your problem with Font#text_width
might be a Windows specific bug at any rate.
To run your script with a literal ö you'll need to invoke Ruby with -KUTF-8
, otherwise you get that invalid multibyte sequence error.
I haven't tried these with TextInput yet.
Hmm. I get the impression that Windows prefers one of the composed forms, but ostensibly it supports all of them. I haven't found any resources that actually say for sure which is the preferred form, though!
What happens when you write "\u00F6"
in a string literal instead of typing ö directly? What about "o\u0308"
? These are equivalent in Unicode, but one is precomposed and the other is not.
If you're on Mac OS X, I believe it uses Unicode normalisation form D, where accented characters are stored as the base letter itself followed by combining forms of, e.g., ´, ¨, ˚, etc.. In this case, Font#text_width
(or the underlying library) might be incorrectly calculating the width by adding the "width" of the combining characters, giving you a too wide result.
Not that this is going to help you much, but it's a possible explanation. Probably something for Julian to look into.
Well, if we're going that route with a different language binding for the browser version, I'd go with
CoffeeScript or (if you must)
haXe.
Actually, although I like CoffeeScript a great deal, haXe can be compiled to C++ as well as JavaScript, so in theory you could write games that would run in the browser
and natively on the desktop, which is kind of stupid awesome.
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill