ippa-chingu 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +3 -2
- data/README.rdoc +23 -16
- data/benchmarks/benchmark5.rb +63 -1
- data/benchmarks/benchmark6.rb +23 -0
- data/chingu.gemspec +3 -3
- data/examples/example1.rb +1 -1
- data/examples/example10.rb +5 -5
- data/examples/example11.rb +51 -0
- data/examples/example2.rb +4 -4
- data/examples/example3.rb +1 -1
- data/examples/example4.rb +23 -17
- data/examples/example7.rb +5 -5
- data/examples/example8.rb +5 -5
- data/examples/example9.rb +31 -18
- data/lib/chingu/basic_game_object.rb +41 -23
- data/lib/chingu/game_object_list.rb +81 -0
- data/lib/chingu/game_state.rb +5 -17
- data/lib/chingu/game_state_manager.rb +1 -1
- data/lib/chingu/helpers.rb +13 -0
- data/lib/chingu/traits/collision_detection.rb +48 -13
- data/lib/chingu/window.rb +6 -9
- data/lib/chingu.rb +1 -1
- metadata +5 -4
- data/lib/chingu/traits/effect_module.rb +0 -86
- data/lib/chingu/traits/velocity_module.rb +0 -44
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.
|
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
|
-
|
43
|
-
|
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
|
66
|
-
|
67
|
-
|
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.
|
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.
|
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.
|
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
|
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.
|
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
|
-
* (
|
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
|
data/benchmarks/benchmark5.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
require 'rubygems'
|
3
|
-
require '
|
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.
|
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-
|
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/
|
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.
|
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
|
data/examples/example10.rb
CHANGED
@@ -10,10 +10,10 @@ $stderr.sync = $stdout.sync = true
|
|
10
10
|
#
|
11
11
|
class Game < Chingu::Window
|
12
12
|
def initialize
|
13
|
-
super(
|
13
|
+
super(600,400)
|
14
14
|
self.caption = "Testing out new module-based traits (SPACE for more spaceships)"
|
15
|
-
self.input = { :space => :
|
16
|
-
|
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
|
30
|
-
Thing.
|
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
|
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.
|
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.
|
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.
|
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.
|
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
|
-
|
55
|
-
|
56
|
-
Bullet.
|
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.
|
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.
|
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.
|
113
|
-
@player = Player.
|
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.
|
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
|
165
|
-
super
|
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.
|
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.
|
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.
|
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
|
-
|
121
|
-
|
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.
|
58
|
-
Plasma.
|
59
|
-
Plasma.
|
60
|
-
Plasma.
|
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.
|
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
|
-
|
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] ||
|
37
|
-
@velocity_y = options[:velocity_y] ||
|
38
|
-
|
39
|
-
@
|
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 =
|
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
|
-
|
70
|
+
100.times { new_fire_cube }
|
58
71
|
end
|
59
72
|
|
60
73
|
def new_fire_cube
|
61
|
-
FireCube.
|
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.
|
93
|
+
FireCube.each_radius_collision(FireCube) do |cube1, cube2|
|
79
94
|
cube1.die!
|
80
95
|
cube2.die!
|
81
96
|
end
|
82
97
|
|
83
|
-
|
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 = "
|
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
|
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
|
-
#
|
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
|
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
|
-
|
47
|
-
|
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
|
-
|
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
|
-
#
|
66
|
-
#
|
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
|
-
#
|
80
|
+
# Bullet.all.each do {} # Iterate through all bullets in current game state
|
69
81
|
#
|
70
82
|
def self.all
|
71
|
-
|
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
|
-
#
|
87
|
-
# Bullet.
|
104
|
+
# Destroys all intances of objects class:
|
105
|
+
# Bullet.destroy_all # Removes all Bullet objects from the game
|
88
106
|
#
|
89
|
-
def self.
|
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
|
data/lib/chingu/game_state.rb
CHANGED
@@ -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 =
|
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.
|
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.
|
120
|
+
@game_objects.draw
|
133
121
|
end
|
134
122
|
|
135
123
|
#
|
data/lib/chingu/helpers.rb
CHANGED
@@ -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
|
-
#
|
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
|
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
|
63
|
-
|
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
|
-
|
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 =
|
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
|
51
|
-
|
50
|
+
def current_parent
|
51
|
+
game_state_manager.current_game_state || self
|
52
52
|
end
|
53
|
-
|
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.
|
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.
|
138
|
+
@game_objects.update
|
142
139
|
end
|
143
140
|
|
144
141
|
#
|
data/lib/chingu.rb
CHANGED
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
|
+
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-
|
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
|