ippa-chingu 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -8,11 +8,13 @@ benchmarks/benchmark.rb
8
8
  benchmarks/benchmark3.rb
9
9
  benchmarks/benchmark4.rb
10
10
  benchmarks/benchmark5.rb
11
+ benchmarks/benchmark6.rb
11
12
  benchmarks/meta_benchmark.rb
12
13
  benchmarks/meta_benchmark2.rb
13
14
  chingu.gemspec
14
15
  examples/example1.rb
15
16
  examples/example10.rb
17
+ examples/example11.rb
16
18
  examples/example2.rb
17
19
  examples/example3.rb
18
20
  examples/example4.rb
@@ -43,6 +45,7 @@ lib/chingu/core_extensions.rb
43
45
  lib/chingu/effects.rb
44
46
  lib/chingu/fpscounter.rb
45
47
  lib/chingu/game_object.rb
48
+ lib/chingu/game_object_list.rb
46
49
  lib/chingu/game_state.rb
47
50
  lib/chingu/game_state_manager.rb
48
51
  lib/chingu/game_states/debug.rb
@@ -60,9 +63,7 @@ lib/chingu/require_all.rb
60
63
  lib/chingu/text.rb
61
64
  lib/chingu/traits/collision_detection.rb
62
65
  lib/chingu/traits/effect.rb
63
- lib/chingu/traits/effect_module.rb
64
66
  lib/chingu/traits/input.rb
65
67
  lib/chingu/traits/rotation_center.rb
66
68
  lib/chingu/traits/velocity.rb
67
- lib/chingu/traits/velocity_module.rb
68
69
  lib/chingu/window.rb
data/README.rdoc CHANGED
@@ -22,7 +22,8 @@ The last years I've dabbled around a lot with game development.
22
22
  I've developed games in both Rubygame and Gosu. I've looked at gamebox.
23
23
  Rubygame is a very capable framework with a lot of functionality (collision detection, very good event system etc). Gosu is way more minimalistic but also faster with OpenGL -acceleration. Gosu isn't likely to get much more complex since it does what it should do very well and fast.
24
24
 
25
- After 10+ game prototypes and some finished smaller games I started to see patterns each time I started a new game. Making classes with x/y/image/other-parameters that I called update/draw on in the main loop. This became the basic Chingu::GameObject which encapsulates Gosus "Image.draw_rot" and enables automatic updating/drawing.
25
+ After 10+ game prototypes and some finished smaller games I started to see patterns each time I started a new game. Making classes with x/y/image/other-parameters that I called update/draw on in the main loop.
26
+ This became the basic Chingu::GameObject which encapsulates Gosus "Image.draw_rot" and enables automatic updating/drawing through "game_objects".
26
27
 
27
28
  There was always a huge big chunk of checking keyboard-events in the main loop.
28
29
  Borrowing ideas from Rubygame this has now become @player.keyboard(:left => :move_left, :space => :fire ... etc.
@@ -39,13 +40,14 @@ Available thoughout your source as $window (Yes, that's the only global Chingu h
39
40
  === Chingu::GameObject
40
41
  Use this for all your in game objects. The player, the enemies, the bullets, the powerups, the loot laying around.
41
42
  It's very reusable and doesn't contain any game-logic (that's up to you!). Only stuff to put it on screen a certain way.
42
- It also gives you a couple of bonuses with chingu, as automatic updates/draws and easier input-mapping.
43
- Has either Chingu::Window or a Chingu::GameState as "owner".
43
+ If you do GameObject.create() instead of new() Chingu will keep save the object in the "game_object"-list for automatic updates/draws.
44
+ GameObjects also have the nicer Chingu input-mapping: @player.input = { :left => :move_left, :right => :move_right, :space => :fire}
45
+ Has either Chingu::Window or a Chingu::GameState as "parent".
44
46
 
45
47
  === Chingu::BasicGameObject
46
48
  For those who think GameObject is a too little fat, there's BasicGameObject (GameObject inherits from BasicGameObject).
47
49
  BasicGameObject is just an empty frame (no x,y,image accessors or draw-logic) for you to build on.
48
- It _can_ be extended with Chingus trait-system though.
50
+ It _can_ be extended with Chingus trait-system though. The new() vs create() behaivor of GameObject comes from BasicGameObject.
49
51
  BasicGameObject#parent points to either $window or a game state and is automaticly set on creation time.
50
52
 
51
53
  === Chingu::GameStateManager
@@ -62,10 +64,9 @@ For example, inside game state Menu you call push_game_state(Level). When Level
62
64
 
63
65
  === Traits
64
66
  Traits are extensions (or plugins if you so will) to BasicGameObjects.
65
- The aim is so encapsulate common behaivor into stand alone classes and modules for easy inclusion in your game classes.
66
- In it's most basic form it's just a class which answers to setup() (called on your game objects creation), update() and draw().
67
- Traits are a fairly new addition to Chingu and will probably morph some more before stabilizing.
68
-
67
+ The aim is so encapsulate common behaivor into modules for easy inclusion in your game classes.
68
+ Making a trait is easy, just an ordinary module with the methods setup_trait(), update() and/or draw().
69
+ It currently has to be namespaced to Chingu::Traits for "has_trait" to work inside GameObject-classes.
69
70
 
70
71
  == OTHER CLASSES / HELPERS
71
72
 
@@ -157,7 +158,7 @@ Chingu doesn't change any fundamental concept of Gosu, but it will make the abov
157
158
  # Player will automaticly be updated and drawn since it's a Chingu::GameObject
158
159
  # You'll need your own Game#update/#draw after a while, but just put #super there and Chingu can do its thing.
159
160
  #
160
- @player = Player.new
161
+ @player = Player.create
161
162
  @player.input = {:left => :move_left, :right => :move_right}
162
163
  end
163
164
  end
@@ -192,7 +193,8 @@ If you've worked with Gosu for a while you're probably tired of passing around t
192
193
  Chingu solves this (as has many other developers) with a global variable $window. Yes, globals are bad, but in this case it kinda makes sense. It's used under the hood in various places.
193
194
 
194
195
  === Chingu::GameObject
195
- This is our basic "game unit"-class, meaning most in game objects (players, enemies, bullets etc) should be inherited from Chingu::GameObject. The basic ideas behind it are:
196
+ This is our basic "game unit"-class, meaning most in game objects (players, enemies, bullets etc) should be inherited from Chingu::GameObject.
197
+ The basic ideas behind it are:
196
198
 
197
199
  * Encapsulate only the very common basics that Most in game objects need
198
200
  * Keep naming close to Gosu, but add smart convenient methods / shortcuts and a more rubyish feeling
@@ -452,20 +454,25 @@ Text is a class to give the use of Gosu::Font more rubyish feel and fit it bette
452
454
  @font.draw("A Text", 200, 50, 55, 2.0)
453
455
 
454
456
  # Chingu
455
- @text = Chingu::Text.new(:text => "A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
457
+ @text = Chingu::Text.create(:text => "A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
456
458
  @text.draw
457
459
 
458
- @text.draw is usually not needed as Text is a GameObject and therefore autodrawn.
459
- It's not only that the second example is readable by ppl now even familiar with Gosu, @text comes with a number of changeable properties, x,y,zorder,angle,factor_x,color,mode etc. Set a new x or angle or color and it will instantly update on screen.
460
+ @text.draw is usually not needed as Text is a GameObject and therefore automaticly updated/drawn (it #create is used instead of #new)
461
+ It's not only that the second example is readable by ppl now even familiar with Gosu, @text comes with a number of changeable properties, x,y,zorder,angle,factor_x,color,mode etc.
462
+ Set a new x or angle or color and it will instantly update on screen.
460
463
 
461
464
 
462
465
  == MISC / FAQ
463
- How do I access my main-window easily?
464
-
466
+ === How do I access my main-window easily?
465
467
  Chingu keeps a global variable, $window, which contains the Chingu::Window instance.
466
468
  Since Chingu::Window is just Gosu::Window + some cheese you can do your $window.button_down?, $window.draw_line() etc from anywhere.
467
469
  See http://www.libgosu.org/rdoc/classes/Gosu/Window.html for a full set of methods.
468
470
 
471
+ === How did you decide on naming of methods / classes?
472
+ There's 1 zillion ways of naming stuff. As a general guideline I've tried to follow Gosus naming.
473
+ If Gosu didn't have a good name for a certain thing/method I've checked Ruby itself and then Rails since alot
474
+ of Ruby-devs are familiar with Rails.
475
+
469
476
  == TODO:
470
477
  * add :padding and :align => :topleft etc to class Text
471
478
  * (skip) rename Chingu::Window so 'include Chingu' and 'include Gosu' wont make Window collide
@@ -486,7 +493,7 @@ See http://www.libgosu.org/rdoc/classes/Gosu/Window.html for a full set of metho
486
493
  * (done) Automate gemgenning rake-task even more
487
494
  * (done) More examples when effects are more complete
488
495
  * class ChipmunkObject
489
- * (has_trait :velocity :p..) class Actor/MovingActor with maybe a bit more logic then the basic GameObject. Would ppl find is useful?
496
+ * (done) class Actor/MovingActor with maybe a bit more logic then the basic GameObject.
490
497
  * (60% done) Spell check all docs, sloppy spelling turns ppl off. tnx jduff ;).
491
498
  * Tests
492
499
  * (done) Streamline fps / tick code
@@ -1,9 +1,22 @@
1
1
  require 'benchmark'
2
2
  require 'rubygems'
3
- require 'randomr'
3
+ require 'set'
4
4
 
5
5
  class Foo
6
+ @list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
7
+ @@list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
8
+
9
+ def self.list
10
+ @list
11
+ end
12
+
13
+ def self.list2
14
+ @@list2
15
+ end
16
+
17
+ attr_accessor :list
6
18
  def initialize
19
+ @list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
7
20
  end
8
21
 
9
22
  def bar
@@ -12,7 +25,35 @@ end
12
25
 
13
26
  foo = Foo.new
14
27
 
28
+
29
+ s = Set.new
15
30
  a = Array.new
31
+ h = Hash.new
32
+ h[:a] = Array.new
33
+
34
+ n = 1000000
35
+ Benchmark.bm(22) do |x|
36
+ x.report('Array << ') do
37
+ n.times do
38
+ a << n
39
+ end
40
+ end
41
+
42
+ x.report('Set << ') do
43
+ n.times do
44
+ s << n
45
+ end
46
+ end
47
+
48
+ x.report('Hash[:a] << ') do
49
+ n.times do
50
+ h[:a] << n
51
+ end
52
+ end
53
+ end
54
+
55
+
56
+
16
57
  n = 1000000
17
58
  Benchmark.bm(22) do |x|
18
59
  x.report('respond_to?') do
@@ -27,3 +68,24 @@ Benchmark.bm(22) do |x|
27
68
  end
28
69
  end
29
70
  end
71
+
72
+ n = 100000
73
+ Benchmark.bm(22) do |x|
74
+ x.report('ivar axx') do
75
+ n.times do
76
+ foo.list.each { |num| }
77
+ end
78
+ end
79
+
80
+ x.report('class attribute axx') do
81
+ n.times do
82
+ Foo.list.each { |num| }
83
+ end
84
+ end
85
+
86
+ x.report('class var axx') do
87
+ n.times do
88
+ Foo.list2.each { |num| }
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,23 @@
1
+ require 'benchmark'
2
+ require 'rubygems'
3
+ require 'set'
4
+
5
+ a = [1,2,3,4,5]
6
+ h = {1=>"b",2=>"b",3=>"b",4=>"b",5=>"b"}
7
+
8
+ n = 1000000
9
+ Benchmark.bm(22) do |x|
10
+
11
+ x.report('Array.each ') do
12
+ n.times do
13
+ a.each {}
14
+ end
15
+ end
16
+
17
+ x.report('Hash.each') do
18
+ n.times do
19
+ h.each {}
20
+ end
21
+ end
22
+
23
+ end
data/chingu.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{chingu}
5
- s.version = "0.5.4"
5
+ s.version = "0.5.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["ippa"]
9
- s.date = %q{2009-09-17}
9
+ s.date = %q{2009-09-22}
10
10
  s.description = %q{Game framework built on top of the OpenGL accelerated game lib Gosu.
11
11
  It adds simple yet powerful game states, prettier input handling, deployment safe asset-handling, a basic re-usable game object and automation of common task.}
12
12
  s.email = ["ippa@rubylicio.us"]
13
13
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "benchmarks/README.txt"]
14
- s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/particle.png", "examples/media/ruby.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/actor.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.rb", "lib/chingu/effects.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/gfx_helpers.rb", "lib/chingu/helpers.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/effect_module.rb", "lib/chingu/traits/input.rb", "lib/chingu/traits/rotation_center.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/traits/velocity_module.rb", "lib/chingu/window.rb"]
14
+ s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/benchmark6.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example11.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/particle.png", "examples/media/ruby.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/actor.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.rb", "lib/chingu/effects.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_object_list.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/gfx_helpers.rb", "lib/chingu/helpers.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/input.rb", "lib/chingu/traits/rotation_center.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
15
15
  s.homepage = %q{http://github.com/ippa/chingu/tree/master}
16
16
  s.rdoc_options = ["--main", "README.rdoc"]
17
17
  s.require_paths = ["lib"]
data/examples/example1.rb CHANGED
@@ -14,7 +14,7 @@ include Gosu
14
14
  class Game < Chingu::Window
15
15
  def initialize
16
16
  super(640,480,false) # leave it blank and it will be 800,600,non fullscreen
17
- @player = Player.new(:x => 200, :y => 200, :image => Image["spaceship.png"])
17
+ @player = Player.create(:x => 200, :y => 200, :image => Image["spaceship.png"])
18
18
  @player.input = { :holding_left => :move_left, :holding_right => :move_right,
19
19
  :holding_up => :move_up, :holding_down => :move_down, :escape => :exit}
20
20
  p RUBY_VERSION
@@ -10,10 +10,10 @@ $stderr.sync = $stdout.sync = true
10
10
  #
11
11
  class Game < Chingu::Window
12
12
  def initialize
13
- super(400,400)
13
+ super(600,400)
14
14
  self.caption = "Testing out new module-based traits (SPACE for more spaceships)"
15
- self.input = { :space => :new_thing, :esc => :exit }
16
- new_thing(200,200)
15
+ self.input = { :space => :create_thing, :esc => :exit }
16
+ create_thing(200,200)
17
17
  end
18
18
 
19
19
  def update
@@ -26,8 +26,8 @@ class Game < Chingu::Window
26
26
  super
27
27
  end
28
28
 
29
- def new_thing(x=nil, y=nil)
30
- Thing.new(:x => x||rand($window.width), :y => y||rand($window.height), :debug => true)
29
+ def create_thing(x=nil, y=nil)
30
+ Thing.create(:x => x||rand($window.width), :y => y||rand($window.height), :debug => true)
31
31
  end
32
32
  end
33
33
 
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'opengl'
3
+ require 'gosu'
4
+ #include Gosu
5
+
6
+ class Game < Gosu::Window
7
+ def initialize
8
+ super(400,400,false)
9
+ end
10
+
11
+ def update
12
+ end
13
+
14
+ def draw
15
+ gl do
16
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
17
+
18
+ # Reset the view
19
+ glLoadIdentity
20
+
21
+ # Move to the left 1.5 units and into the screen 6.0 units
22
+ glTranslate(-1.5, 0.0, -6.0)
23
+
24
+ # -- Draw a triangle --
25
+ glColor(1.0,1.0,1.0)
26
+
27
+ # Begin drawing a polygon
28
+ glBegin(GL_POLYGON)
29
+ glVertex3f( 0.0, 1.0, 0.0) # Top vertex
30
+ glVertex3f( 1.0, -1.0, 0.0) # Bottom right vertex
31
+ glVertex3f(-1.0, -1.0, 0.0) # Bottom left vertex
32
+ # Done with the polygon
33
+ glEnd
34
+
35
+ # Move 3 units to the right
36
+ glTranslate(3.0, 0.0, 0.0)
37
+
38
+ # -- Draw a square (quadrilateral) --
39
+ # Begin drawing a polygon (4 sided)
40
+ glBegin(GL_QUADS)
41
+ glVertex3f(-1.0, 1.0, 0.0) # Top Left vertex
42
+ glVertex3f( 1.0, 1.0, 0.0) # Top Right vertex
43
+ glVertex3f( 1.0, -1.0, 0.0) # Bottom Right vertex
44
+ glVertex3f(-1.0, -1.0, 0.0) # Bottom Left
45
+ glEnd
46
+ glFlush
47
+ end
48
+ end
49
+ end
50
+
51
+ Game.new.show
data/examples/example2.rb CHANGED
@@ -16,7 +16,7 @@ class Game < Chingu::Window
16
16
  #
17
17
  super
18
18
 
19
- push_game_state(Play.new)
19
+ push_game_state(Play)
20
20
  end
21
21
  end
22
22
 
@@ -35,7 +35,7 @@ class Player < Chingu::GameObject
35
35
  def move_down; @y += 1; end
36
36
 
37
37
  def fire
38
- Bullet.new(:x => @x, :y => @y)
38
+ Bullet.create(:x => @x, :y => @y)
39
39
  end
40
40
  end
41
41
 
@@ -59,7 +59,7 @@ class Play < Chingu::GameState
59
59
 
60
60
  def initialize
61
61
  super
62
- @player = Player.new(:x => 200, :y => 200)
62
+ @player = Player.create(:x => 200, :y => 200)
63
63
  @player.input = { :holding_left => :move_left,
64
64
  :holding_right => :move_right,
65
65
  :holding_up => :move_up,
@@ -108,7 +108,7 @@ class Play < Chingu::GameState
108
108
  #
109
109
 
110
110
  super
111
- $window.caption = "FPS: #{$window.fps} - milliseconds_since_last_tick: #{$window.milliseconds_since_last_tick} - game objects# #{current_game_state.game_objects.size}"
111
+ $window.caption = "FPS: #{$window.fps} - milliseconds_since_last_tick: #{$window.milliseconds_since_last_tick} - game objects# #{current_game_state.game_objects.size} Bullets# #{Bullet.size}"
112
112
  end
113
113
  end
114
114
 
data/examples/example3.rb CHANGED
@@ -11,7 +11,7 @@ class Game < Chingu::Window
11
11
  super
12
12
  self.input = {:holding_left => :scroll_left, :holding_right => :scroll_right, :escape => :exit}
13
13
 
14
- @parallax = Chingu::Parallax.new(:x => 0, :y => 0, :center_x => 0, :center_y => 0)
14
+ @parallax = Chingu::Parallax.create(:x => 0, :y => 0, :center_x => 0, :center_y => 0)
15
15
 
16
16
  #
17
17
  # If no :zorder is given to @parallax.add_background it defaults to first added -> lowest zorder
data/examples/example4.rb CHANGED
@@ -34,7 +34,7 @@ class Game < Chingu::Window
34
34
  push_game_state(Intro)
35
35
 
36
36
  # Yes you can do crazy things like this :)
37
- self.input = { :left_mouse_button => lambda{Chingu::Text.new(:text => "Woff!")}, :esc => :exit}
37
+ self.input = { :left_mouse_button => lambda{Chingu::Text.create(:text => "Woff!")}, :esc => :exit}
38
38
  end
39
39
  end
40
40
 
@@ -51,9 +51,11 @@ class Player < Chingu::GameObject
51
51
  def move_down; @y += 1; end
52
52
 
53
53
  def fire
54
- Bullet.new(:x => @x - 20, :y => @y)
55
- Bullet.new(:x => @x, :y => @y)
56
- Bullet.new(:x => @x + 20, :y => @y)
54
+ #puts $window.current_parent.to_s
55
+ #puts $window.game_state_manager.inside_state
56
+ Bullet.create(:x => @x - 20, :y => @y)
57
+ Bullet.create(:x => @x, :y => @y)
58
+ Bullet.create(:x => @x + 20, :y => @y)
57
59
  end
58
60
  end
59
61
 
@@ -74,9 +76,9 @@ end
74
76
  # GAMESTATE #1 - INTRO
75
77
  #
76
78
  class Intro < Chingu::GameState
77
- def initialize(options)
79
+ def initialize(options = {})
78
80
  super
79
- @title = Chingu::Text.new(:text=>"Press and release F1", :x=>200, :y=>50, :size=>30)
81
+ @title = Chingu::Text.create(:text=>"Press and release F1", :x=>200, :y=>50, :size=>30)
80
82
  self.input = { :f1 => :pressed, :released_f1 => :released, :f2 => Menu}
81
83
  end
82
84
 
@@ -93,9 +95,9 @@ end
93
95
  # GAMESTATE #2 - MENU
94
96
  #
95
97
  class Menu < Chingu::GameState
96
- def initialize(options)
98
+ def initialize(options = {})
97
99
  super
98
- @title = Chingu::Text.new(:text => "Press 'S' to Start game", :x=>100, :y=>50, :size=>30)
100
+ @title = Chingu::Text.create(:text => "Press 'S' to Start game", :x=>100, :y=>50, :size=>30)
99
101
  self.input = { :s => Level.new(:level => 10) }
100
102
  end
101
103
  end
@@ -107,10 +109,10 @@ class Level < Chingu::GameState
107
109
  #
108
110
  # initialize() is called when you create the game state
109
111
  #
110
- def initialize(options)
112
+ def initialize(options = {})
111
113
  super
112
- @title = Chingu::Text.new(:text=>"Level #{options[:level].to_s}. P: pause R:restart", :x=>20, :y=>10, :size=>30)
113
- @player = Player.new
114
+ @title = Chingu::Text.create(:text=>"Level #{options[:level].to_s}. P: pause R:restart", :x=>20, :y=>10, :size=>30)
115
+ @player = Player.create
114
116
  @player.input = { :holding_left => :move_left,
115
117
  :holding_right => :move_right,
116
118
  :holding_up => :move_up,
@@ -127,7 +129,7 @@ class Level < Chingu::GameState
127
129
  def update
128
130
  super
129
131
  Bullet.destroy_if {|bullet| bullet.outside_window? }
130
- $window.caption = "FPS: #{$window.fps} - GameObjects: #{game_objects.size}"
132
+ $window.caption = "FPS: #{$window.fps} - GameObjects: #{game_objects.size} - Bullets: #{Bullet.size}"
131
133
  end
132
134
 
133
135
  #
@@ -137,8 +139,12 @@ class Level < Chingu::GameState
137
139
  # This can be useful if you want to display some kind of box above the gameplay (pause/options/info/... box)
138
140
  #
139
141
  def setup
142
+ # Destroy all created objects of class Bullet
143
+ #p Bullet.size
144
+ #puts Bullet.all
145
+ Bullet.destroy_all
146
+
140
147
  # Place player in a good starting position
141
- Bullet.clear
142
148
  @player.x = $window.width/2
143
149
  @player.y = $window.height - @player.image.height
144
150
  end
@@ -150,9 +156,9 @@ end
150
156
  # NOTICE: Chingu now comes with a predefined Chingu::GameStates::Pause that works simular to this!
151
157
  #
152
158
  class Pause < Chingu::GameState
153
- def initialize(options)
159
+ def initialize(options = {})
154
160
  super
155
- @title = Chingu::Text.new(:text=>"PAUSED (press 'u' to un-pause)", :x=>100, :y=>200, :size=>20, :color => Color.new(0xFF00FF00))
161
+ @title = Chingu::Text.create(:text=>"PAUSED (press 'u' to un-pause)", :x=>100, :y=>200, :size=>20, :color => Color.new(0xFF00FF00))
156
162
  self.input = { :u => :un_pause }
157
163
  end
158
164
 
@@ -161,8 +167,8 @@ class Pause < Chingu::GameState
161
167
  end
162
168
 
163
169
  def draw
164
- previous_game_state.draw # Draw prev game state onto screen (in this case our level)
165
- super # Draw game objects in current game state, this includes Chingu::Texts
170
+ previous_game_state.draw # Draw prev game state onto screen (in this case our level)
171
+ super # Draw game objects in current game state, this includes Chingu::Texts
166
172
  end
167
173
  end
168
174
 
data/examples/example7.rb CHANGED
@@ -87,7 +87,7 @@ class Particles < Chingu::GameState
87
87
  #
88
88
  # Fire 1. Dies quickly (big :fade). Small in size (small :zoom)
89
89
  #
90
- Chingu::Particle.new( :x => 100,
90
+ Chingu::Particle.create( :x => 100,
91
91
  :y => @ground_y,
92
92
  :animation => @fireball_animation,
93
93
  :zooming => +0.05,
@@ -99,7 +99,7 @@ class Particles < Chingu::GameState
99
99
  #
100
100
  # Fire 2. Higher flame, :fade only -4. Wide Flame with bigger :zoom.
101
101
  #
102
- Chingu::Particle.new( :x => 300,
102
+ Chingu::Particle.create( :x => 300,
103
103
  :y => @ground_y,
104
104
  :animation => @fireball_animation,
105
105
  :zooming => +0.2,
@@ -110,15 +110,15 @@ class Particles < Chingu::GameState
110
110
  #
111
111
  # Fire 3. Blue plasma with smooth particle.png and color-overlay.
112
112
  #
113
- Chingu::Particle.new( :x => 500,
113
+ Chingu::Particle.create( :x => 500,
114
114
  :y => @ground_y,
115
115
  :image => "particle.png",
116
116
  :color => @blue_laserish,
117
117
  :mode => :additive
118
118
  )
119
119
 
120
- game_objects_of_class(Particle).each { |particle| particle.y -= 5; particle.x += 2 - rand(4) }
121
- self.game_objects.reject! { |object| object.outside_window? || object.color.alpha == 0 }
120
+ Particle.all.each { |particle| particle.y -= 5; particle.x += 2 - rand(4) }
121
+ game_objects.destroy_if { |object| object.outside_window? || object.color.alpha == 0 }
122
122
  super
123
123
  end
124
124
 
data/examples/example8.rb CHANGED
@@ -54,10 +54,10 @@ class Particles < Chingu::GameState
54
54
  # first optimization: 490 particles, 47 fps (350 @ 60)
55
55
  # optimized GameObject if/elsif: 490 particles, 50 fps
56
56
  #
57
- Plasma.new(:x => 0, :y => 0 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 10)
58
- Plasma.new(:x => 0, :y => 50 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 14)
59
- Plasma.new(:x => 0, :y => 100 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 7)
60
- Plasma.new(:x => 0, :y => 200 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 6)
57
+ Plasma.create(:x => 0, :y => 0 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 10)
58
+ Plasma.create(:x => 0, :y => 50 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 14)
59
+ Plasma.create(:x => 0, :y => 100 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 7)
60
+ Plasma.create(:x => 0, :y => 200 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 6)
61
61
 
62
62
  Plasma.all.each do |particle|
63
63
  #
@@ -93,7 +93,7 @@ class Particles < Chingu::GameState
93
93
  # +4 fps
94
94
  #
95
95
  #self.game_objects.reject! { |object| object.outside_window? || object.color.alpha == 0 }
96
- self.game_objects.reject! { |object| object.color.alpha == 0 }
96
+ self.game_objects.destroy_if { |object| object.color.alpha == 0 }
97
97
 
98
98
  super
99
99
  end
data/examples/example9.rb CHANGED
@@ -18,7 +18,8 @@ class Game < Chingu::Window
18
18
  end
19
19
 
20
20
  class FireCube < Chingu::GameObject
21
- has_traits :velocity, :effect
21
+ has_trait :velocity
22
+ has_trait :effect
22
23
  has_trait :collision_detection
23
24
  #
24
25
  # TODO:
@@ -26,27 +27,39 @@ class FireCube < Chingu::GameObject
26
27
  # has_trait :collision_detection, :type => :radius
27
28
  #
28
29
 
29
- attr_accessor :color
30
+ attr_accessor :color, :radius
30
31
 
31
32
  def initialize(options)
32
33
  super
33
34
  @mode = :additive
34
35
 
35
36
  # initialize with a rightwards velocity with some damping to look more realistic
36
- @velocity_x = options[:velocity_x] || 3 - rand(6)
37
- @velocity_y = options[:velocity_y] || 3 - rand(6)
38
- @bounding_box = Rect.new([@x, @y, 20, 20])
39
- @color = Color.new(255,100,255,255)
37
+ @velocity_x = options[:velocity_x] || 1 + rand(2)
38
+ @velocity_y = options[:velocity_y] || 1 + rand(2)
39
+
40
+ @bounding_box = Rect.new([@x, @y, 10, 10])
41
+ @radius = 12
42
+
43
+ @blue = Color.new(255,100,255,255)
44
+ @red = Color.new(255,255,10,10)
45
+ @color = @blue
40
46
  end
41
47
 
42
48
  def draw
43
49
  $window.fill_rect(@bounding_box, @color)
44
50
  end
45
51
 
52
+ def update
53
+ @color = @blue
54
+ super
55
+ end
56
+
57
+ def collides?(object2)
58
+ radius_collision?(object2)
59
+ end
60
+
46
61
  def die!
47
- @color = Color.new(255,255,255,255)
48
- self.fading = -20
49
- self.detect_collisions = false
62
+ @color = @red
50
63
  end
51
64
 
52
65
  end
@@ -54,14 +67,16 @@ end
54
67
  class Particles < Chingu::GameState
55
68
  def setup
56
69
  self.input = { :space => :new_fire_cube }
57
- 20.times { new_fire_cube }
70
+ 100.times { new_fire_cube }
58
71
  end
59
72
 
60
73
  def new_fire_cube
61
- FireCube.new(:x => rand($window.width), :y => rand($window.height))
74
+ FireCube.create(:x => rand($window.width), :y => rand($window.height))
62
75
  end
63
76
 
64
- def update
77
+ def update
78
+ super
79
+
65
80
  FireCube.all.each do |particle|
66
81
  if particle.x < 0 || particle.x > $window.width
67
82
  particle.velocity_x = -particle.velocity_x
@@ -73,20 +88,18 @@ class Particles < Chingu::GameState
73
88
  end
74
89
 
75
90
  #
76
- # GameObject.each_collsion wont collide an object with itself
91
+ # GameObject.each_collsion / each_radius_collision wont collide an object with itself
77
92
  #
78
- FireCube.each_collision(FireCube) do |cube1, cube2|
93
+ FireCube.each_radius_collision(FireCube) do |cube1, cube2|
79
94
  cube1.die!
80
95
  cube2.die!
81
96
  end
82
97
 
83
- self.game_objects.reject! { |object| object.color.alpha == 0 }
84
-
85
- super
98
+ game_objects.destroy_if { |object| object.color.alpha == 0 }
86
99
  end
87
100
 
88
101
  def draw
89
- $window.caption = "particle example (esc to quit) [particles#: #{game_objects.size} - framerate: #{$window.fps}]"
102
+ $window.caption = "Radius based collision Detection between all particles. Particles#: #{game_objects.size} - FPS: #{$window.fps}"
90
103
  super
91
104
  end
92
105
  end
@@ -6,8 +6,9 @@ module Chingu
6
6
  # It will also acts as a container for the trait-system of chingu.
7
7
  #
8
8
  class BasicGameObject
9
- attr_reader :options, :parent
10
-
9
+ attr_reader :options
10
+ attr_accessor :parent
11
+
11
12
  #
12
13
  # adds a trait or traits to a certain game class
13
14
  #
@@ -29,29 +30,40 @@ module Chingu
29
30
  end
30
31
 
31
32
  #
32
- # BasicGameUnit initialize
33
- #
34
- # - caches all trait methods for fast calls later on
35
- # - call .setup() on all traits that implements it
36
- # - adds game object to correct game state or $window if no game state exists
33
+ # BasicGameObject initialize
34
+ # - call .setup_trait() on all traits that implements it
37
35
  #
38
36
  def initialize(options = {})
39
37
  @options = options
40
38
 
39
+ # This will call #setup_trait on the latest trait mixed in
40
+ # which then will pass it on to the next setup_trait() with a super-call.
41
+ setup_trait(options)
42
+ end
43
+
44
+ #
45
+ # Creates a new object from class just as new() but also:
46
+ # - adds game object to current game state
47
+ # - or $window if no game state exists
48
+ #
49
+ # Use create() instead of new() if you want to keep track of your objects through
50
+ # Chingus "game_objects" which is available in all game states and the main window.
51
+ #
52
+ def self.create(options = {})
53
+ instance = self.new(options)
54
+
41
55
  #
42
- # A GameObject can either belong to a GameState or our mainwindow ($window)
43
- # .. or live in limbo with manual updates
56
+ # A GameObject either belong to a GameState or our mainwindow ($window)
44
57
  #
45
58
  if $window && $window.respond_to?(:game_state_manager)
46
- @parent = $window.game_state_manager.inside_state || $window
47
- @parent.add_game_object(self) if @parent
59
+ if (instance.parent = $window.game_state_manager.inside_state || $window)
60
+ instance.parent.add_game_object(instance)
61
+ end
48
62
  end
49
63
 
50
- # This will call #setup on the latest trait mixed in, which then will pass it on with super.
51
- setup_trait(options)
64
+ return instance
52
65
  end
53
66
 
54
-
55
67
  def setup_trait(options)
56
68
  end
57
69
 
@@ -62,20 +74,26 @@ module Chingu
62
74
  end
63
75
 
64
76
  #
65
- # Fetch all objects of a current class.
66
- # Bullet.all # => Enumerator of all objects of class Bullet
77
+ # Returns an array with all objects of current class.
78
+ # BasicGameObject#all is state aware so only objects belonging to the current state will be returned.
67
79
  #
68
- # NOTE: ObjectSpace doesn't play nice with jruby.
80
+ # Bullet.all.each do {} # Iterate through all bullets in current game state
69
81
  #
70
82
  def self.all
71
- ObjectSpace.each_object(self)
83
+ $window.current_parent.game_objects.of_class(self).dup
84
+ end
85
+
86
+ #
87
+ # Returns
88
+ #
89
+ def self.size
90
+ $window.current_parent.game_objects.of_class(self).size
72
91
  end
73
92
 
74
93
  #
75
94
  # Destroy all instances of current class that fills a certain condition
76
95
  # Enemy.destroy_if(&:dead?) # Assumes Enemy.dead? returns true/false depending on aliveness :)
77
96
  #
78
- #
79
97
  def self.destroy_if(&block)
80
98
  all.each do |object|
81
99
  object.destroy! if yield(object)
@@ -83,11 +101,11 @@ module Chingu
83
101
  end
84
102
 
85
103
  #
86
- # Clear all intances of objects class:
87
- # Bullet.clear # Removes all Bullet objects from the game
104
+ # Destroys all intances of objects class:
105
+ # Bullet.destroy_all # Removes all Bullet objects from the game
88
106
  #
89
- def self.clear
90
- all.each { |object| object.destroy! }
107
+ def self.destroy_all
108
+ self.all.each { |object| object.destroy! }
91
109
  end
92
110
 
93
111
  #
@@ -0,0 +1,81 @@
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
+ #
25
+ # Manages a list of game objects
26
+ # An instance of GameObjectList is automaticly created as "game_objects" if using Chingu::Window
27
+ #
28
+ class GameObjectList
29
+
30
+ def initialize
31
+ @game_objects = Array.new
32
+ #@game_objects_by_class = Hash.new
33
+ end
34
+
35
+ def to_s
36
+ "#{@game_objects.size} game objects."
37
+ end
38
+
39
+ def of_class(klass)
40
+ @game_objects.select { |game_object| game_object.is_a? klass }
41
+ #@game_objects_by_class[klass] || []
42
+ end
43
+
44
+ def remove_all
45
+ @game_objects.clear
46
+ #@game_objects_of_class.clear
47
+ end
48
+ alias :clear :remove_all
49
+
50
+ def add_game_object(object)
51
+ @game_objects.push(object)
52
+ #(@game_objects_by_class[object.class] ||= []).push(object)
53
+ end
54
+
55
+ def remove_game_object(object)
56
+ @game_objects.delete(object)
57
+ #@game_objects_by_class[object.class].delete(object)
58
+ end
59
+
60
+ def destroy_if
61
+ @game_objects.reject! { |object| yield(object) }
62
+ #@game_objects_by_class.delete_if { |klass, object| yield(object) }
63
+ end
64
+
65
+ def size
66
+ @game_objects.size
67
+ end
68
+
69
+ def draw
70
+ @game_objects.each { |object| object.draw }
71
+ end
72
+
73
+ def update
74
+ @game_objects.each { |object| object.update }
75
+ end
76
+
77
+ def each
78
+ @game_objects.each { |object| yield object }
79
+ end
80
+ end
81
+ end
@@ -56,12 +56,12 @@ module Chingu
56
56
  include Chingu::InputClient
57
57
 
58
58
  attr_reader :options # so jlnr can access his :level-number
59
- attr_accessor :game_state_manager
59
+ attr_accessor :game_state_manager, :game_objects
60
60
 
61
61
  def initialize(options = {})
62
62
  @options = options
63
63
  ## @game_state_manager = options[:game_state_manager] || $window.game_state_manager
64
- @game_objects = Set.new
64
+ @game_objects = GameObjectList.new
65
65
  @input_clients = Set.new # Set is like a unique Array with Hash lookupspeed
66
66
 
67
67
  # Game state mamanger can be run alone
@@ -69,12 +69,7 @@ module Chingu
69
69
  $window.game_state_manager.inside_state = self
70
70
  end
71
71
  end
72
-
73
- def game_objects
74
- return [] unless defined?(@game_objects)
75
- return @game_objects
76
- end
77
-
72
+
78
73
  #
79
74
  # An unique identifier for the GameState-class,
80
75
  # Used in game state manager to keep track of created states.
@@ -86,13 +81,6 @@ module Chingu
86
81
  def to_s
87
82
  self.class.to_s
88
83
  end
89
-
90
- def add_game_object(object)
91
- @game_objects << object
92
- end
93
- def remove_game_object(object)
94
- @game_objects.delete(object)
95
- end
96
84
 
97
85
  def setup
98
86
  # Your game state setup logic here.
@@ -122,14 +110,14 @@ module Chingu
122
110
 
123
111
  @input_clients.each { |game_object| dispatch_input_for(game_object) }
124
112
 
125
- @game_objects.each { |object| object.update }
113
+ @game_objects.update
126
114
  end
127
115
 
128
116
  #
129
117
  # Calls Draw on each game object that has current game state as parent (created inside that game state)
130
118
  #
131
119
  def draw
132
- @game_objects.each { |object| object.draw }
120
+ @game_objects.draw
133
121
  end
134
122
 
135
123
  #
@@ -280,7 +280,7 @@ module Chingu
280
280
  # If state is a GameState-class, create it.
281
281
  #
282
282
  elsif state.superclass == Chingu::GameState
283
- new_state = state.new({})
283
+ new_state = state.new
284
284
  end
285
285
 
286
286
  return new_state
@@ -142,6 +142,19 @@ module Chingu
142
142
  end
143
143
 
144
144
  module GameObjectHelpers
145
+
146
+ def add_game_object(object)
147
+ @game_objects.add_game_object(object)
148
+ end
149
+
150
+ def remove_game_object(object)
151
+ @game_objects.remove_game_object(object)
152
+ end
153
+
154
+ def game_objects
155
+ @game_objects
156
+ end
157
+
145
158
  #
146
159
  # Fetch game objects of a certain type/class
147
160
  #
@@ -23,8 +23,11 @@
23
23
  module Chingu
24
24
  module Traits
25
25
  #
26
+ # Research:
27
+ # 1) QuadTrees: http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
28
+ # 2) Sweep and Prune
26
29
  #
27
- # Use QuadTrees: http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
30
+ # SEE: http://www.shmup-dev.com/forum/index.php?board=65.0
28
31
  #
29
32
  # Makes use of 3 attributes
30
33
  # @bounding_box - a Rect-instance, uses in bounding_box collisions
@@ -32,7 +35,8 @@ module Chingu
32
35
  # @detect_collisions - [true|false], should object be checked for collisions with Object.each_collision
33
36
  #
34
37
  module CollisionDetection
35
- attr_accessor :bounding_box, :radius, :detect_collisions
38
+ attr_accessor :bounding_box, :radius
39
+ ## attr_accessor :detect_collisions # slowed down example9 with 3 fps
36
40
 
37
41
  def self.included(base)
38
42
  base.extend(ClassMethods)
@@ -47,10 +51,10 @@ module Chingu
47
51
  end
48
52
 
49
53
  if @image
50
- @radius ||= @image.width / 2
54
+ @radius ||= (@image.height + @image.width) / 2 * 0.80
51
55
  end
52
56
 
53
- @detect_collisions = true
57
+ ## @detect_collisions = true
54
58
  super
55
59
  end
56
60
 
@@ -59,9 +63,9 @@ module Chingu
59
63
  # By default it calls bounding_box_collision? which will check for intersectons between the
60
64
  # two objects "bounding_box" attributs (a Chingu::Rect instance)
61
65
  #
62
- def collision?(object2)
63
- #bounding_box_collision?(object2)
64
- radius_collision?(object2)
66
+ def collides?(object2)
67
+ bounding_box_collision?(object2)
68
+ #radius_collision?(object2)
65
69
  end
66
70
 
67
71
  #
@@ -77,7 +81,7 @@ module Chingu
77
81
  # Returns true if colliding.
78
82
  #
79
83
  def radius_collision?(object2)
80
- distance(self.x, self.y, object2.x, object2.y) < self.radius + object2.radius
84
+ distance(self.x, self.y, object2.x, object2.y) < self.radius# + object2.radius
81
85
  end
82
86
 
83
87
  #
@@ -92,8 +96,39 @@ module Chingu
92
96
  super
93
97
  end
94
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
+ if object.detect_collisions
107
+ yield(self, object) if collides?(object)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
95
113
 
96
114
  module ClassMethods
115
+
116
+ #
117
+ # Works like each_collsion but with inline-code for speedups
118
+ #
119
+ def each_radius_collision(klasses = [])
120
+ Array(klasses).each do |klass|
121
+ object2_list = klass.all
122
+
123
+ self.all.each do |object1|
124
+ object2_list.each do |object2|
125
+ next if object1 == object2 # Don't collide objects with themselves
126
+ yield object1, object2 if distance(object1.x, object1.y, object2.x, object2.y) < object1.radius
127
+ end
128
+ end
129
+ end
130
+ end
131
+
97
132
  #
98
133
  # Class method that will check for collisions between all instances of two classes
99
134
  # and yield the 2 colliding game object instances.
@@ -108,17 +143,17 @@ module Chingu
108
143
  def each_collision(klasses = [])
109
144
  # Make sure klasses is always an array.
110
145
  Array(klasses).each do |klass|
146
+ object2_list = klass.all
147
+
111
148
  self.all.each do |object1|
112
- klass.all.each do |object2|
149
+ object2_list.all.each do |object2|
113
150
  next if object1 == object2 # Don't collide objects with themselves
114
-
115
- if object1.detect_collisions && object2.detect_collisions
116
- yield object1, object2 if object1.collision?(object2)
117
- end
151
+ yield object1, object2 if object1.collides?(object2)
118
152
  end
119
153
  end
120
154
  end
121
155
  end
156
+
122
157
  end
123
158
 
124
159
  end
data/lib/chingu/window.rb CHANGED
@@ -39,7 +39,7 @@ module Chingu
39
39
  Gosu::Tile.autoload_dirs = [".", File.join(@root, "gfx"), File.join(@root, "media")]
40
40
  Gosu::Song.autoload_dirs = [".", File.join(@root, "sfx"), File.join(@root, "media")]
41
41
 
42
- @game_objects = Set.new
42
+ @game_objects = GameObjectList.new
43
43
  @input_clients = Set.new # Set is like a unique Array with Hash lookupspeed
44
44
 
45
45
  @fps_counter = FPSCounter.new
@@ -47,13 +47,10 @@ module Chingu
47
47
  @milliseconds_since_last_tick = 0
48
48
  end
49
49
 
50
- def add_game_object(object)
51
- @game_objects << object
50
+ def current_parent
51
+ game_state_manager.current_game_state || self
52
52
  end
53
- def remove_game_object(object)
54
- @game_objects.delete(object)
55
- end
56
-
53
+
57
54
  #
58
55
  # Frames per second, access with $window.fps or $window.framerate
59
56
  #
@@ -126,7 +123,7 @@ module Chingu
126
123
  #
127
124
  # Draw all game objects associated with the main window.
128
125
  #
129
- @game_objects.each { |object| object.draw }
126
+ @game_objects.draw
130
127
 
131
128
  #
132
129
  # Let the game state manager call draw on the active game state (if any)
@@ -138,7 +135,7 @@ module Chingu
138
135
  # Call update() on all game objects in main game window.
139
136
  #
140
137
  def update_game_objects
141
- @game_objects.each { |object| object.update }
138
+ @game_objects.update
142
139
  end
143
140
 
144
141
  #
data/lib/chingu.rb CHANGED
@@ -28,5 +28,5 @@ require File.join(CHINGU_ROOT,"chingu","require_all") # Thanks to http://github.
28
28
  require_all "#{CHINGU_ROOT}/chingu"
29
29
 
30
30
  module Chingu
31
- VERSION = "0.5.4"
31
+ VERSION = "0.5.5"
32
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ippa-chingu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ippa
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-17 00:00:00 -07:00
12
+ date: 2009-09-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -44,11 +44,13 @@ files:
44
44
  - benchmarks/benchmark3.rb
45
45
  - benchmarks/benchmark4.rb
46
46
  - benchmarks/benchmark5.rb
47
+ - benchmarks/benchmark6.rb
47
48
  - benchmarks/meta_benchmark.rb
48
49
  - benchmarks/meta_benchmark2.rb
49
50
  - chingu.gemspec
50
51
  - examples/example1.rb
51
52
  - examples/example10.rb
53
+ - examples/example11.rb
52
54
  - examples/example2.rb
53
55
  - examples/example3.rb
54
56
  - examples/example4.rb
@@ -79,6 +81,7 @@ files:
79
81
  - lib/chingu/effects.rb
80
82
  - lib/chingu/fpscounter.rb
81
83
  - lib/chingu/game_object.rb
84
+ - lib/chingu/game_object_list.rb
82
85
  - lib/chingu/game_state.rb
83
86
  - lib/chingu/game_state_manager.rb
84
87
  - lib/chingu/game_states/debug.rb
@@ -96,11 +99,9 @@ files:
96
99
  - lib/chingu/text.rb
97
100
  - lib/chingu/traits/collision_detection.rb
98
101
  - lib/chingu/traits/effect.rb
99
- - lib/chingu/traits/effect_module.rb
100
102
  - lib/chingu/traits/input.rb
101
103
  - lib/chingu/traits/rotation_center.rb
102
104
  - lib/chingu/traits/velocity.rb
103
- - lib/chingu/traits/velocity_module.rb
104
105
  - lib/chingu/window.rb
105
106
  has_rdoc: false
106
107
  homepage: http://github.com/ippa/chingu/tree/master
@@ -1,86 +0,0 @@
1
- module Chingu
2
- module Traits
3
- module Effect
4
- #
5
- # Adds .rotating .fading and .zooming to any GameObject.
6
- #
7
- # TODO: better naming? suggestions:
8
- #
9
- # basic gosu unit <-> automation name
10
- # ==============================================
11
- # angle <-> rotation? rotating? automatic_angle?
12
- # factor <-> growth? scale? automatic_zoom?
13
- # alpha <-> fade
14
- #
15
- attr_accessor :rotating, :fading, :zooming
16
-
17
- def initialize(options)
18
- puts "Effect#initialize"
19
- super
20
- end
21
-
22
- # Zoom - increase @factor_x and @factor_y at the same time.
23
- def zoom(amount = 0.1)
24
- @factor_x += amount
25
- @factor_y += amount
26
- end
27
-
28
- # Zoom Out - decrease @factor_x and @factor_y at the same time.
29
- def zoom_out(amount = 0.1)
30
- @factor_x -= amount
31
- @factor_y -= amount
32
- end
33
-
34
- # Rotate object 'amount' degrees
35
- def rotate(amount = 1)
36
- @angle += amount
37
- end
38
-
39
- # Fade object by decreasing/increasing color.alpha
40
- def fade(amount = 1)
41
- return if amount == 0
42
-
43
- new_alpha = @color.alpha + amount
44
- if amount < 0
45
- @color.alpha = [0, new_alpha].max
46
- else
47
- @color.alpha = [0, new_alpha].min
48
- end
49
- end
50
-
51
- # Fade out objects color by decreasing color.alpha
52
- def fade_out(amount = 1)
53
- fade(-amount)
54
- end
55
-
56
- # Fade in objects color by increasing color.alpha
57
- def fade_in(amount = 1)
58
- fade(amount)
59
- end
60
-
61
- #
62
- # Setup
63
- #
64
- def setup(options)
65
- puts "Effect#setup"
66
- @rotating = options[:rotating] || nil
67
- @zooming = options[:zooming] || nil
68
- @fading = options[:fading] || nil
69
- super
70
- end
71
-
72
- def draw
73
- puts "Effect#draw"
74
- super
75
- end
76
-
77
- def update
78
- puts "Effect#update"
79
- rotate(@rotating) if @rotating
80
- fade(@fading) if @fading
81
- zoom(@zooming) if @zooming
82
- super
83
- end
84
- end
85
- end
86
- end
@@ -1,44 +0,0 @@
1
- module Chingu
2
- module Traits
3
- #
4
- # A chingu component providing velocity and acceleration logic.
5
- #
6
- module Velocity
7
- attr_accessor :velocity_x, :velocity_y, :acceleration_x, :acceleration_y, :max_velocity
8
-
9
- def initialize(options)
10
- puts "Velocity#initialize"
11
- super
12
- end
13
-
14
- def stop
15
- @acceleration_y = @acceleration_x = @velocity_y = @acceleration_y = 0
16
- end
17
-
18
- #
19
- # Setup
20
- #
21
- def setup(options)
22
- puts "Velocity#setup"
23
- @velocity_x = options[:velocity_x] || 0
24
- @velocity_y = options[:velocity_y] || 0
25
- @acceleration_x = options[:acceleration_x] || 0
26
- @acceleration_y = options[:acceleration_y] || 0
27
- @max_velocity = options[:max_velocity] || 1000
28
- super
29
- end
30
-
31
- #
32
- # Modifies X & Y of parent
33
- #
34
- def update
35
- puts "Velocity#update"
36
- @velocity_y += @acceleration_y if (@velocity_y + @acceleration_y).abs < @max_velocity
37
- @velocity_x += @acceleration_x if (@velocity_x + @acceleration_x).abs < @max_velocity
38
- @y += @velocity_y
39
- @x += @velocity_x
40
- super
41
- end
42
- end
43
- end
44
- end