gamebox 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +40 -37
- data/README.txt +2 -2
- data/Rakefile +27 -20
- data/TODO.txt +8 -8
- data/bin/gamebox +7 -1
- data/docs/getting_started.rdoc +2 -5
- data/docs/logo.png +0 -0
- data/lib/gamebox.rb +12 -1
- data/lib/gamebox/actor.rb +34 -9
- data/lib/gamebox/actor_factory.rb +25 -14
- data/lib/gamebox/actor_view.rb +6 -6
- data/lib/gamebox/{logo.rb → actors/logo.rb} +0 -0
- data/lib/gamebox/{score.rb → actors/score.rb} +2 -1
- data/lib/gamebox/{svg_actor.rb → actors/svg_actor.rb} +3 -4
- data/lib/gamebox/ai/polaris.rb +2 -0
- data/lib/gamebox/behavior.rb +3 -0
- data/lib/gamebox/{animated.rb → behaviors/animated.rb} +13 -5
- data/lib/gamebox/{graphical.rb → behaviors/graphical.rb} +11 -1
- data/lib/gamebox/{layered.rb → behaviors/layered.rb} +14 -0
- data/lib/gamebox/{physical.rb → behaviors/physical.rb} +41 -14
- data/lib/gamebox/{updatable.rb → behaviors/updatable.rb} +1 -1
- data/lib/gamebox/{templates/template_app → data}/config/objects.yml +4 -2
- data/lib/gamebox/data/graphics/logo.png +0 -0
- data/lib/gamebox/event_compat.rb +285 -0
- data/lib/gamebox/ftor.rb +2 -0
- data/lib/gamebox/gamebox_application.rb +12 -1
- data/lib/gamebox/generators/actor_generator.rb +2 -2
- data/lib/gamebox/generators/view_generator.rb +42 -0
- data/lib/gamebox/input_manager.rb +88 -21
- data/lib/gamebox/{aliasing.rb → lib/aliasing.rb} +0 -0
- data/lib/gamebox/{templates/template_app/lib → lib}/diy.rb +0 -0
- data/lib/gamebox/{inflections.rb → lib/inflections.rb} +0 -0
- data/lib/gamebox/{inflector.rb → lib/inflector.rb} +2 -2
- data/lib/gamebox/{linked_list.rb → lib/linked_list.rb} +0 -0
- data/lib/gamebox/{metaclass.rb → lib/metaclass.rb} +0 -0
- data/lib/gamebox/lib/numbers_ext.rb +3 -0
- data/lib/gamebox/{platform.rb → lib/platform.rb} +0 -0
- data/lib/gamebox/{publisher_ext.rb → lib/publisher_ext.rb} +0 -0
- data/lib/gamebox/{sorted_list.rb → lib/sorted_list.rb} +0 -0
- data/lib/gamebox/lib/surface_ext.rb +76 -0
- data/lib/gamebox/physical_director.rb +1 -1
- data/lib/gamebox/{physical_level.rb → physical_stage.rb} +28 -18
- data/lib/gamebox/physics.rb +2 -2
- data/lib/gamebox/resource_manager.rb +77 -8
- data/lib/gamebox/sound_manager.rb +15 -17
- data/lib/gamebox/stage.rb +143 -0
- data/lib/gamebox/stage_manager.rb +110 -0
- data/lib/gamebox/svg_document.rb +1 -1
- data/lib/gamebox/tasks/gamebox_tasks.rb +1 -1
- data/lib/gamebox/templates/{test_actor.erb → actor_spec.erb} +2 -2
- data/lib/gamebox/templates/actor_view.erb +8 -0
- data/lib/gamebox/templates/actor_view_spec.erb +10 -0
- data/lib/gamebox/templates/template_app/Rakefile +4 -4
- data/lib/gamebox/templates/template_app/config/game.yml +1 -0
- data/lib/gamebox/templates/template_app/config/stage_config.yml +2 -0
- data/lib/gamebox/templates/template_app/script/generate +2 -1
- data/lib/gamebox/templates/template_app/{test → spec}/helper.rb +0 -0
- data/lib/gamebox/templates/template_app/src/{demo_level.rb → demo_stage.rb} +5 -3
- data/lib/gamebox/templates/template_app/src/game.rb +4 -6
- data/lib/gamebox/version.rb +3 -2
- data/lib/gamebox/viewport.rb +18 -9
- data/lib/gamebox/{graphical_actor_view.rb → views/graphical_actor_view.rb} +13 -1
- data/lib/gamebox/wrapped_screen.rb +2 -1
- data/spec/actor_spec.rb +57 -0
- data/{test/test_animated.rb → spec/animated_spec.rb} +5 -6
- data/spec/helper.rb +24 -0
- data/{test/test_line_of_site.rb → spec/line_of_site_spec.rb} +1 -1
- data/{test/test_physical.rb → spec/physical_spec.rb} +3 -4
- data/{test/test_polaris.rb → spec/polaris_spec.rb} +1 -1
- data/{test/test_viewport.rb → spec/viewport_spec.rb} +11 -8
- metadata +53 -50
- data/docs/gamebox04_big.png +0 -0
- data/lib/gamebox/level.rb +0 -65
- data/lib/gamebox/mode.rb +0 -123
- data/lib/gamebox/mode_manager.rb +0 -80
- data/lib/gamebox/numbers_ext.rb +0 -3
- data/lib/gamebox/surface_ext.rb +0 -37
- data/lib/gamebox/templates/template_app/config/mode_level_config.yml +0 -3
- data/test/helper.rb +0 -26
- data/test/test_actor.rb +0 -36
data/lib/gamebox/ftor.rb
ADDED
@@ -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
|
-
|
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','
|
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,'
|
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
|
-
|
8
|
-
|
9
|
-
|
25
|
+
MOUSE_LEFT => :left,
|
26
|
+
MOUSE_MIDDLE => :middle,
|
27
|
+
MOUSE_RIGHT => :right,
|
10
28
|
}
|
11
29
|
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
84
|
+
when KeyPressed
|
53
85
|
case event.key
|
54
|
-
when
|
86
|
+
when :f
|
55
87
|
puts "Framerate:#{@clock.framerate}"
|
56
|
-
when
|
57
|
-
throw :rubygame_quit
|
88
|
+
when @auto_quit
|
89
|
+
throw :rubygame_quit
|
58
90
|
end
|
59
|
-
when
|
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
|
-
|
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
|
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
|
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
|
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
|
File without changes
|
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
|
@@ -1,29 +1,26 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
require '
|
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
|
7
|
+
class PhysicalStage < Stage
|
8
8
|
|
9
9
|
attr_accessor :space
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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 =
|
19
|
+
@space.elastic_iterations = 5
|
20
|
+
end
|
25
21
|
|
26
|
-
|
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
|