chingu 0.7.6.6 → 0.7.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/chingu.gemspec +9 -2
  2. data/examples/example11_animation.rb +2 -5
  3. data/examples/example17_gosu_tutorial.rb +2 -2
  4. data/examples/example18_animation_trait.rb +2 -2
  5. data/examples/example19_edit_viewport.rb +6 -3
  6. data/examples/example21.yml +283 -291
  7. data/examples/example21_sidescroller_with_edit.rb +22 -16
  8. data/examples/example22_text.rb +5 -1
  9. data/examples/example23_chipmunk.rb +25 -0
  10. data/examples/example3_parallax.rb +1 -0
  11. data/examples/example4_gamestates.rb +20 -5
  12. data/examples/game1.rb +13 -40
  13. data/lib/chingu.rb +2 -1
  14. data/lib/chingu/assets.rb +2 -2
  15. data/lib/chingu/basic_game_object.rb +1 -23
  16. data/lib/chingu/game_object.rb +21 -0
  17. data/lib/chingu/game_object_map.rb +96 -0
  18. data/lib/chingu/game_states/debug.rb +60 -14
  19. data/lib/chingu/game_states/edit.rb +5 -1
  20. data/lib/chingu/game_states/fade_to.rb +1 -1
  21. data/lib/chingu/helpers/input_client.rb +13 -5
  22. data/lib/chingu/helpers/input_dispatcher.rb +13 -8
  23. data/lib/chingu/helpers/options_setter.rb +33 -0
  24. data/lib/chingu/input.rb +5 -5
  25. data/lib/chingu/rect.rb +2 -0
  26. data/lib/chingu/text.rb +7 -9
  27. data/lib/chingu/traits/animation.rb +1 -0
  28. data/lib/chingu/traits/bounding_box.rb +1 -5
  29. data/lib/chingu/traits/bounding_circle.rb +1 -6
  30. data/lib/chingu/traits/effect.rb +4 -4
  31. data/lib/chingu/traits/retrofy.rb +1 -1
  32. data/lib/chingu/traits/sprite.rb +234 -0
  33. data/lib/chingu/traits/velocity.rb +22 -11
  34. data/lib/chingu/traits/viewport.rb +2 -2
  35. data/lib/chingu/viewport.rb +32 -21
  36. data/lib/chingu/window.rb +6 -5
  37. data/spec/chingu/helpers/options_setter_spec.rb +39 -0
  38. data/spec/spec_helper.rb +3 -0
  39. metadata +12 -5
@@ -23,16 +23,33 @@ module Chingu
23
23
  module GameStates
24
24
 
25
25
  #
26
- # Debug game state (F1 is default key to start/exit debug win, 'p' to pause game)
26
+ # Debug game state (F1 is default key to start/exit debug win, 'p'
27
+ # to pause game)
28
+ #
29
+ # Usage:
27
30
  #
28
31
  class Debug < Chingu::GameState
29
- def initialize(options)
32
+ include Chingu::Helpers::OptionsSetter
33
+
34
+ attr_accessor :fade_color, :text_color, :text, :x_offset, :y_offset
35
+
36
+ # TODO - centralize!
37
+ Z = 999
38
+
39
+ DEFAULTS = {
40
+ :x_offset => 10,
41
+ :y_offset => 10,
42
+ :text_color => Gosu::Color.new(255,255,255,255),
43
+ :fade_color => Gosu::Color.new(100,100,100,70),
44
+ :paused => false
45
+ }
46
+
47
+ def initialize(options = {})
30
48
  super
31
- @white = Color.new(255,255,255,255)
32
- @fade_color = Gosu::Color.new(100,255,255,255)
33
-
34
- @font = Gosu::Font.new($window, default_font_name, 15)
35
- @paused = true
49
+ set_options(options, DEFAULTS)
50
+
51
+ # it fails when setup in DEFAULTS as it needs existing $window
52
+ @font ||= Gosu::Font.new($window, Gosu::default_font_name, 16)
36
53
 
37
54
  self.input = {:p => :pause, :f1 => :return_to_game, :esc => :return_to_game}
38
55
  end
@@ -42,7 +59,7 @@ module Chingu
42
59
  end
43
60
 
44
61
  def pause
45
- @paused = @paused ? false : true
62
+ @paused = !@paused
46
63
  end
47
64
 
48
65
  def update
@@ -50,16 +67,45 @@ module Chingu
50
67
  end
51
68
 
52
69
  def draw
53
- game_state_manager.previous_game_state.draw
70
+ previous_state.draw unless previous_state.nil?
54
71
 
55
72
  $window.draw_quad( 0,0,@fade_color,
56
73
  $window.width,0,@fade_color,
57
74
  $window.width,$window.height,@fade_color,
58
- 0,$window.height,@fade_color,10)
59
-
60
- text = "DEBUG CONSOLE"
61
- @font.draw(text, $window.width - @font.text_width(text), @font.height, 999)
62
- end
75
+ 0,$window.height,@fade_color,10)
76
+
77
+ @font.draw("DEBUG CONSOLE", @x_offset, @y_offset, Z)
78
+ print_lines(@text || generate_info)
79
+ end
80
+
81
+ protected
82
+
83
+ def print_lines(text)
84
+ height = @font.height
85
+ lines = text.respond_to?(:lines) ? text.lines : text
86
+
87
+ lines.each_with_index do |line,i|
88
+ @font.draw(line, @x_offset, @y_offset + height * (i+3), Z,1,1, @text_color)
89
+ end
90
+ end
91
+
92
+ def generate_info
93
+ info = ''
94
+ info << previous_state.to_s
95
+
96
+ info << "\nObjects\n"
97
+
98
+ previous_state.game_objects.each do |o|
99
+ info << " #{o.class.to_s}: #{o.to_s}\n"
100
+ end
101
+
102
+ info
103
+ end
104
+
105
+ def previous_state
106
+ game_state_manager.previous_game_state
107
+ end
108
+
63
109
  end
64
110
  end
65
111
  end
@@ -268,7 +268,11 @@ module Chingu
268
268
  #
269
269
  # Draw red rectangles/circles around all selected game objects
270
270
  #
271
- selected_game_objects.each { |game_object| game_object.draw_debug }
271
+ if defined?(previous_game_state.viewport)
272
+ previous_game_state.viewport.apply { selected_game_objects.each { |game_object| game_object.draw_debug } }
273
+ else
274
+ selected_game_objects.each { |game_object| game_object.draw_debug }
275
+ end
272
276
 
273
277
  if @cursor_game_object
274
278
  @cursor_game_object.draw_at($window.mouse_x, $window.mouse_y)
@@ -36,7 +36,7 @@ module Chingu
36
36
  class FadeTo < Chingu::GameState
37
37
 
38
38
  def initialize(new_game_state, options = {})
39
- @options = {:speed => 3, :zorder => 999999}.merge(options)
39
+ @options = {:speed => 3, :zorder => INFINITY}.merge(options)
40
40
 
41
41
  @new_game_state = new_game_state
42
42
  @new_game_state = new_game_state.new if new_game_state.is_a? Class
@@ -45,16 +45,24 @@ module Chingu
45
45
  #
46
46
  module InputClient
47
47
  #
48
- # Returns true or false depending on if the key is pressed
48
+ # Returns true or false depending if any of the given keys are pressed
49
49
  #
50
- def holding?(key)
51
- $window.button_down?(Chingu::Input::SYMBOL_TO_CONSTANT[key])
50
+ # Example:
51
+ # @player.go_left if holding?(:left, :a)
52
+ #
53
+ def holding?(*keys)
54
+ Array(keys).each do |key|
55
+ return true if $window.button_down?(Chingu::Input::SYMBOL_TO_CONSTANT[key])
56
+ end
57
+ return false
52
58
  end
53
59
 
60
+ #
61
+ # Input-map writer
62
+ #
54
63
  def input=(input_map)
55
64
  @input ||= Hash.new
56
- #@input = input_map
57
-
65
+
58
66
  if input_map.is_a? Array
59
67
  #
60
68
  # Un-nest input_map [:left, :right, :space]
@@ -80,21 +80,26 @@ module Chingu
80
80
  # For a given object, dispatch "action".
81
81
  # An action can be:
82
82
  #
83
- # * Symbol (:p, :space), translates into a method-call
84
- # * Proc/Lambda, call() it
83
+ # * Symbol (:p, :space) or String, translates into a method-call
84
+ # * Proc/Lambda or Method, call() it
85
85
  # * GameState-instance, push it on top of stack
86
86
  # * GameState-inherited class, create a new instance, cache it and push it on top of stack
87
87
  #
88
88
  def dispatch_action(action, object)
89
89
  # puts "Dispatch Action: #{action} - Objects class: #{object.class.to_s}"
90
- if action.is_a? Symbol
90
+ case action
91
+ when Symbol, String
91
92
  object.send(action)
92
- elsif action.is_a? Proc
93
- action.call
94
- elsif action.is_a? Chingu::GameState
95
- push_game_state(action)
96
- elsif action.superclass == Chingu::GameState
93
+ when Proc, Method
94
+ action[]
95
+ when Chingu::GameState
97
96
  push_game_state(action)
97
+ when Class
98
+ if action.ancestors.include?(Chingu::GameState)
99
+ push_game_state(action)
100
+ end
101
+ else
102
+ # TODO possibly raise an error? This ought to be handled when the input is specified in the first place.
98
103
  end
99
104
  end
100
105
  end
@@ -0,0 +1,33 @@
1
+ module Chingu
2
+ module Helpers
3
+
4
+ #
5
+ # Provides #set_options method to simplify common initialization from Hash.
6
+ #
7
+ module OptionsSetter
8
+
9
+ protected
10
+
11
+ #
12
+ # Takes hash and sets the instance variables denoted by 'keys'
13
+ # to 'values'. Uses setter, when available, otherwise simple
14
+ # 'instance_variable_set' is called. You can specify defaults
15
+ # for your convenience.
16
+ #
17
+ def set_options(options, defaults = {})
18
+ options = defaults.merge(options)
19
+
20
+ options.each do |attr,value|
21
+ setter = "#{attr}="
22
+
23
+ if self.respond_to?(setter)
24
+ self.send(setter, value)
25
+ else
26
+ self.instance_variable_set("@#{attr.to_s}", value)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -104,11 +104,11 @@ module Chingu
104
104
  # Gamepad-buttons 0-15
105
105
  (0..15).each do |number|
106
106
  CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = [
107
- "gamepad_button_#{number.to_s}",
108
- "gamepad_#{number.to_s}",
109
- "pad_button_#{number.to_s}",
110
- "pad_#{number.to_s}",
111
- "gp_#{number.to_s}"
107
+ "gamepad_button_#{number.to_s}".to_sym,
108
+ "gamepad_#{number.to_s}".to_sym,
109
+ "pad_button_#{number.to_s}".to_sym,
110
+ "pad_#{number.to_s}".to_sym,
111
+ "gp_#{number.to_s}".to_sym
112
112
  ]
113
113
  end
114
114
 
@@ -226,6 +226,7 @@ class Rect < Array
226
226
 
227
227
  # Return the x coordinate of the center of the Rect
228
228
  def centerx; return self.at(0)+(self.at(2).div(2)); end
229
+ alias center_x centerx;
229
230
 
230
231
  # Set the x coordinate of the center of the Rect by translating the
231
232
  # Rect (adjusting the x offset).
@@ -236,6 +237,7 @@ class Rect < Array
236
237
 
237
238
  # Return the y coordinate of the center of the Rect
238
239
  def centery; return self.at(1)+(self.at(3).div(2)); end
240
+ alias center_y centery;
239
241
 
240
242
  # Set the y coordinate of the center of the Rect by translating the
241
243
  # Rect (adjusting the y offset).
@@ -34,7 +34,7 @@ module Chingu
34
34
  #
35
35
  class Text < Chingu::GameObject
36
36
  attr_accessor :text
37
- attr_reader :height, :gosu_font, :line_spacing, :align, :max_width, :background
37
+ attr_reader :size, :gosu_font, :line_spacing, :align, :max_width, :background
38
38
 
39
39
  @@size = nil
40
40
  @@font = nil
@@ -69,14 +69,14 @@ module Chingu
69
69
 
70
70
  @text = text || options[:text] || "-No text specified-"
71
71
  @font = options[:font] || @@font || Gosu::default_font_name()
72
- @height = @size = options[:height] || options[:size] || @@size || 15
72
+ @size = options[:size] || options[:height] || @@size || 15
73
73
  @line_spacing = options[:line_spacing] || 1
74
74
  @align = options[:align] || :left
75
75
  @max_width = options[:max_width]
76
76
  @padding = options[:padding] || @@padding
77
77
  self.rotation_center = :top_left
78
78
 
79
- @gosu_font = Gosu::Font.new($window, @font, @height)
79
+ @gosu_font = Gosu::Font.new($window, @font, @size)
80
80
  create_image unless @image
81
81
 
82
82
  if options[:background]
@@ -89,6 +89,8 @@ module Chingu
89
89
  @background.width = self.width + @padding * 2
90
90
  @background.height = self.height + @padding * 2
91
91
  end
92
+
93
+ self.height = options[:height] if options[:height]
92
94
  end
93
95
 
94
96
  #
@@ -99,10 +101,6 @@ module Chingu
99
101
  create_image
100
102
  end
101
103
 
102
- def size
103
- @height
104
- end
105
-
106
104
  #
107
105
  # Returns the width, in pixels, the given text would occupy if drawn.
108
106
  #
@@ -125,9 +123,9 @@ module Chingu
125
123
  #
126
124
  def create_image
127
125
  if @max_width
128
- @image = Gosu::Image.from_text($window, @text, @font, @height, @line_spacing, @max_width, @align)
126
+ @image = Gosu::Image.from_text($window, @text, @font, @size, @line_spacing, @max_width, @align)
129
127
  else
130
- @image = Gosu::Image.from_text($window, @text, @font, @height)
128
+ @image = Gosu::Image.from_text($window, @text, @font, @size)
131
129
  end
132
130
  end
133
131
  end
@@ -62,6 +62,7 @@ module Chingu
62
62
  state = $3.length > 0 ? $3 : "default"
63
63
  animations[state.to_sym] = Chingu::Animation.new(trait_options[:animation].merge(:file => tile_file))
64
64
  elsif tile_file =~ /[a-zA-Z\_+]\.(bmp|png)/
65
+ puts tile_file
65
66
  animations[:default] = Chingu::Animation.new(trait_options[:animation].merge(:file => tile_file))
66
67
  end
67
68
 
@@ -93,11 +93,7 @@ module Chingu
93
93
  # Visualises the bounding box as a red rectangle.
94
94
  #
95
95
  def draw_debug
96
- if defined?(parent.viewport)
97
- $window.draw_rect(self.bounding_box.move(-parent.viewport.x, -parent.viewport.y), Chingu::DEBUG_COLOR, Chingu::DEBUG_ZORDER)
98
- else
99
- $window.draw_rect(self.bounding_box, Chingu::DEBUG_COLOR, Chingu::DEBUG_ZORDER)
100
- end
96
+ $window.draw_rect(self.bounding_box, Chingu::DEBUG_COLOR, Chingu::DEBUG_ZORDER)
101
97
  end
102
98
 
103
99
  end
@@ -80,12 +80,7 @@ module Chingu
80
80
  # Visualises the bounding circle as a red circle.
81
81
  #
82
82
  def draw_debug
83
- x,y = self.x, self.y # Do we need to take center_x/center_y into consideration here?
84
- if defined?(parent.viewport)
85
- $window.draw_circle(x - parent.viewport.x, y - parent.viewport.y, self.radius, Chingu::DEBUG_COLOR)
86
- else
87
- $window.draw_circle(x, y, self.radius, Chingu::DEBUG_COLOR)
88
- end
83
+ $window.draw_circle(self.x, self.y, self.radius, Chingu::DEBUG_COLOR)
89
84
  end
90
85
 
91
86
  end
@@ -65,15 +65,15 @@ module Chingu
65
65
 
66
66
  # Increase @factor_x and @factor_y at the same time.
67
67
  def scale(amount = 0.1)
68
- @factor_x += amount
69
- @factor_y += amount
68
+ self.factor_x += amount
69
+ self.factor_y += amount
70
70
  end
71
71
  alias :zoom :scale
72
72
 
73
73
  # Ddecrease @factor_x and @factor_y at the same time.
74
74
  def scale_out(amount = 0.1)
75
- @factor_x -= amount
76
- @factor_y -= amount
75
+ self.factor_x -= amount
76
+ self.factor_y -= amount
77
77
  end
78
78
  alias :zoom_out :scale_out
79
79
 
@@ -63,7 +63,7 @@ module Chingu
63
63
  end
64
64
 
65
65
  def draw
66
- @image.draw_rot(self.screen_x, self.screen_y, @zorder, @angle, @center_x, @center_y, @factor_x, @factor_y, @color, @mode)
66
+ self.image.draw_rot(self.screen_x, self.screen_y, self.zorder, self.angle, self.center_x, self.center_y, self.factor_x, self.factor_y, self.color, self.mode)
67
67
  end
68
68
  end
69
69
  end
@@ -0,0 +1,234 @@
1
+ #--
2
+ # Part of Chingu -- OpenGL accelerated 2D game framework for Ruby
3
+ # Copyright (C) 2009 ippa / ippa@rubylicio.us
4
+ #
5
+ # Written/Refactored by Jakub Hozak - jakub.hozak@gmail.com
6
+ #
7
+ #++
8
+
9
+ module Chingu
10
+ module Traits
11
+
12
+ #
13
+ # A Chingu trait providing ability to be drawn as an image.
14
+ #
15
+ # Example:
16
+ #
17
+ # class Rocket < BasicGameObject
18
+ # trait :sprite, :image => 'rocket.png'
19
+ # end
20
+ #
21
+ # Rocket.create
22
+ #
23
+ # Options:
24
+ # :image - actual sprite to draw
25
+ # - see #image= for details as this method is used to set this option
26
+ #
27
+ # Introducing Variables:
28
+ # :x, :y, :angle, :factor_x, :factor_y, :center_x, :center_y, :zorder, :mode, :visible
29
+ #
30
+ module Sprite
31
+
32
+ include Chingu::Helpers::OptionsSetter
33
+
34
+ module ClassMethods
35
+ def initialize_trait(options = {})
36
+ trait_options[:sprite] = options
37
+ end
38
+ end
39
+
40
+ attr_accessor :x, :y, :angle, :factor_x, :factor_y, :center_x, :center_y, :zorder, :mode, :visible
41
+
42
+ # default settings for all variables unless set in constructor
43
+ DEFAULTS = {
44
+ :x => 0, :y => 0, :angle => 0,
45
+ :factor_x => 1.0, :factor_y => 1.0,
46
+ :zorder => 100, :center_x => 0.5, :center_y => 0.5,
47
+ :mode => :default,
48
+ :color => nil
49
+ }
50
+
51
+ def setup_trait(object_options = {})
52
+ set_options(trait_options[:sprite].merge(object_options), DEFAULTS)
53
+ super
54
+ end
55
+
56
+ def color=(color)
57
+ @color = color.is_a?(Gosu::Color) ? color : Gosu::Color.new(color || 0xFFFFFFFF)
58
+ end
59
+
60
+ #
61
+ # Accepts String, callable object or any-other non-nil capable
62
+ # of drawing itself on screen.
63
+ #
64
+ # Examples:
65
+ # image = 'rocket.png'
66
+ # image = Gosu::Image.new($window, 'rocket.png')
67
+ #
68
+ # image = lambda do
69
+ # # TexPlay is library for Gosu image generation
70
+ # TexPlay.create_image($window,10,10).paint { circle(5,5,5, :color => :red) }
71
+ # end
72
+ #
73
+ def image=(image)
74
+ raise ArgumentError.new("No image set") if image.nil?
75
+
76
+ @image = if String === image
77
+ # 1) Try loading the image the normal way
78
+ # 2) Try looking up the picture using Chingus Image-cache
79
+ Gosu::Image.new($window, image,false) rescue Gosu::Image[image]
80
+ elsif image.respond_to? :call
81
+ image.call
82
+ else
83
+ image
84
+ end
85
+ end
86
+
87
+ #
88
+ # Get all settings from a game object in one array.
89
+ # Complemented by the GameObject#attributes= setter.
90
+ # Makes it easy to clone a objects x,y,angle etc.
91
+ #
92
+ def attributes
93
+ [@x, @y, @angle, @center_x, @center_y, @factor_x, @factor_y, @color, @mode, @zorder]
94
+ end
95
+
96
+ #
97
+ # Set all attributes on 1 line
98
+ # Mainly used in combination with game_object1.attributes = game_object2.attributes
99
+ #
100
+ def attributes=(attributes)
101
+ self.x, self.y, self.angle, self.center_x, self.center_y, self.factor_x, self.factor_y, self.color, self.mode, self.zorder = *attributes
102
+ end
103
+
104
+ #
105
+ # Set an effective width for the object on screen.
106
+ # Chingu does this by setting factor_x depending on imge.width and width given.
107
+ # Usually better to have a large image and make it smaller then the other way around.
108
+ #
109
+ def width=(width)
110
+ @factor_x = width.to_f / @image.width.to_f
111
+ end
112
+
113
+ # Get effective on width by calculating it from image-width and factor
114
+ def width
115
+ (@image.width * @factor_x).abs
116
+ end
117
+
118
+ #
119
+ # Set an effective height for the object on screen.
120
+ # Chingu does this by setting factor_x depending on imge.width and width given.
121
+ # Usually better to have a large image and make it smaller then the other way around.
122
+ #
123
+ def height=(height)
124
+ @factor_y = height.to_f / @image.height.to_f
125
+ end
126
+
127
+ # Get effective on heightby calculating it from image-width and factor
128
+ def height
129
+ (@image.height.to_f * @factor_y).abs
130
+ end
131
+
132
+ # Set width and height in one swoop
133
+ def size=(size)
134
+ self.width, self.height = *size
135
+ end
136
+
137
+ # Get objects width and height in an array
138
+ def size
139
+ [self.width, self.height]
140
+ end
141
+
142
+
143
+ # Quick way of setting both factor_x and factor_y
144
+ def factor=(factor)
145
+ @factor_x = @factor_y = factor
146
+ end
147
+ alias scale= factor=
148
+ # alias scale factor
149
+
150
+ # Quick way of setting both center_x and center_y
151
+ def center=(center)
152
+ @center_x = @center_y = center
153
+ end
154
+
155
+ # Get objects alpha-value (internally stored in @color.alpha)
156
+ def alpha
157
+ @color.alpha
158
+ end
159
+
160
+ # Set objects alpha-value (internally stored in @color.alpha)
161
+ # If out of range, set to closest working value. this makes fading simpler.
162
+ def alpha=(value)
163
+ value = 0 if value < 0
164
+ value = 255 if value > 255
165
+ @color.alpha = value
166
+ end
167
+
168
+ #
169
+ # Sets angle, normalize it to between 0..360
170
+ #
171
+ def angle=(value)
172
+ if value < 0
173
+ value = 360+value
174
+ elsif value > 360
175
+ value = value-360
176
+ end
177
+ @angle = value
178
+ end
179
+
180
+ #
181
+ # Disable automatic calling of draw and draw_trait each game loop
182
+ #
183
+ def hide!
184
+ @visible = false
185
+ end
186
+
187
+ #
188
+ # Enable automatic calling of draw and draw_trait each game loop
189
+ #
190
+ def show!
191
+ @visible = true
192
+ end
193
+
194
+ #
195
+ # Returns true if visible (not hidden)
196
+ #
197
+ def visible?
198
+ @visible == true
199
+ end
200
+
201
+
202
+ # Returns true if object is inside the game window, false if outside
203
+ def inside_window?(x = @x, y = @y)
204
+ x >= 0 && x <= $window.width && y >= 0 && y <= $window.height
205
+ end
206
+
207
+ # Returns true object is outside the game window
208
+ def outside_window?(x = @x, y = @y)
209
+ not inside_window?(x,y)
210
+ end
211
+
212
+ #
213
+ # Our encapsulation of GOSU's image.draw_rot, uses the objects variables to draw it on screen if @visible is true
214
+ #
215
+ def draw
216
+ draw_relative
217
+ end
218
+
219
+ #
220
+ # Works as #draw() but takes offsets for all draw_rot()-arguments. Used among others by the viewport-trait.
221
+ #
222
+ def draw_relative(x=0, y=0, zorder=0, angle=0, center_x=0, center_y=0, factor_x=0, factor_y=0)
223
+ @image.draw_rot(@x+x, @y+y, @zorder+zorder, @angle+angle, @center_x+center_x, @center_y+center_y, @factor_x+factor_x, @factor_y+factor_y, @color, @mode) if @visible
224
+ end
225
+
226
+ #
227
+ # Works as #draw() but takes x/y arguments. Used among others by the edit-game state.
228
+ #
229
+ def draw_at(x, y)
230
+ draw_relative(x,y)
231
+ end
232
+ end
233
+ end
234
+ end