chingu 0.7.6.6 → 0.7.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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