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.
Files changed (86) hide show
  1. data/History.txt +18 -0
  2. data/Manifest.txt +85 -0
  3. data/README.txt +33 -0
  4. data/Rakefile +42 -0
  5. data/TODO.txt +29 -0
  6. data/bin/gamebox +49 -0
  7. data/docs/gamebox04_big.png +0 -0
  8. data/docs/getting_started.rdoc +99 -0
  9. data/docs/logo.png +0 -0
  10. data/lib/gamebox.rb +6 -0
  11. data/lib/gamebox/actor.rb +143 -0
  12. data/lib/gamebox/actor_factory.rb +64 -0
  13. data/lib/gamebox/actor_view.rb +35 -0
  14. data/lib/gamebox/ai/line_of_site.rb +61 -0
  15. data/lib/gamebox/ai/polaris.rb +107 -0
  16. data/lib/gamebox/ai/two_d_grid_location.rb +21 -0
  17. data/lib/gamebox/ai/two_d_grid_map.rb +77 -0
  18. data/lib/gamebox/aliasing.rb +16 -0
  19. data/lib/gamebox/animated.rb +84 -0
  20. data/lib/gamebox/behavior.rb +16 -0
  21. data/lib/gamebox/config_manager.rb +22 -0
  22. data/lib/gamebox/console_app.rb +39 -0
  23. data/lib/gamebox/data/fonts/Asimov.ttf +0 -0
  24. data/lib/gamebox/data/fonts/GAMEBOX_FONTS_GO_HERE +0 -0
  25. data/lib/gamebox/data/graphics/GAMEBOX_GRAPHICS_GO_HERE +0 -0
  26. data/lib/gamebox/data/graphics/logo.png +0 -0
  27. data/lib/gamebox/data/music/GAMEBOX_MUSIC_GOES_HERE +0 -0
  28. data/lib/gamebox/data/sounds/GAMEBOX_SOUND_FX_GO_HERE +0 -0
  29. data/lib/gamebox/director.rb +47 -0
  30. data/lib/gamebox/gamebox_application.rb +77 -0
  31. data/lib/gamebox/graphical.rb +24 -0
  32. data/lib/gamebox/graphical_actor_view.rb +31 -0
  33. data/lib/gamebox/inflections.rb +52 -0
  34. data/lib/gamebox/inflector.rb +278 -0
  35. data/lib/gamebox/input_manager.rb +104 -0
  36. data/lib/gamebox/layered.rb +34 -0
  37. data/lib/gamebox/level.rb +64 -0
  38. data/lib/gamebox/linked_list.rb +137 -0
  39. data/lib/gamebox/logo.rb +11 -0
  40. data/lib/gamebox/metaclass.rb +6 -0
  41. data/lib/gamebox/mode.rb +123 -0
  42. data/lib/gamebox/mode_manager.rb +80 -0
  43. data/lib/gamebox/numbers_ext.rb +3 -0
  44. data/lib/gamebox/physical.rb +139 -0
  45. data/lib/gamebox/physical_director.rb +17 -0
  46. data/lib/gamebox/physical_level.rb +89 -0
  47. data/lib/gamebox/physics.rb +27 -0
  48. data/lib/gamebox/publisher_ext.rb +13 -0
  49. data/lib/gamebox/resource_manager.rb +122 -0
  50. data/lib/gamebox/score.rb +35 -0
  51. data/lib/gamebox/sorted_list.rb +59 -0
  52. data/lib/gamebox/sound_manager.rb +84 -0
  53. data/lib/gamebox/surface_ext.rb +37 -0
  54. data/lib/gamebox/svg_actor.rb +55 -0
  55. data/lib/gamebox/svg_document.rb +160 -0
  56. data/lib/gamebox/template_app/README +30 -0
  57. data/lib/gamebox/template_app/Rakefile +20 -0
  58. data/lib/gamebox/template_app/config/boot.rb +5 -0
  59. data/lib/gamebox/template_app/config/environment.rb +29 -0
  60. data/lib/gamebox/template_app/config/game.yml +6 -0
  61. data/lib/gamebox/template_app/config/mode_level_config.yml +3 -0
  62. data/lib/gamebox/template_app/config/objects.yml +29 -0
  63. data/lib/gamebox/template_app/data/fonts/FONTS_GO_HERE +0 -0
  64. data/lib/gamebox/template_app/data/graphics/GRAPHICS_GO_HERE +0 -0
  65. data/lib/gamebox/template_app/data/music/MUSIC_GOES_HERE +0 -0
  66. data/lib/gamebox/template_app/data/sounds/SOUND_FX_GO_HERE +0 -0
  67. data/lib/gamebox/template_app/doc/README_FOR_APP +1 -0
  68. data/lib/gamebox/template_app/lib/code_statistics.rb +107 -0
  69. data/lib/gamebox/template_app/lib/diy.rb +371 -0
  70. data/lib/gamebox/template_app/lib/platform.rb +16 -0
  71. data/lib/gamebox/template_app/src/app.rb +8 -0
  72. data/lib/gamebox/template_app/src/demo_level.rb +20 -0
  73. data/lib/gamebox/template_app/src/game.rb +22 -0
  74. data/lib/gamebox/template_app/src/my_actor.rb +17 -0
  75. data/lib/gamebox/version.rb +10 -0
  76. data/lib/gamebox/viewport.rb +81 -0
  77. data/lib/gamebox/wrapped_screen.rb +15 -0
  78. data/script/perf_polaris.rb +36 -0
  79. data/test/helper.rb +25 -0
  80. data/test/test_actor.rb +38 -0
  81. data/test/test_animated.rb +64 -0
  82. data/test/test_line_of_site.rb +14 -0
  83. data/test/test_physical.rb +26 -0
  84. data/test/test_polaris.rb +193 -0
  85. data/test/test_viewport.rb +116 -0
  86. metadata +188 -0
@@ -0,0 +1,35 @@
1
+ class ScoreView < ActorView
2
+ def draw(target,x_off,y_off)
3
+ text = @actor.score.to_s
4
+ text = '0'*(6-text.size)+text
5
+
6
+ font = @mode.resource_manager.load_font 'Asimov.ttf', 30
7
+ text_image = font.render text, true, [250,250,250,255]
8
+
9
+ x = @actor.x
10
+ y = @actor.y
11
+
12
+ text_image.blit target.screen, [x,y]
13
+ end
14
+ end
15
+ class Score < Actor
16
+ attr_accessor :score
17
+
18
+ def setup
19
+ clear
20
+ end
21
+
22
+ def clear
23
+ @score = 0
24
+ end
25
+
26
+ def +(amount)
27
+ @score += amount
28
+ self
29
+ end
30
+
31
+ def -(amount)
32
+ @score -= amount
33
+ self
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ require 'linked_list'
2
+
3
+ # Keeps a list of items sorted. Elements must be comparable
4
+ class SortedList
5
+ attr_reader :list
6
+ def initialize(initial_list=nil)
7
+ @list = LinkedList.new
8
+ unless initial_list.nil?
9
+ initial_list.each do |item|
10
+ add item
11
+ end
12
+ end
13
+ end
14
+
15
+ def add(item)
16
+ added = false
17
+ @list.each_element do |node|
18
+ if node.obj > item
19
+ added = true
20
+ @list.place item, :before, node
21
+ break
22
+ end
23
+ end
24
+ @list << item unless added
25
+ item
26
+ end
27
+ alias :<< :add
28
+
29
+ def shift
30
+ @list.shift
31
+ end
32
+
33
+ def empty?
34
+ @list.empty?
35
+ end
36
+
37
+ def contains?(item)
38
+ @list.each do |obj|
39
+ if obj == item
40
+ return true
41
+ end
42
+ end
43
+ false
44
+ end
45
+
46
+ def find(item)
47
+ @list.each do |obj|
48
+ if obj == item
49
+ return obj
50
+ end
51
+ end
52
+ nil
53
+ end
54
+
55
+ def size
56
+ @list.size
57
+ end
58
+
59
+ end
@@ -0,0 +1,84 @@
1
+ class SoundManager
2
+
3
+ constructor :resource_manager, :config_manager
4
+ def setup
5
+ # Not in the pygame version - for Rubygame, we need to
6
+ # explicitly open the audio device.
7
+ # Args are:
8
+ # Frequency - Sampling frequency in samples per second (Hz).
9
+ # 22050 is recommended for most games; 44100 is
10
+ # CD audio rate. The larger the value, the more
11
+ # processing required.
12
+ # Format - Output sample format. This is one of the
13
+ # AUDIO_* constants in Rubygame::Mixer
14
+ # Channels -output sound channels. Use 2 for stereo,
15
+ # 1 for mono. (this option does not affect number
16
+ # of mixing channels)
17
+ # Samplesize - Bytes per output sample. Specifically, this
18
+ # determines the size of the buffer that the
19
+ # sounds will be mixed in.
20
+ # Rubygame::Mixer::open_audio( 22050, Rubygame::Mixer::AUDIO_U8, 2, 1024 )
21
+ Rubygame::Mixer::open_audio( 22050, nil, 2, 1024 )
22
+
23
+ puts 'Warning, sound disabled' unless
24
+ (@enabled = (Rubygame::VERSIONS[:sdl_mixer] != nil))
25
+ @enabled = (@enabled and (@config_manager.settings[:sound].nil? or @config_manager.settings[:sound] == true))
26
+
27
+ if @enabled
28
+ @music = {}
29
+ files = Dir.glob "#{MUSIC_PATH}**"
30
+ for f in files
31
+ name = File.basename(f)
32
+ begin
33
+ sym = name.gsub(" ","_").split(".")[0..-2].join(".").to_sym
34
+ @music[sym] = @resource_manager.load_music(f)
35
+ rescue;end
36
+ end if files
37
+
38
+ @sounds = {}
39
+ files = Dir.glob "#{SOUND_PATH}**"
40
+ for f in files
41
+ name = File.basename(f)
42
+ begin
43
+ sym = name.gsub(" ","_").split(".")[0..-2].join(".").to_sym
44
+ @sounds[sym] = @resource_manager.load_sound(f)
45
+ rescue;end
46
+ end if files
47
+ end
48
+ end
49
+
50
+ def enabled?
51
+ @enabled
52
+ end
53
+
54
+ def play_sound(what, volume=nil)
55
+ if @enabled && @sounds[what]
56
+ @sound_thread = Thread.new do
57
+ @sounds[what].volume = volume if volume
58
+ @sounds[what].play
59
+ end
60
+ end
61
+ end
62
+
63
+ def play_music(what, volume=nil)
64
+ if @enabled && @music[what]
65
+ @music_thread = Thread.new do
66
+ @music[what].volume = volume if volume
67
+ @music[what].play :repeats => -1
68
+ end
69
+ end
70
+ end
71
+
72
+ def stop_music(what)
73
+ if @enabled
74
+ @music[what].stop if @music[what]
75
+ end
76
+ end
77
+
78
+ def stop_sound(what)
79
+ if @enabled
80
+ @sounds[what].stop if @sounds[what]
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,37 @@
1
+ require 'ftor'
2
+ module Rubygame
3
+
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
+ end
36
+
37
+ end # module Rubygame
@@ -0,0 +1,55 @@
1
+ require 'actor'
2
+ require 'actor_view'
3
+
4
+ require "enumerator"
5
+
6
+
7
+ # SvgActor knows how to build himself based on an svg document based on the :name
8
+ # passed in being the group name in the doc (layer).
9
+ class SvgActor < Actor
10
+
11
+ attr_accessor :segments, :type
12
+ def setup
13
+ @name = @opts[:name]
14
+ @svg_doc = @opts[:svg_doc]
15
+
16
+ my_layer = @svg_doc.find_group_by_label(@name.to_s)
17
+ build_from_vertices my_layer.path.vertices
18
+ @visible = my_layer.path.visible?
19
+ end
20
+
21
+ def build_from_vertices(vertices)
22
+
23
+ moment_of_inertia,mass = Float::Infinity,Float::Infinity
24
+ terrain_body = CP::Body.new(mass,moment_of_inertia)
25
+ elasticity = 0
26
+ friction = 0.7
27
+ thickness = 6
28
+ @segments = []
29
+ vertices.each_cons(2) do |a,b|
30
+ seg = CP::Shape::Segment.new(terrain_body, a,b, thickness)
31
+ seg.collision_type = @name
32
+ seg.e = elasticity
33
+ seg.u = friction
34
+ seg.group = :terrain
35
+ @segments << [a,b]
36
+ @level.space.add_static_shape(seg)
37
+ end
38
+ end
39
+
40
+ def visible?
41
+ @visible
42
+ end
43
+
44
+ end
45
+
46
+ class SvgActorView < ActorView
47
+ def draw(target,x_off,y_off)
48
+ return unless @actor.visible?
49
+ @actor.segments.each do |seg|
50
+ p1 = seg[0]
51
+ p2 = seg[1]
52
+ target.draw_line_s [p1.x+x_off,p1.y+y_off], [p2.x+x_off,p2.y+y_off], [25,255,25,255], 6
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,160 @@
1
+ require 'rexml/document'
2
+ require 'strscan'
3
+
4
+ class SvgDocument
5
+
6
+ def initialize(xml_string)
7
+ @document = REXML::Document.new(xml_string)
8
+ @root = @document.root
9
+ end
10
+
11
+ def find_group_by_label(label)
12
+ g = REXML::XPath.first(@root, "//g[@inkscape:label='#{label}']")
13
+ return nil unless g
14
+ Group.new(g)
15
+ end
16
+
17
+ module HasBounds
18
+ attr_accessor :bounds
19
+
20
+ def translate(vec)
21
+ @bounds.translate(vec) if @bounds
22
+ end
23
+
24
+ def center
25
+ @bounds.center if @bounds
26
+ end
27
+
28
+ protected
29
+
30
+ def set_bounds_from_attributes
31
+ x = @node.attributes["x"].to_f
32
+ y = @node.attributes["y"].to_f
33
+ width = @node.attributes["width"].to_f
34
+ height = @node.attributes["height"].to_f
35
+ @bounds = Rect.new [x,y,width,height]
36
+ end
37
+ end
38
+
39
+ module HasTranslation
40
+ def translation
41
+ transform = @node.attributes["transform"]
42
+ if transform and transform =~ /translate\(\s*(.+?)\s*,\s*(.+?\)\s*)/
43
+ vec2($1.to_f, ty = $2.to_f)
44
+ else
45
+ ZeroVec2
46
+ end
47
+ end
48
+ end
49
+
50
+ class Base
51
+ include HasTranslation
52
+ attr_reader :node
53
+
54
+ def initialize(node)
55
+ raise "Can't make #{self.class.name} from nil" if node.nil?
56
+ @node = node
57
+ end
58
+
59
+ def game_class
60
+ @node.attributes['game:class']
61
+ end
62
+
63
+ def game_handle
64
+ @node.attributes['game:handle']
65
+ end
66
+
67
+ def visible?
68
+ @node.attributes['visible'] != 'false'
69
+ end
70
+ end
71
+
72
+ class Group < Base
73
+ def paths(opts={})
74
+ inst_from_xpath "path", Path, opts
75
+ end
76
+
77
+ def path(opts={})
78
+ paths(opts).first
79
+ end
80
+
81
+ def rects(opts={})
82
+ inst_from_xpath "rect", Rectangle, opts
83
+ end
84
+
85
+ def rect(opts={})
86
+ rects(opts).first
87
+ end
88
+
89
+ def images(opts={})
90
+ inst_from_xpath "image", Image, opts
91
+ end
92
+
93
+ def image(opts={})
94
+ images(opts).first
95
+ end
96
+
97
+ def groups(opts={})
98
+ inst_from_xpath "g", Group, opts
99
+ end
100
+
101
+ def group(opts={})
102
+ groups(opts).first
103
+ end
104
+
105
+ private
106
+
107
+ def map_from_xpath(xpr, opts={})
108
+ opts.each do |key,val|
109
+ xpr << "[@#{key}='#{val}']"
110
+ end
111
+ REXML::XPath.match(@node, xpr).map do |n|
112
+ yield n
113
+ end
114
+ end
115
+
116
+ def inst_from_xpath(xpr, clazz, opts={})
117
+ map_from_xpath(xpr,opts) do |n|
118
+ clazz.new(n)
119
+ end
120
+ end
121
+ end
122
+
123
+ class Path < Base
124
+ # The bezier path object must have all its nodes turned "sharp",
125
+ # or non-curve-handle-ish, or this parser will not work properly
126
+ def vertices
127
+ unless @verts
128
+ @verts = []
129
+ data = @node.attributes['d']
130
+ scanner = StringScanner.new(data)
131
+ pat = /[ML]\s+([-0-9.,]+)\s*/
132
+ hit = scanner.scan(pat)
133
+ while hit
134
+ x,y = scanner[1].split(/,/).map { |s| s.to_f }
135
+ @verts << vec2(x,y)
136
+ hit = scanner.scan(pat)
137
+ end
138
+ end
139
+ @verts
140
+ end
141
+ end
142
+
143
+ class Rectangle < Base
144
+ include HasBounds
145
+
146
+ def initialize(node)
147
+ super node
148
+ set_bounds_from_attributes
149
+ end
150
+ end
151
+
152
+ class Image < Rectangle
153
+ attr_reader :image_name
154
+
155
+ def initialize(node)
156
+ super(node)
157
+ @image_name = @node.attributes["xlink:href"]
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,30 @@
1
+ == Welcome to Gamebox
2
+ Blurb here
3
+
4
+ == Description of Contents
5
+
6
+ src
7
+ Holds all the code that's specific to this particular application.
8
+
9
+ config
10
+ Configuration files for the Gamebox environment and other dependencies.
11
+
12
+ doc
13
+ This directory is where your application documentation will be stored when generated
14
+ using <tt>rake doc:app</tt>
15
+
16
+ lib
17
+ Application specific libraries. Basically, any kind of custom code that doesn't
18
+ belong under controllers, models, or helpers. This directory is in the load path.
19
+
20
+ script
21
+ Helper scripts for automation and generation.
22
+
23
+ test
24
+ Unit and functional tests along with fixtures. When using the script/generate scripts, template
25
+ test files will be generated for you and placed in this directory.
26
+
27
+ vendor
28
+ External libraries that the application depends on. Also includes the plugins subdirectory.
29
+ If the app has frozen rails, those gems also go here, under vendor/rails/.
30
+ This directory is in the load path.