gamebox 0.0.1
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.
- data/History.txt +18 -0
- data/Manifest.txt +85 -0
- data/README.txt +33 -0
- data/Rakefile +42 -0
- data/TODO.txt +29 -0
- data/bin/gamebox +49 -0
- data/docs/gamebox04_big.png +0 -0
- data/docs/getting_started.rdoc +99 -0
- data/docs/logo.png +0 -0
- data/lib/gamebox.rb +6 -0
- data/lib/gamebox/actor.rb +143 -0
- data/lib/gamebox/actor_factory.rb +64 -0
- data/lib/gamebox/actor_view.rb +35 -0
- data/lib/gamebox/ai/line_of_site.rb +61 -0
- data/lib/gamebox/ai/polaris.rb +107 -0
- data/lib/gamebox/ai/two_d_grid_location.rb +21 -0
- data/lib/gamebox/ai/two_d_grid_map.rb +77 -0
- data/lib/gamebox/aliasing.rb +16 -0
- data/lib/gamebox/animated.rb +84 -0
- data/lib/gamebox/behavior.rb +16 -0
- data/lib/gamebox/config_manager.rb +22 -0
- data/lib/gamebox/console_app.rb +39 -0
- data/lib/gamebox/data/fonts/Asimov.ttf +0 -0
- data/lib/gamebox/data/fonts/GAMEBOX_FONTS_GO_HERE +0 -0
- data/lib/gamebox/data/graphics/GAMEBOX_GRAPHICS_GO_HERE +0 -0
- data/lib/gamebox/data/graphics/logo.png +0 -0
- data/lib/gamebox/data/music/GAMEBOX_MUSIC_GOES_HERE +0 -0
- data/lib/gamebox/data/sounds/GAMEBOX_SOUND_FX_GO_HERE +0 -0
- data/lib/gamebox/director.rb +47 -0
- data/lib/gamebox/gamebox_application.rb +77 -0
- data/lib/gamebox/graphical.rb +24 -0
- data/lib/gamebox/graphical_actor_view.rb +31 -0
- data/lib/gamebox/inflections.rb +52 -0
- data/lib/gamebox/inflector.rb +278 -0
- data/lib/gamebox/input_manager.rb +104 -0
- data/lib/gamebox/layered.rb +34 -0
- data/lib/gamebox/level.rb +64 -0
- data/lib/gamebox/linked_list.rb +137 -0
- data/lib/gamebox/logo.rb +11 -0
- data/lib/gamebox/metaclass.rb +6 -0
- data/lib/gamebox/mode.rb +123 -0
- data/lib/gamebox/mode_manager.rb +80 -0
- data/lib/gamebox/numbers_ext.rb +3 -0
- data/lib/gamebox/physical.rb +139 -0
- data/lib/gamebox/physical_director.rb +17 -0
- data/lib/gamebox/physical_level.rb +89 -0
- data/lib/gamebox/physics.rb +27 -0
- data/lib/gamebox/publisher_ext.rb +13 -0
- data/lib/gamebox/resource_manager.rb +122 -0
- data/lib/gamebox/score.rb +35 -0
- data/lib/gamebox/sorted_list.rb +59 -0
- data/lib/gamebox/sound_manager.rb +84 -0
- data/lib/gamebox/surface_ext.rb +37 -0
- data/lib/gamebox/svg_actor.rb +55 -0
- data/lib/gamebox/svg_document.rb +160 -0
- data/lib/gamebox/template_app/README +30 -0
- data/lib/gamebox/template_app/Rakefile +20 -0
- data/lib/gamebox/template_app/config/boot.rb +5 -0
- data/lib/gamebox/template_app/config/environment.rb +29 -0
- data/lib/gamebox/template_app/config/game.yml +6 -0
- data/lib/gamebox/template_app/config/mode_level_config.yml +3 -0
- data/lib/gamebox/template_app/config/objects.yml +29 -0
- data/lib/gamebox/template_app/data/fonts/FONTS_GO_HERE +0 -0
- data/lib/gamebox/template_app/data/graphics/GRAPHICS_GO_HERE +0 -0
- data/lib/gamebox/template_app/data/music/MUSIC_GOES_HERE +0 -0
- data/lib/gamebox/template_app/data/sounds/SOUND_FX_GO_HERE +0 -0
- data/lib/gamebox/template_app/doc/README_FOR_APP +1 -0
- data/lib/gamebox/template_app/lib/code_statistics.rb +107 -0
- data/lib/gamebox/template_app/lib/diy.rb +371 -0
- data/lib/gamebox/template_app/lib/platform.rb +16 -0
- data/lib/gamebox/template_app/src/app.rb +8 -0
- data/lib/gamebox/template_app/src/demo_level.rb +20 -0
- data/lib/gamebox/template_app/src/game.rb +22 -0
- data/lib/gamebox/template_app/src/my_actor.rb +17 -0
- data/lib/gamebox/version.rb +10 -0
- data/lib/gamebox/viewport.rb +81 -0
- data/lib/gamebox/wrapped_screen.rb +15 -0
- data/script/perf_polaris.rb +36 -0
- data/test/helper.rb +25 -0
- data/test/test_actor.rb +38 -0
- data/test/test_animated.rb +64 -0
- data/test/test_line_of_site.rb +14 -0
- data/test/test_physical.rb +26 -0
- data/test/test_polaris.rb +193 -0
- data/test/test_viewport.rb +116 -0
- metadata +188 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'publisher'
|
2
|
+
class InputManager
|
3
|
+
extend Publisher
|
4
|
+
can_fire :key_up, :event_received
|
5
|
+
|
6
|
+
attr_accessor :hooks
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@queue = EventQueue.new
|
10
|
+
@queue.ignore = [
|
11
|
+
ActiveEvent,
|
12
|
+
JoyAxisEvent,
|
13
|
+
JoyBallEvent,
|
14
|
+
JoyDownEvent,
|
15
|
+
JoyHatEvent,
|
16
|
+
JoyUpEvent,
|
17
|
+
ResizeEvent
|
18
|
+
]
|
19
|
+
|
20
|
+
@clock = Clock.new do |c|
|
21
|
+
c.target_framerate = 40
|
22
|
+
if c.respond_to? :calibrate
|
23
|
+
c.calibrate
|
24
|
+
c.granularity = 2 if c.granularity < 2
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@hooks = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def framerate=(frame_rate)
|
32
|
+
@clock.target_framerate = frame_rate
|
33
|
+
end
|
34
|
+
|
35
|
+
def framerate
|
36
|
+
@clock.target_framerate
|
37
|
+
end
|
38
|
+
|
39
|
+
def main_loop(game)
|
40
|
+
catch(:rubygame_quit) do
|
41
|
+
loop do
|
42
|
+
# add magic hooks
|
43
|
+
@queue.each do |event|
|
44
|
+
case event
|
45
|
+
when KeyDownEvent
|
46
|
+
case event.key
|
47
|
+
when K_F
|
48
|
+
puts "Framerate:#{@clock.framerate}"
|
49
|
+
when K_ESCAPE
|
50
|
+
throw :rubygame_quit
|
51
|
+
end
|
52
|
+
when QuitEvent
|
53
|
+
throw :rubygame_quit
|
54
|
+
end
|
55
|
+
fire :event_received, event
|
56
|
+
|
57
|
+
event_hooks = @hooks[event.class]
|
58
|
+
event_action_hooks = event_hooks[event.key] if event_hooks
|
59
|
+
if event_action_hooks
|
60
|
+
for callback in event_action_hooks
|
61
|
+
callback.call
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
game.update @clock.tick
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def register_hook(event_class, *event_ids, &block)
|
72
|
+
return unless block_given?
|
73
|
+
@hooks[event_class] ||= {}
|
74
|
+
for event_id in event_ids
|
75
|
+
@hooks[event_class][event_id] ||= []
|
76
|
+
@hooks[event_class][event_id] << block
|
77
|
+
end
|
78
|
+
listener = eval("self", block.binding)
|
79
|
+
listener.when :remove_me do
|
80
|
+
unregister_hook event_class, *event_ids, &block
|
81
|
+
end
|
82
|
+
end
|
83
|
+
alias reg register_hook
|
84
|
+
|
85
|
+
def unregister_hook(event_class, *event_ids, &block)
|
86
|
+
@hooks[event_class] ||= {}
|
87
|
+
for event_id in event_ids
|
88
|
+
@hooks[event_class][event_id] ||= []
|
89
|
+
if block_given?
|
90
|
+
@hooks[event_class][event_id].delete block
|
91
|
+
else
|
92
|
+
# for blocks in @hooks[event_class][event_id]
|
93
|
+
# listener = eval("self", block.binding)
|
94
|
+
# @hooks[event_class][event_id].delete block if listener == id
|
95
|
+
# end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
alias unreg unregister_hook
|
100
|
+
|
101
|
+
def clear_hooks
|
102
|
+
@hooks = {}
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'behavior'
|
2
|
+
# Keeps track of the layer that something is to be drawn on.
|
3
|
+
# By default it sets everything to layer 0 and parallax layer of
|
4
|
+
# 1.
|
5
|
+
class Layered < Behavior
|
6
|
+
|
7
|
+
attr_accessor :layer, :parallax
|
8
|
+
def setup
|
9
|
+
if @opts.is_a? Hash
|
10
|
+
@layer = @opts[:layer]
|
11
|
+
@parallax = @opts[:parallax]
|
12
|
+
else
|
13
|
+
@layer = @opts
|
14
|
+
end
|
15
|
+
|
16
|
+
@layer ||= 0
|
17
|
+
@parallax ||= 1
|
18
|
+
|
19
|
+
layered_obj = self
|
20
|
+
@actor.instance_eval do
|
21
|
+
(class << self; self; end).class_eval do
|
22
|
+
define_method :layer do
|
23
|
+
layered_obj.layer
|
24
|
+
end
|
25
|
+
define_method :parallax do
|
26
|
+
layered_obj.parallax
|
27
|
+
end
|
28
|
+
define_method :layered do
|
29
|
+
layered_obj
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,64 @@
|
|
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
|
+
require 'inflector'
|
4
|
+
require 'publisher'
|
5
|
+
require 'director'
|
6
|
+
class Level
|
7
|
+
extend Publisher
|
8
|
+
|
9
|
+
can_fire_anything
|
10
|
+
attr_accessor :director, :resource_manager, :sound_manager,
|
11
|
+
:opts, :viewport
|
12
|
+
|
13
|
+
def initialize(actor_factory, resource_manager, sound_manager, viewport, opts={})
|
14
|
+
@director = Director.new
|
15
|
+
@actor_factory = actor_factory
|
16
|
+
@actor_factory.director = @director
|
17
|
+
|
18
|
+
@sound_manager = sound_manager
|
19
|
+
@resource_manager = resource_manager
|
20
|
+
@viewport = viewport
|
21
|
+
@opts = opts
|
22
|
+
setup
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_actor(type, args={})
|
29
|
+
@actor_factory.build type, self, args
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(time)
|
33
|
+
@director.update time
|
34
|
+
end
|
35
|
+
|
36
|
+
def draw(target,x_off,y_off)
|
37
|
+
end
|
38
|
+
|
39
|
+
# extract all the params from a node that are needed to construct an actor
|
40
|
+
def create_actors_from_svg
|
41
|
+
float_keys = ["x","y"]
|
42
|
+
dynamic_actors ||= {}
|
43
|
+
layer = @svg_doc.find_group_by_label("actors")
|
44
|
+
|
45
|
+
unless layer.nil?
|
46
|
+
# each image in the layer is an actor
|
47
|
+
layer.images.each do |actor_def|
|
48
|
+
klass = actor_def.game_class.to_sym
|
49
|
+
handle = actor_def.game_handle
|
50
|
+
new_opts = {}
|
51
|
+
actor_def.node.attributes.each do |k,v|
|
52
|
+
v = v.to_f if float_keys.include? k
|
53
|
+
new_opts[k.to_sym] = v
|
54
|
+
end
|
55
|
+
|
56
|
+
actor = create_actor klass, new_opts
|
57
|
+
dynamic_actors[handle.to_sym] = actor if handle
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
dynamic_actors
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
class LinkedList
|
2
|
+
include Enumerable
|
3
|
+
|
4
|
+
ListElem = Struct.new(:obj, :prev, :next)
|
5
|
+
attr_accessor :head, :tail
|
6
|
+
|
7
|
+
def initialize(enum = nil)
|
8
|
+
@head = @tail = ListElem.new
|
9
|
+
@head.next = @head
|
10
|
+
@head.prev = @head
|
11
|
+
|
12
|
+
append enum unless enum.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
# pop off the first item
|
16
|
+
def shift
|
17
|
+
tmp = @head.next
|
18
|
+
@head.next = tmp.next
|
19
|
+
tmp.next.prev = @head
|
20
|
+
#puts "SHIFTING [#{tmp.obj.x},#{tmp.obj.y}]"
|
21
|
+
# puts to_s
|
22
|
+
return tmp.obj
|
23
|
+
end
|
24
|
+
|
25
|
+
# pop off the last item
|
26
|
+
def unshift
|
27
|
+
tmp = @tail.prev
|
28
|
+
@tail.prev = @tail.prev.prev
|
29
|
+
@tail.next = @tail
|
30
|
+
return tmp.obj
|
31
|
+
end
|
32
|
+
|
33
|
+
def place(new_obj, location, elem)
|
34
|
+
# puts "placing #{new_obj[0][0]},#{new_obj[0][1]} #{location} #{elem.obj[0][0]},#{elem.obj[0][1]}"
|
35
|
+
tmp = ListElem.new
|
36
|
+
tmp.obj = new_obj
|
37
|
+
case location
|
38
|
+
when :before
|
39
|
+
tmp.next = elem
|
40
|
+
tmp.prev = elem.prev
|
41
|
+
elem.prev.next = tmp
|
42
|
+
elem.prev = tmp
|
43
|
+
when :after
|
44
|
+
tmp.prev = elem
|
45
|
+
tmp.next = elem.next
|
46
|
+
elem.next.prev = tmp
|
47
|
+
elem.next = tmp
|
48
|
+
end
|
49
|
+
# puts to_s
|
50
|
+
tmp
|
51
|
+
end
|
52
|
+
|
53
|
+
def append(e)
|
54
|
+
# puts "appending #{e[0][0]},#{e[0][1]}"
|
55
|
+
tmp = ListElem.new
|
56
|
+
tmp.obj = e
|
57
|
+
tmp.prev = @tail.prev
|
58
|
+
tmp.next = @tail
|
59
|
+
tmp.prev.next = tmp
|
60
|
+
tmp.next.prev = tmp
|
61
|
+
# puts to_s
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
alias :<< :append
|
66
|
+
def prepend(e)
|
67
|
+
tmp = ListElem.new
|
68
|
+
tmp.obj = e
|
69
|
+
tmp.prev = @head
|
70
|
+
tmp.next = @head.next
|
71
|
+
tmp.prev.next = tmp
|
72
|
+
tmp.next.prev = tmp
|
73
|
+
self
|
74
|
+
end
|
75
|
+
alias :>> :prepend
|
76
|
+
|
77
|
+
# only removed the first instance of e
|
78
|
+
def remove(e)
|
79
|
+
i = @head.next
|
80
|
+
|
81
|
+
while @tail != i
|
82
|
+
if i.obj == e
|
83
|
+
# remove it
|
84
|
+
i.prev.next = i.next
|
85
|
+
i.next.prev = i.prev
|
86
|
+
return i.obj
|
87
|
+
end
|
88
|
+
i = i.next
|
89
|
+
end
|
90
|
+
i
|
91
|
+
end
|
92
|
+
alias :- :remove
|
93
|
+
|
94
|
+
def empty?()
|
95
|
+
@tail.prev == @head
|
96
|
+
end
|
97
|
+
|
98
|
+
def each
|
99
|
+
i = @head.next
|
100
|
+
|
101
|
+
while @tail != i
|
102
|
+
yield i.obj
|
103
|
+
i = i.next
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def each_element
|
108
|
+
i = @head.next
|
109
|
+
|
110
|
+
while @tail != i
|
111
|
+
yield i
|
112
|
+
i = i.next
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
str = "LinkedList #{self.object_id} ["
|
118
|
+
i = @head.next
|
119
|
+
|
120
|
+
while @tail != i
|
121
|
+
str += "#{i.obj[0]}-#{i.obj[1]},"
|
122
|
+
i = i.next
|
123
|
+
end
|
124
|
+
str += "]"
|
125
|
+
str
|
126
|
+
end
|
127
|
+
|
128
|
+
def size
|
129
|
+
size = 0
|
130
|
+
i = @head.next
|
131
|
+
while @tail != i
|
132
|
+
i = i.next
|
133
|
+
size += 1
|
134
|
+
end
|
135
|
+
size
|
136
|
+
end
|
137
|
+
end
|
data/lib/gamebox/logo.rb
ADDED
data/lib/gamebox/mode.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'inflector'
|
2
|
+
require 'viewport'
|
3
|
+
# Mode is a state that the game is in. (ie intro mode, multiplayer mode,
|
4
|
+
# single player mode).
|
5
|
+
class Mode
|
6
|
+
extend Publisher
|
7
|
+
can_fire_anything
|
8
|
+
|
9
|
+
attr_accessor :level, :drawables, :resource_manager, :sound_manager
|
10
|
+
def initialize(input_manager, actor_factory, resource_manager, sound_manager, config_manager, levels)
|
11
|
+
@input_manager = input_manager
|
12
|
+
@actor_factory = actor_factory
|
13
|
+
@resource_manager = resource_manager
|
14
|
+
@sound_manager = sound_manager
|
15
|
+
@config_manager = config_manager
|
16
|
+
res = @config_manager[:screen_resolution]
|
17
|
+
|
18
|
+
@viewport = Viewport.new res[0], res[1]
|
19
|
+
@drawables = {}
|
20
|
+
@levels = levels
|
21
|
+
setup
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
@level_number = 0
|
29
|
+
clear_drawables
|
30
|
+
@level = build_level @levels[@level_number], nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def next_level
|
34
|
+
@level_number += 1
|
35
|
+
clear_drawables
|
36
|
+
@level = build_level @levels[@level_number], @level
|
37
|
+
end
|
38
|
+
|
39
|
+
def prev_level
|
40
|
+
@level_number -= 1
|
41
|
+
clear_drawables
|
42
|
+
@level = build_level @levels[@level_number], @level
|
43
|
+
end
|
44
|
+
|
45
|
+
def restart_level
|
46
|
+
clear_drawables
|
47
|
+
@level = build_level @levels[@level_number], @level
|
48
|
+
end
|
49
|
+
|
50
|
+
def stop
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_level(level_def, prev_level_instance)
|
54
|
+
level_sym = level_def.keys.first
|
55
|
+
begin
|
56
|
+
require level_sym.to_s+"_level"
|
57
|
+
rescue LoadError => ex
|
58
|
+
puts "Load error: #{ex.inspect}"
|
59
|
+
puts ex.backtrace.join("\n")
|
60
|
+
# maybe we have included it elsewhere
|
61
|
+
end
|
62
|
+
level_klass = ObjectSpace.const_get(Inflector.camelize(level_sym.to_s+"_level"))
|
63
|
+
full_level_def = { :prev_level => prev_level_instance }
|
64
|
+
full_level_def.merge! level_def[level_sym] if level_def[level_sym].is_a? Hash
|
65
|
+
level = level_klass.new @actor_factory, @resource_manager, @sound_manager, @viewport, full_level_def
|
66
|
+
level.when :restart_level do
|
67
|
+
restart_level
|
68
|
+
end
|
69
|
+
level.when :next_level do
|
70
|
+
if @level_number == @levels.size-1
|
71
|
+
fire :next_mode
|
72
|
+
else
|
73
|
+
next_level
|
74
|
+
end
|
75
|
+
end
|
76
|
+
level.when :prev_level do
|
77
|
+
if @level_number == 0
|
78
|
+
fire :prev_mode
|
79
|
+
else
|
80
|
+
prev_level
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
level
|
85
|
+
end
|
86
|
+
|
87
|
+
def update(time)
|
88
|
+
@level.update time if @level
|
89
|
+
@viewport.update time
|
90
|
+
end
|
91
|
+
|
92
|
+
def draw(target)
|
93
|
+
@level.draw target, @viewport.x_offset, @viewport.y_offset
|
94
|
+
|
95
|
+
for parallax_layer in @drawables.keys.sort.reverse
|
96
|
+
pd = @drawables[parallax_layer]
|
97
|
+
for layer in pd.keys.sort
|
98
|
+
for d in pd[layer]
|
99
|
+
trans_x = @viewport.x_offset parallax_layer
|
100
|
+
trans_y = @viewport.y_offset parallax_layer
|
101
|
+
d.draw target, trans_x, trans_y
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def unregister_drawable(drawable)
|
108
|
+
@drawables[drawable.parallax][drawable.layer].delete drawable
|
109
|
+
end
|
110
|
+
|
111
|
+
def clear_drawables
|
112
|
+
@drawables = {}
|
113
|
+
end
|
114
|
+
|
115
|
+
def register_drawable(drawable)
|
116
|
+
layer = drawable.layer
|
117
|
+
parallax = drawable.parallax
|
118
|
+
@drawables[parallax] ||= {}
|
119
|
+
@drawables[parallax][layer] ||= []
|
120
|
+
@drawables[parallax][layer] << drawable
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|