gamebox 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|