chingu 0.5.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +21 -0
  3. data/LICENSE +504 -0
  4. data/Manifest.txt +72 -0
  5. data/README.rdoc +588 -0
  6. data/Rakefile +19 -0
  7. data/benchmarks/README.txt +1 -0
  8. data/benchmarks/benchmark.rb +6 -0
  9. data/benchmarks/benchmark3.rb +23 -0
  10. data/benchmarks/benchmark4.rb +71 -0
  11. data/benchmarks/benchmark5.rb +91 -0
  12. data/benchmarks/benchmark6.rb +23 -0
  13. data/benchmarks/meta_benchmark.rb +67 -0
  14. data/benchmarks/meta_benchmark2.rb +39 -0
  15. data/chingu.gemspec +34 -0
  16. data/examples/example1.rb +37 -0
  17. data/examples/example10.rb +75 -0
  18. data/examples/example11.rb +51 -0
  19. data/examples/example12.rb +67 -0
  20. data/examples/example2.rb +115 -0
  21. data/examples/example3.rb +40 -0
  22. data/examples/example4.rb +175 -0
  23. data/examples/example5.rb +107 -0
  24. data/examples/example6.rb +57 -0
  25. data/examples/example7.rb +133 -0
  26. data/examples/example8.rb +109 -0
  27. data/examples/example9.rb +106 -0
  28. data/examples/media/Parallax-scroll-example-layer-0.png +0 -0
  29. data/examples/media/Parallax-scroll-example-layer-1.png +0 -0
  30. data/examples/media/Parallax-scroll-example-layer-2.png +0 -0
  31. data/examples/media/Parallax-scroll-example-layer-3.png +0 -0
  32. data/examples/media/background1.png +0 -0
  33. data/examples/media/fire_bullet.png +0 -0
  34. data/examples/media/fireball.png +0 -0
  35. data/examples/media/particle.png +0 -0
  36. data/examples/media/ruby.png +0 -0
  37. data/examples/media/spaceship.png +0 -0
  38. data/examples/media/stickfigure.bmp +0 -0
  39. data/examples/media/stickfigure.png +0 -0
  40. data/examples/media/video_games.png +0 -0
  41. data/lib/chingu.rb +32 -0
  42. data/lib/chingu/actor.rb +17 -0
  43. data/lib/chingu/animation.rb +142 -0
  44. data/lib/chingu/assets.rb +64 -0
  45. data/lib/chingu/basic_game_object.rb +132 -0
  46. data/lib/chingu/core_extensions.rb +53 -0
  47. data/lib/chingu/effects.rb +36 -0
  48. data/lib/chingu/fpscounter.rb +62 -0
  49. data/lib/chingu/game_object.rb +127 -0
  50. data/lib/chingu/game_object_list.rb +91 -0
  51. data/lib/chingu/game_state.rb +137 -0
  52. data/lib/chingu/game_state_manager.rb +284 -0
  53. data/lib/chingu/game_states/debug.rb +65 -0
  54. data/lib/chingu/game_states/fade_to.rb +91 -0
  55. data/lib/chingu/game_states/pause.rb +57 -0
  56. data/lib/chingu/gfx_helpers.rb +89 -0
  57. data/lib/chingu/helpers.rb +166 -0
  58. data/lib/chingu/inflector.rb +34 -0
  59. data/lib/chingu/input.rb +100 -0
  60. data/lib/chingu/named_resource.rb +254 -0
  61. data/lib/chingu/parallax.rb +83 -0
  62. data/lib/chingu/particle.rb +21 -0
  63. data/lib/chingu/rect.rb +612 -0
  64. data/lib/chingu/require_all.rb +133 -0
  65. data/lib/chingu/text.rb +56 -0
  66. data/lib/chingu/traits/collision_detection.rb +172 -0
  67. data/lib/chingu/traits/effect.rb +113 -0
  68. data/lib/chingu/traits/input.rb +38 -0
  69. data/lib/chingu/traits/retrofy.rb +53 -0
  70. data/lib/chingu/traits/rotation_center.rb +84 -0
  71. data/lib/chingu/traits/timer.rb +90 -0
  72. data/lib/chingu/traits/velocity.rb +67 -0
  73. data/lib/chingu/window.rb +170 -0
  74. metadata +162 -0
  75. metadata.gz.sig +1 -0
@@ -0,0 +1,133 @@
1
+ #--
2
+ # Copyright (C)2009 Tony Arcieri
3
+ # You can redistribute this under the terms of the MIT license
4
+ # See file LICENSE for details
5
+ #++
6
+
7
+ module RequireAll
8
+ # A wonderfully simple way to load your code.
9
+ #
10
+ # The easiest way to use require_all is to just point it at a directory
11
+ # containing a bunch of .rb files. These files can be nested under
12
+ # subdirectories as well:
13
+ #
14
+ # require_all 'lib'
15
+ #
16
+ # This will find all the .rb files under the lib directory and load them.
17
+ # The proper order to load them in will be determined automatically.
18
+ #
19
+ # If the dependencies between the matched files are unresolvable, it will
20
+ # throw the first unresolvable NameError.
21
+ #
22
+ # You can also give it a glob, which will enumerate all the matching files:
23
+ #
24
+ # require_all 'lib/**/*.rb'
25
+ #
26
+ # It will also accept an array of files:
27
+ #
28
+ # require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
29
+ #
30
+ # Or if you want, just list the files directly as arguments:
31
+ #
32
+ # require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
33
+ #
34
+ def require_all(*args)
35
+ # Handle passing an array as an argument
36
+ args.flatten!
37
+
38
+ if args.size > 1
39
+ # If we got a list, those be are files!
40
+ files = args
41
+ else
42
+ arg = args.first
43
+ begin
44
+ # Try assuming we're doing plain ol' require compat
45
+ stat = File.stat(arg)
46
+
47
+ if stat.file?
48
+ files = [arg]
49
+ elsif stat.directory?
50
+ files = Dir.glob File.join(arg, '**', '*.rb')
51
+ else
52
+ raise ArgumentError, "#{arg} isn't a file or directory"
53
+ end
54
+ rescue Errno::ENOENT
55
+ # If the stat failed, maybe we have a glob!
56
+ files = Dir.glob arg
57
+
58
+ # Maybe it's an .rb file and the .rb was omitted
59
+ if File.file?(arg + '.rb')
60
+ require(arg + '.rb')
61
+ return true
62
+ end
63
+
64
+ # If we ain't got no files, the glob failed
65
+ raise LoadError, "no such file to load -- #{arg}" if files.empty?
66
+ end
67
+ end
68
+
69
+ # If there's nothing to load, you're doing it wrong!
70
+ raise LoadError, "no files to load" if files.empty?
71
+
72
+ files.map! { |file| File.expand_path file }
73
+
74
+ begin
75
+ failed = []
76
+ first_name_error = nil
77
+
78
+ # Attempt to load each file, rescuing which ones raise NameError for
79
+ # undefined constants. Keep trying to successively reload files that
80
+ # previously caused NameErrors until they've all been loaded or no new
81
+ # files can be loaded, indicating unresolvable dependencies.
82
+ files.each do |file|
83
+ begin
84
+ require file
85
+ rescue NameError => ex
86
+ failed << file
87
+ first_name_error ||= ex
88
+ rescue ArgumentError => ex
89
+ # Work around ActiveSuport freaking out... *sigh*
90
+ #
91
+ # ActiveSupport sometimes throws these exceptions and I really
92
+ # have no idea why. Code loading will work successfully if these
93
+ # exceptions are swallowed, although I've run into strange
94
+ # nondeterministic behaviors with constants mysteriously vanishing.
95
+ # I've gone spelunking through dependencies.rb looking for what
96
+ # exactly is going on, but all I ended up doing was making my eyes
97
+ # bleed.
98
+ #
99
+ # FIXME: If you can understand ActiveSupport's dependencies.rb
100
+ # better than I do I would *love* to find a better solution
101
+ raise unless ex.message["is not missing constant"]
102
+
103
+ STDERR.puts "Warning: require_all swallowed ActiveSupport 'is not missing constant' error"
104
+ STDERR.puts ex.backtrace[0..9]
105
+ end
106
+ end
107
+
108
+ # If this pass didn't resolve any NameErrors, we've hit an unresolvable
109
+ # dependency, so raise one of the exceptions we encountered.
110
+ if failed.size == files.size
111
+ raise first_name_error
112
+ else
113
+ files = failed
114
+ end
115
+ end until failed.empty?
116
+
117
+ true
118
+ end
119
+
120
+ # Works like require_all, but paths are relative to the caller rather than
121
+ # the current working directory
122
+ def require_rel(*paths)
123
+ # Handle passing an array as an argument
124
+ paths.flatten!
125
+
126
+ source_directory = File.dirname caller.first.sub(/:\d+$/, '')
127
+ paths.each do |path|
128
+ require_all File.join(source_directory, path)
129
+ end
130
+ end
131
+ end
132
+
133
+ include RequireAll
@@ -0,0 +1,56 @@
1
+ module Chingu
2
+ #
3
+ # Text is a class to give the use of Gosu::Font more rubyish feel and fit it better into Chingu.
4
+ # Pure Gosu:
5
+ # @font = Gosu::Font.new($window, "verdana", 30)
6
+ # @font.draw("A Text", 200, 50, 55, 2.0)
7
+ #
8
+ # Chingu
9
+ # @text = Chingu::Text.new(:text => "A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
10
+ # @text.draw # usually not needed as Text is a GameObject and therefore autodrawn
11
+ #
12
+ # @text comes with a number of changable properties, x,y,zorder,angle,factor_x,color,mode etc.
13
+ #
14
+ class Text < Chingu::GameObject
15
+ attr_accessor :text
16
+ attr_reader :height, :gosu_font
17
+
18
+ @@size = nil
19
+ @@font = nil
20
+ def self.font; @@font; end
21
+ def self.font=(value); @@font = value; end
22
+
23
+ def self.size; @@size; end
24
+ def self.size=(value); @@size = value; end
25
+ def self.height; @@size; end
26
+ def self.height=(value); @@size = value; end
27
+
28
+ #
29
+ # Takes the standard GameObject-hash-arguments but also:
30
+ # - :text - a string of text
31
+ # - :font_name|:font - name of a systemfont (default: "verdana")
32
+ # - :height|size - how many pixels high should the text be
33
+ #
34
+ def initialize(options)
35
+ super(options)
36
+ @text = options[:text] || "-No text specified-"
37
+ @font = options[:font] || @@font || default_font_name()
38
+ @height = options[:height] || options[:size] || @@size || 15
39
+
40
+ @gosu_font = Gosu::Font.new($window, @font, @height)
41
+ end
42
+
43
+ def draw
44
+ @gosu_font.draw_rot(@text, @x.to_i, @y.to_i, @zorder, @angle, @factor_x, @factor_y, @color, @mode)
45
+ end
46
+
47
+ #
48
+ # Returns the width, in pixels, the given text would occupy if drawn.
49
+ #
50
+ def width
51
+ @gosu_font.text_width(@text, @factor_x)
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,172 @@
1
+ #--
2
+ #
3
+ # Chingu -- Game framework built on top of the opengl accelerated gamelib Gosu
4
+ # Copyright (C) 2009 ippa / ippa@rubylicio.us
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+
22
+
23
+ module Chingu
24
+ module Traits
25
+ #
26
+ # Research:
27
+ # 1) QuadTrees: http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
28
+ # 2) Sweep and Prune
29
+ #
30
+ # SEE: http://www.shmup-dev.com/forum/index.php?board=65.0
31
+ #
32
+ # Makes use of 3 attributes
33
+ # @bounding_box - a Rect-instance, uses in bounding_box collisions
34
+ # @radius -
35
+ # @detect_collisions - [true|false], should object be checked for collisions with Object.each_collision
36
+ #
37
+ module CollisionDetection
38
+ attr_accessor :bounding_box, :radius
39
+ ## attr_accessor :detect_collisions # slowed down example9 with 3 fps
40
+
41
+ def self.included(base)
42
+ base.extend(ClassMethods)
43
+ end
44
+
45
+ #
46
+ # Automaticly try to set a bounding_box and radius. Don't overwrite if they already exists.
47
+ #
48
+ def setup_trait(options)
49
+ if @x and @y and @image
50
+ @bounding_box ||= Rect.new(@x, @y, @image.width, @image.height)
51
+ end
52
+
53
+ if @image
54
+ @radius ||= (@image.height + @image.width) / 2 * 0.80
55
+ end
56
+
57
+ ## @detect_collisions = true
58
+ super
59
+ end
60
+
61
+ #
62
+ # The standard method called when self needs to be checked for a collision with another object
63
+ # By default it calls bounding_box_collision? which will check for intersectons between the
64
+ # two objects "bounding_box" attributs (a Chingu::Rect instance)
65
+ #
66
+ def collides?(object2)
67
+ bounding_box_collision?(object2)
68
+ #radius_collision?(object2)
69
+ end
70
+
71
+ #
72
+ # Collide self with a given game object by checking both objects bounding_box'es
73
+ # Returns true if colliding.
74
+ #
75
+ def bounding_box_collision?(object2)
76
+ self.bounding_box.collide_rect?(object2.bounding_box)
77
+ end
78
+
79
+ #
80
+ # Collide self using distance between 2 objects and their radius.
81
+ # Returns true if colliding.
82
+ #
83
+ def radius_collision?(object2)
84
+ distance(self.x, self.y, object2.x, object2.y) < self.radius + object2.radius
85
+ end
86
+
87
+ #
88
+ # Have bounding box follow game objects x/y
89
+ #
90
+ def update_trait
91
+ if defined?(@bounding_box) && @bounding_box.is_a?(Rect)
92
+ @bounding_box.x = self.x
93
+ @bounding_box.y = self.y
94
+ end
95
+
96
+ super
97
+ end
98
+
99
+ #
100
+ # Collides self with all objects of given classes
101
+ # Yields self and the objects it collides with
102
+ #
103
+ def each_collision(klasses = [])
104
+ Array(klasses).each do |klass|
105
+ klass.all.each do |object|
106
+ yield(self, object) if collides?(object)
107
+ end
108
+ end
109
+ end
110
+
111
+ #
112
+ # Works like each_collsion but with inline-code for speedups
113
+ #
114
+ def each_radius_collision(klasses = [])
115
+ Array(klasses).each do |klass|
116
+ klass.all.each do |object|
117
+ yield(self, object) if distance(@x, @y, object.x, object.y) < @radius + object.radius
118
+ end
119
+ end
120
+ end
121
+
122
+
123
+
124
+ module ClassMethods
125
+
126
+ #
127
+ # Works like each_collsion but with inline-code for speedups
128
+ #
129
+ def each_radius_collision(klasses = [])
130
+ Array(klasses).each do |klass|
131
+ object2_list = klass.all
132
+ #total_radius = object1.radius + object2.radius # possible optimization?
133
+
134
+ self.all.each do |object1|
135
+ object2_list.each do |object2|
136
+ next if object1 == object2 # Don't collide objects with themselves
137
+ yield object1, object2 if distance(object1.x, object1.y, object2.x, object2.y) < object1.radius + object2.radius
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ #
144
+ # Class method that will check for collisions between all instances of two classes
145
+ # and yield the 2 colliding game object instances.
146
+ #
147
+ # It will not collide objects with themselves.
148
+ #
149
+ # example:
150
+ #
151
+ # Enemy.each_collision(Bullet).each do |enemy, bullet| enemy.die!; end
152
+ #
153
+ #
154
+ def each_collision(klasses = [])
155
+ # Make sure klasses is always an array.
156
+ Array(klasses).each do |klass|
157
+ object2_list = klass.all
158
+
159
+ self.all.each do |object1|
160
+ object2_list.all.each do |object2|
161
+ next if object1 == object2 # Don't collide objects with themselves
162
+ yield object1, object2 if object1.collides?(object2)
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,113 @@
1
+ #--
2
+ #
3
+ # Chingu -- Game framework built on top of the opengl accelerated gamelib Gosu
4
+ # Copyright (C) 2009 ippa / ippa@rubylicio.us
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+
22
+
23
+ module Chingu
24
+ module Traits
25
+ module Effect
26
+ #
27
+ # Adds .rotating .fading and .zooming to any GameObject.
28
+ #
29
+ # TODO: better naming? suggestions:
30
+ #
31
+ # basic gosu unit <-> automation name
32
+ # ==============================================
33
+ # angle <-> rotation? rotating? automatic_angle?
34
+ # factor <-> growth? scale? automatic_zoom?
35
+ # alpha <-> fade
36
+ #
37
+ attr_accessor :rotating, :fading, :zooming
38
+
39
+ #def self.initialize_trait(options)
40
+ # @effect_options = {:debug => false}.merge(options)
41
+ # puts "Effect#initialize" if @effect_options[:debug]
42
+ # super
43
+ #end
44
+
45
+ #
46
+ # Setup
47
+ #
48
+ def setup_trait(options)
49
+ @effect_options = {:debug => false}.merge(options)
50
+ puts "Effect#setup" if @effect_options[:debug]
51
+
52
+ @rotating = options[:rotating] || nil
53
+ @zooming = options[:zooming] || nil
54
+ @fading = options[:fading] || nil
55
+ super
56
+ end
57
+
58
+ def draw_trait
59
+ puts "Effect#draw" if @effect_options[:debug]
60
+ super
61
+ end
62
+
63
+ def update_trait
64
+ puts "Effect#update" if @effect_options[:debug]
65
+
66
+ rotate(@rotating) if @rotating
67
+ fade(@fading) if @fading
68
+ zoom(@zooming) if @zooming
69
+ super
70
+ end
71
+
72
+ # Zoom - increase @factor_x and @factor_y at the same time.
73
+ def zoom(amount = 0.1)
74
+ @factor_x += amount
75
+ @factor_y += amount
76
+ end
77
+
78
+ # Zoom Out - decrease @factor_x and @factor_y at the same time.
79
+ def zoom_out(amount = 0.1)
80
+ @factor_x -= amount
81
+ @factor_y -= amount
82
+ end
83
+
84
+ # Rotate object 'amount' degrees
85
+ def rotate(amount = 1)
86
+ @angle += amount
87
+ end
88
+
89
+ # Fade object by decreasing/increasing color.alpha
90
+ def fade(amount = 1)
91
+ return if amount == 0
92
+
93
+ new_alpha = @color.alpha + amount
94
+ if amount < 0
95
+ @color.alpha = [0, new_alpha].max
96
+ else
97
+ @color.alpha = [0, new_alpha].min
98
+ end
99
+ end
100
+
101
+ # Fade out objects color by decreasing color.alpha
102
+ def fade_out(amount = 1)
103
+ fade(-amount)
104
+ end
105
+
106
+ # Fade in objects color by increasing color.alpha
107
+ def fade_in(amount = 1)
108
+ fade(amount)
109
+ end
110
+
111
+ end
112
+ end
113
+ end