Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Extending Gosu / What's the best way to patch in new "draw_foo" methods?
- - By RunnerPack Date 2017-01-16 01:30
I've got the beginnings of a passable "draw_circle" method that draws an unfilled circle with a given edge thickness (using draw_quad), but I don't know how to integrate it into Gosu so it functions like draw_line, etc.

I tried monkey-patching it into Gosu::Window, and it works fine when called directly from within (a subclass of) Window#draw. However, I want to call it from within the #draw of another class, which is itself called inside Window#draw. When I do, Ruby says the method is undefined. Okay, that kinda makes sense... I just have to call Window#draw_circle, then, right? So, I pass a reference to the Window object into my class' constructor, but calling @win.draw_circle(...) makes the first call to draw_quad inside draw_circle fail with the message "invalid value".

Since draw_quad, etc. are defined directly in the Gosu module, I tried doing that with my draw_circle, too, but then I can't figure out how to call it at all. It doesn't "just work" like calling draw_quad, etc.

I don't know enough about Ruby namespaces or the way Gosu works to figure this out. Help!
Parent - - By jlnr (dev) Date 2017-01-16 02:44
I think the trick you are missing is to def self.x instead of def x:

module Gosu
  def self.draw_circle
    ... draw_quad(...) ...
  end
end
Parent - - By RunnerPack Date 2017-01-16 03:20 Edited 2017-01-16 03:28
That results in, in the working example: undefined method 'draw_circle' for #<GfxWindow:0x287bc20> and, in the non-working example: undefined method 'draw_circle' for #<Connector:0x2944398>

I'll post some minimal code to show what I'm trying to do.

EDIT:

If I add "Gosu::" to the draw_circle calls, the non-working example gives "invalid value" and the working example works again, but I don't have to add "Gosu::" to draw_quad, etc., so why should I now?
Parent - - By jlnr (dev) Date 2017-01-16 06:36 Edited 2017-01-17 03:55
Ah, I see. draw_quad originally was (and still is) an instance method of Gosu::Window, which is why you can call it without Gosu:: or Gosu. inside of your window subclass, but only there.

The fact that everything had to be called on a Gosu::Window instance made it necessary to pass around references to the window everywhere (same thing with the old Image constructors etc.), which was so annoying that many games used a global $window variable instead. So in Gosu 0.9, I've moved all the draw_ methods into module Gosu, along with button_down?.

There are technically two draw_quad methods now, one on Gosu::Window and one in Gosu itself. If you want draw_circle to have the same behaviour, you'll need to implement it twice as well. The method in Gosu::Window would just forward all arguments to the module.

It's a bit of a mess. I was about to deprecate the instance methods on Gosu::Window in favour of Gosu.draw_xxx, but I'm afraid that'll make things even more confusing when someone uses include Gosu.

Related comment on the pull request that'll bring deprecations to Gosu 0.11.1 - https://github.com/gosu/gosu/pull/370#issuecomment-272708027
Parent - By RunnerPack Date 2017-01-16 22:33
Well, now I feel silly... I really was sending an "invalid value" to draw_circle (and, thus, to the draw_rect inside)!

I've made draw_circle a class method of Gosu and made an instance method of Window pointing to it, and all works as it should!

I'll probably post the project (which isn't really a game), along with the circle routine itself, to the showcase.

Thanks for your help, jlnr!
Up Topic Gosu / Extending Gosu / What's the best way to patch in new "draw_foo" methods?

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill