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 +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
|