gamebox 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/History.txt +14 -0
  2. data/Manifest.txt +40 -37
  3. data/README.txt +2 -2
  4. data/Rakefile +27 -20
  5. data/TODO.txt +8 -8
  6. data/bin/gamebox +7 -1
  7. data/docs/getting_started.rdoc +2 -5
  8. data/docs/logo.png +0 -0
  9. data/lib/gamebox.rb +12 -1
  10. data/lib/gamebox/actor.rb +34 -9
  11. data/lib/gamebox/actor_factory.rb +25 -14
  12. data/lib/gamebox/actor_view.rb +6 -6
  13. data/lib/gamebox/{logo.rb → actors/logo.rb} +0 -0
  14. data/lib/gamebox/{score.rb → actors/score.rb} +2 -1
  15. data/lib/gamebox/{svg_actor.rb → actors/svg_actor.rb} +3 -4
  16. data/lib/gamebox/ai/polaris.rb +2 -0
  17. data/lib/gamebox/behavior.rb +3 -0
  18. data/lib/gamebox/{animated.rb → behaviors/animated.rb} +13 -5
  19. data/lib/gamebox/{graphical.rb → behaviors/graphical.rb} +11 -1
  20. data/lib/gamebox/{layered.rb → behaviors/layered.rb} +14 -0
  21. data/lib/gamebox/{physical.rb → behaviors/physical.rb} +41 -14
  22. data/lib/gamebox/{updatable.rb → behaviors/updatable.rb} +1 -1
  23. data/lib/gamebox/{templates/template_app → data}/config/objects.yml +4 -2
  24. data/lib/gamebox/data/graphics/logo.png +0 -0
  25. data/lib/gamebox/event_compat.rb +285 -0
  26. data/lib/gamebox/ftor.rb +2 -0
  27. data/lib/gamebox/gamebox_application.rb +12 -1
  28. data/lib/gamebox/generators/actor_generator.rb +2 -2
  29. data/lib/gamebox/generators/view_generator.rb +42 -0
  30. data/lib/gamebox/input_manager.rb +88 -21
  31. data/lib/gamebox/{aliasing.rb → lib/aliasing.rb} +0 -0
  32. data/lib/gamebox/{templates/template_app/lib → lib}/diy.rb +0 -0
  33. data/lib/gamebox/{inflections.rb → lib/inflections.rb} +0 -0
  34. data/lib/gamebox/{inflector.rb → lib/inflector.rb} +2 -2
  35. data/lib/gamebox/{linked_list.rb → lib/linked_list.rb} +0 -0
  36. data/lib/gamebox/{metaclass.rb → lib/metaclass.rb} +0 -0
  37. data/lib/gamebox/lib/numbers_ext.rb +3 -0
  38. data/lib/gamebox/{platform.rb → lib/platform.rb} +0 -0
  39. data/lib/gamebox/{publisher_ext.rb → lib/publisher_ext.rb} +0 -0
  40. data/lib/gamebox/{sorted_list.rb → lib/sorted_list.rb} +0 -0
  41. data/lib/gamebox/lib/surface_ext.rb +76 -0
  42. data/lib/gamebox/physical_director.rb +1 -1
  43. data/lib/gamebox/{physical_level.rb → physical_stage.rb} +28 -18
  44. data/lib/gamebox/physics.rb +2 -2
  45. data/lib/gamebox/resource_manager.rb +77 -8
  46. data/lib/gamebox/sound_manager.rb +15 -17
  47. data/lib/gamebox/stage.rb +143 -0
  48. data/lib/gamebox/stage_manager.rb +110 -0
  49. data/lib/gamebox/svg_document.rb +1 -1
  50. data/lib/gamebox/tasks/gamebox_tasks.rb +1 -1
  51. data/lib/gamebox/templates/{test_actor.erb → actor_spec.erb} +2 -2
  52. data/lib/gamebox/templates/actor_view.erb +8 -0
  53. data/lib/gamebox/templates/actor_view_spec.erb +10 -0
  54. data/lib/gamebox/templates/template_app/Rakefile +4 -4
  55. data/lib/gamebox/templates/template_app/config/game.yml +1 -0
  56. data/lib/gamebox/templates/template_app/config/stage_config.yml +2 -0
  57. data/lib/gamebox/templates/template_app/script/generate +2 -1
  58. data/lib/gamebox/templates/template_app/{test → spec}/helper.rb +0 -0
  59. data/lib/gamebox/templates/template_app/src/{demo_level.rb → demo_stage.rb} +5 -3
  60. data/lib/gamebox/templates/template_app/src/game.rb +4 -6
  61. data/lib/gamebox/version.rb +3 -2
  62. data/lib/gamebox/viewport.rb +18 -9
  63. data/lib/gamebox/{graphical_actor_view.rb → views/graphical_actor_view.rb} +13 -1
  64. data/lib/gamebox/wrapped_screen.rb +2 -1
  65. data/spec/actor_spec.rb +57 -0
  66. data/{test/test_animated.rb → spec/animated_spec.rb} +5 -6
  67. data/spec/helper.rb +24 -0
  68. data/{test/test_line_of_site.rb → spec/line_of_site_spec.rb} +1 -1
  69. data/{test/test_physical.rb → spec/physical_spec.rb} +3 -4
  70. data/{test/test_polaris.rb → spec/polaris_spec.rb} +1 -1
  71. data/{test/test_viewport.rb → spec/viewport_spec.rb} +11 -8
  72. metadata +53 -50
  73. data/docs/gamebox04_big.png +0 -0
  74. data/lib/gamebox/level.rb +0 -65
  75. data/lib/gamebox/mode.rb +0 -123
  76. data/lib/gamebox/mode_manager.rb +0 -80
  77. data/lib/gamebox/numbers_ext.rb +0 -3
  78. data/lib/gamebox/surface_ext.rb +0 -37
  79. data/lib/gamebox/templates/template_app/config/mode_level_config.yml +0 -3
  80. data/test/helper.rb +0 -26
  81. data/test/test_actor.rb +0 -36
@@ -0,0 +1,2 @@
1
+ require 'rubygame/ftor'
2
+ Ftor = Rubygame::Ftor
@@ -4,6 +4,8 @@ $: << "#{File.dirname(__FILE__)}/../config"
4
4
  require 'rubygems'
5
5
  require 'rubygame'
6
6
  include Rubygame
7
+ include Rubygame::Events
8
+ require 'event_compat'
7
9
  require 'surface_ext'
8
10
 
9
11
  require "environment"
@@ -23,7 +25,16 @@ class GameboxApp
23
25
  end
24
26
 
25
27
  def initialize
26
- @context = DIY::Context.from_file(APP_ROOT + '/config/objects.yml')
28
+ gamebox_objects = YAML.load(File.read(GAMEBOX_PATH + 'data/config/objects.yml'))
29
+
30
+ game_objects_file = APP_ROOT + '/config/objects.yml'
31
+ game_specific_objects = {}
32
+ if File.exist? game_objects_file
33
+ game_specific_objects = YAML.load(File.read(game_objects_file))
34
+ end
35
+ objects = gamebox_objects.merge! game_specific_objects
36
+
37
+ @context = DIY::Context.from_yaml(YAML.dump(objects))
27
38
  end
28
39
 
29
40
  def setup
@@ -28,13 +28,13 @@ class ActorGenerator
28
28
  end
29
29
 
30
30
  def build_test_actor
31
- template_file = File.open(File.join(GAMEBOX_PATH,'templates','test_actor.erb'))
31
+ template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_spec.erb'))
32
32
  template_contents = template_file.readlines.join
33
33
  actor_template = ERB.new(template_contents)
34
34
 
35
35
  result = actor_template.result @bind
36
36
 
37
- out_file = File.join(APP_ROOT,'test','test_'+Inflector.underscore(@actor_name)+".rb")
37
+ out_file = File.join(APP_ROOT,'spec',Inflector.underscore(@actor_name)+"_spec.rb")
38
38
  raise "File exists [#{out_file}]" if File.exists? out_file
39
39
  File.open(out_file,"w+") do |f|
40
40
  f.write result
@@ -0,0 +1,42 @@
1
+
2
+ class ViewGenerator
3
+ require 'erb'
4
+ def generate(*args)
5
+
6
+ @actor_view_name = ARGV[1]
7
+ @actor_view_name += "View" unless @actor_view_name.end_with? "View"
8
+ @behaviors = ARGV[2]
9
+ @bind = binding
10
+
11
+ build_actor_view
12
+ build_test_actor_view
13
+ end
14
+
15
+ def build_actor_view
16
+ template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_view.erb'))
17
+ template_contents = template_file.readlines.join
18
+ actor_view_template = ERB.new(template_contents)
19
+
20
+ result = actor_view_template.result @bind
21
+
22
+ out_file = File.join(APP_ROOT,'src',Inflector.underscore(@actor_view_name)+".rb")
23
+ raise "File exists [#{out_file}]" if File.exists? out_file
24
+ File.open(out_file,"w+") do |f|
25
+ f.write result
26
+ end
27
+ end
28
+
29
+ def build_test_actor_view
30
+ template_file = File.open(File.join(GAMEBOX_PATH,'templates','actor_view_spec.erb'))
31
+ template_contents = template_file.readlines.join
32
+ actor_view_template = ERB.new(template_contents)
33
+
34
+ result = actor_view_template.result @bind
35
+
36
+ out_file = File.join(APP_ROOT,'spec',Inflector.underscore(@actor_view_name)+"_spec.rb")
37
+ raise "File exists [#{out_file}]" if File.exists? out_file
38
+ File.open(out_file,"w+") do |f|
39
+ f.write result
40
+ end
41
+ end
42
+ end
@@ -1,26 +1,52 @@
1
1
  require 'publisher'
2
+
3
+ # InputManager handles the pumping of SDL for events and distributing of said events.
4
+ # You can gain access to these events by registering for all events,
5
+ # or just the ones you care about.
6
+ # All events:
7
+ # input_manager.when :event_received do |evt|
8
+ # ...
9
+ # end
10
+ #
11
+ # Some events:
12
+ # input_manager.reg KeyPressed, :space do
13
+ # ...
14
+ # end
15
+ #
16
+ # Don't forget to unreg for these things between stages,
17
+ # since the InputManager is shared across stages.
2
18
  class InputManager
3
19
  extend Publisher
4
20
  can_fire :key_up, :event_received
5
21
 
22
+
23
+ # lookup map for mouse button clicks
6
24
  MOUSE_BUTTON_LOOKUP = {
7
- 1 => :left,
8
- 2 => :middle,
9
- 3 => :right,
25
+ MOUSE_LEFT => :left,
26
+ MOUSE_MIDDLE => :middle,
27
+ MOUSE_RIGHT => :right,
10
28
  }
11
29
 
12
- attr_accessor :hooks
13
-
14
- def initialize
30
+ constructor :config_manager
31
+
32
+ # Sets up the clock and main event loop. You should never call this method,
33
+ # as this class should be initialized by diy.
34
+ def setup
15
35
  @queue = EventQueue.new
36
+ @queue.enable_new_style_events
16
37
  @queue.ignore = [
17
- ActiveEvent,
18
- JoyAxisEvent,
19
- JoyBallEvent,
20
- JoyDownEvent,
21
- JoyHatEvent,
22
- JoyUpEvent,
23
- ResizeEvent
38
+ InputFocusGained,
39
+ InputFocusLost,
40
+ MouseFocusGained,
41
+ MouseFocusLost,
42
+ WindowMinimized,
43
+ WindowUnminimized,
44
+ JoystickAxisMoved,
45
+ JoystickBallMoved,
46
+ JoystickButtonPressed,
47
+ JoystickButtonReleased,
48
+ JoystickHatMoved,
49
+ WindowResized
24
50
  ]
25
51
 
26
52
  @clock = Clock.new do |c|
@@ -31,39 +57,49 @@ class InputManager
31
57
  end
32
58
  end
33
59
 
60
+ @auto_quit = @config_manager[:auto_quit]
61
+
34
62
  @hooks = {}
35
63
  @non_id_hooks = {}
36
64
  end
37
65
 
66
+ # Sets the target framerate for the game.
67
+ # This setting controls how lock Clock#tick will delay.
38
68
  def framerate=(frame_rate)
39
69
  @clock.target_framerate = frame_rate
40
70
  end
41
71
 
72
+ # Returns the target framerate.
42
73
  def framerate
43
74
  @clock.target_framerate
44
75
  end
45
76
 
77
+ # This is where the queue gets pumped. This gets called from your game application.
46
78
  def main_loop(game)
47
79
  catch(:rubygame_quit) do
48
80
  loop do
49
81
  # add magic hooks
50
82
  @queue.each do |event|
51
83
  case event
52
- when KeyDownEvent
84
+ when KeyPressed
53
85
  case event.key
54
- when K_F
86
+ when :f
55
87
  puts "Framerate:#{@clock.framerate}"
56
- when K_ESCAPE
57
- throw :rubygame_quit
88
+ when @auto_quit
89
+ throw :rubygame_quit
58
90
  end
59
- when QuitEvent
91
+ when QuitRequested
60
92
  throw :rubygame_quit
61
93
  end
62
94
  fire :event_received, event
63
95
 
64
96
  event_hooks = @hooks[event.class]
65
97
  id = event.key if event.respond_to? :key
66
- id ||= MOUSE_BUTTON_LOOKUP[event.button] if event.respond_to? :button
98
+
99
+ if event.respond_to? :button
100
+ id ||= (MOUSE_BUTTON_LOOKUP[event.button] or event.button)
101
+ end
102
+
67
103
  unless id.nil?
68
104
  event_action_hooks = event_hooks[id] if event_hooks
69
105
  if event_action_hooks
@@ -86,7 +122,22 @@ class InputManager
86
122
  end
87
123
  end
88
124
 
125
+ # registers a block to be called when matching events are pulled from the SDL queue.
126
+ # ie
127
+ # input_manager.register_hook KeyPressed do |evt|
128
+ # # will be called on every key press
129
+ # end
130
+ # input_manager.register_hook KeyPressed, K_SPACE do |evt|
131
+ # # will be called on every spacebar key press
132
+ # end
89
133
  def register_hook(event_class, *event_ids, &block)
134
+ return unless block_given?
135
+ listener = eval("self", block.binding)
136
+ _register_hook listener, event_class, *event_ids, &block
137
+ end
138
+ alias reg register_hook
139
+
140
+ def _register_hook(listener, event_class, *event_ids, &block)
90
141
  return unless block_given?
91
142
  @hooks[event_class] ||= {}
92
143
  for event_id in event_ids
@@ -97,13 +148,15 @@ class InputManager
97
148
  if event_ids.empty?
98
149
  @non_id_hooks[event_class] << block
99
150
  end
100
- listener = eval("self", block.binding)
101
151
  listener.when :remove_me do
102
152
  unregister_hook event_class, *event_ids, &block
103
153
  end
104
154
  end
105
- alias reg register_hook
106
155
 
156
+ # unregisters a block to be called when matching events are pulled from the SDL queue.
157
+ # ie
158
+ # input_manager.unregister_hook KeyPressed, :space, registered_block
159
+ # also see InputManager#clear_hooks for clearing many hooks
107
160
  def unregister_hook(event_class, *event_ids, &block)
108
161
  @hooks[event_class] ||= {}
109
162
  for event_id in event_ids
@@ -117,6 +170,9 @@ class InputManager
117
170
  end
118
171
  alias unreg unregister_hook
119
172
 
173
+
174
+ # removes all blocks that are in the scope of listener's instance.
175
+ # clears all listeners if listener is nil
120
176
  def clear_hooks(listener=nil)
121
177
  if listener
122
178
  for event_klass, id_listeners in @hooks
@@ -137,4 +193,15 @@ class InputManager
137
193
  @non_id_hooks = {}
138
194
  end
139
195
  end
196
+
197
+ # autohook a boolean to be set to true while a key is pressed
198
+ def while_key_pressed(key, target, accessor)
199
+ _register_hook target, KeyPressed, key do
200
+ target.send accessor.to_s+"=", true
201
+ end
202
+ _register_hook target, KeyReleased, key do
203
+ target.send accessor.to_s+"=", false
204
+ end
205
+ end
206
+
140
207
  end
File without changes
File without changes
@@ -200,7 +200,7 @@ module Inflector
200
200
  class_name_in_module.to_s.gsub(/^.*::/, '')
201
201
  end
202
202
 
203
- # Create the name of a table like Rails does for models to table names. This method
203
+ # Create the name of a table like Rails does for stagels to table names. This method
204
204
  # uses the pluralize method on the last word in the string.
205
205
  #
206
206
  # Examples
@@ -211,7 +211,7 @@ module Inflector
211
211
  pluralize(underscore(class_name))
212
212
  end
213
213
 
214
- # Create a class name from a table name like Rails does for table names to models.
214
+ # Create a class name from a table name like Rails does for table names to stagels.
215
215
  # Note that this returns a string and not a Class. (To convert to an actual class
216
216
  # follow classify with constantize.)
217
217
  #
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ class Float
2
+ INFINITY = 1.0/0.0
3
+ end
File without changes
File without changes
@@ -0,0 +1,76 @@
1
+ require 'ftor'
2
+ include Rubygame::Color
3
+ module Rubygame
4
+ class Surface
5
+ def draw_line_s(point1, point2, color, thickness)
6
+ half_thickness = thickness/2.0
7
+ x1 = point1[0]
8
+ y1 = point1[1]
9
+ x2 = point2[0]
10
+ y2 = point2[1]
11
+
12
+ point1_vector = Ftor.new x1, y1
13
+ point2_vector = Ftor.new x2, y2
14
+
15
+ line_vector = point2_vector-point1_vector
16
+ perp_vector = line_vector.normal.unit
17
+
18
+ points = []
19
+ pvt = perp_vector*half_thickness
20
+ poly_point1 = Ftor.new(x1,y1)+pvt
21
+ poly_point2 = Ftor.new(x2,y2)+pvt
22
+ poly_point3 = Ftor.new(x2,y2)-pvt
23
+ poly_point4 = Ftor.new(x1,y1)-pvt
24
+
25
+ points << [poly_point1.x,poly_point1.y]
26
+ points << [poly_point2.x,poly_point2.y]
27
+ points << [poly_point3.x,poly_point3.y]
28
+ points << [poly_point4.x,poly_point4.y]
29
+ points << [poly_point1.x,poly_point1.y]
30
+
31
+ draw_polygon_s points, color
32
+ draw_circle_s [x1,y1], half_thickness, color
33
+ draw_circle_s [x2,y2], half_thickness, color
34
+ end
35
+
36
+ # BY IPPA
37
+ def fill_gradient(user_options = {})
38
+ # merge arguments from methodcall Over default options
39
+ default_options = {
40
+ :from_color => :black,
41
+ :to_color => :white,
42
+ :thickness => 10,
43
+ :orientation => :down,
44
+ :rect => Rect.new([0, 0, self.width, self.height])
45
+ }
46
+ options = default_options.merge(user_options)
47
+
48
+ # typecast color and rect arguments
49
+ from_color = (options[:from_color].is_a? ColorRGB)? options[:from_color] : Color[options[:from_color]]
50
+ to_color = (options[:to_color].is_a? ColorRGB)? options[:to_color] : Color[options[:to_color]]
51
+ rect = (options[:rect].is_a? Rect)? options[:rect] : Rect.new(:rect)
52
+
53
+ length = (options[:orientation] == :vertical) ? rect.height : rect.width
54
+ weight_step = 1.0 / (length.to_f / options[:thickness].to_f)
55
+ weight = 0.0
56
+ x = rect.x
57
+ y = rect.y
58
+
59
+ while weight < 1.0
60
+ color = to_color.average(from_color, weight)
61
+
62
+ if options[:orientation] == :vertical
63
+ self.draw_box_s([x, y], [rect.width, y + options[:thickness]], color)
64
+ y += options[:thickness]
65
+ else
66
+ self.draw_box_s([x, y],[x + options[:thickness], rect.height], color)
67
+ x += options[:thickness]
68
+ end
69
+
70
+ weight += weight_step
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end # module Rubygame
@@ -12,6 +12,6 @@ class PhysicalDirector < Director
12
12
  end
13
13
 
14
14
  def actor_removed(act)
15
- act.level.unregister_physical_object act if act.is? :physical
15
+ act.stage.unregister_physical_object act if act.is? :physical
16
16
  end
17
17
  end
@@ -1,29 +1,26 @@
1
- # Levels represent on level of game play. Some games will likely have only one
2
- # level. Level is responsible for loading its background, props, and directors.
3
- # PhysicalLevel adds a physics space to the Level
4
- require 'level'
1
+ # Stage represent on level of game play. Some games will likely have only one
2
+ # stage. Stage is responsible for loading its background, props, and directors.
3
+ # PhysicalStage adds a physics space to the Stage
4
+ require 'stage'
5
5
  require 'physics'
6
6
  require 'physical_director'
7
- class PhysicalLevel < Level
7
+ class PhysicalStage < Stage
8
8
 
9
9
  attr_accessor :space
10
10
 
11
- def initialize(actor_factory, resource_manager, sound_manager, input_manager, viewport, opts={})
12
- @actor_factory = actor_factory
13
- @director = PhysicalDirector.new
14
- @actor_factory.director = @director
15
-
16
- @resource_manager = resource_manager
17
- @sound_manager = sound_manager
18
- @input_manager = input_manager
19
- @viewport = viewport
20
- @opts = opts
21
-
11
+ def setup
12
+ super
13
+ setup_space
14
+ end
15
+
16
+ def setup_space
22
17
  @space = Space.new
23
18
  @space.iterations = 20
24
- @space.elastic_iterations = 0
19
+ @space.elastic_iterations = 5
20
+ end
25
21
 
26
- setup
22
+ def create_director
23
+ PhysicalDirector.new
27
24
  end
28
25
 
29
26
  PHYSICS_STEP = 25.0
@@ -87,4 +84,17 @@ class PhysicalLevel < Level
87
84
  end
88
85
  end
89
86
 
87
+ # Find any / all objects who's bounding box currently contains
88
+ # the passed in screen position. Requires a block as this sets
89
+ # a callback all the way down in Chipmunk and could be called
90
+ # later in the future.
91
+ #
92
+ # This block is called on each actor found
93
+ def pick(x, y, &block)
94
+ @space.shape_point_query(vec2(x, y)) do |found|
95
+ actor = @director.find_physical_obj(found)
96
+ block.call(actor)
97
+ end
98
+ end
99
+
90
100
  end