chingu 0.5.9.4 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +25 -21
- data/Manifest.txt +3 -0
- data/README.rdoc +27 -3
- data/chingu.gemspec +3 -3
- data/examples/example11.rb +15 -14
- data/examples/example13.rb +1 -1
- data/examples/example14.rb +124 -0
- data/examples/example2.rb +10 -6
- data/examples/example9.rb +4 -14
- data/examples/game1.rb +87 -76
- data/examples/high_score_list.yml +2 -2
- data/lib/chingu.rb +4 -1
- data/lib/chingu/basic_game_object.rb +34 -23
- data/lib/chingu/game_state.rb +24 -8
- data/lib/chingu/helpers/gfx.rb +13 -1
- data/lib/chingu/helpers/input_client.rb +39 -2
- data/lib/chingu/helpers/rotation_center.rb +7 -1
- data/lib/chingu/input.rb +14 -9
- data/lib/chingu/traits/bounding_box.rb +63 -0
- data/lib/chingu/traits/collision_detection.rb +8 -39
- data/lib/chingu/traits/effect.rb +3 -8
- data/lib/chingu/traits/radius.rb +55 -0
- data/lib/chingu/traits/retrofy.rb +9 -11
- data/lib/chingu/traits/timer.rb +3 -4
- data/lib/chingu/traits/velocity.rb +3 -12
- metadata +5 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
-
=== 0.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
1
|
+
=== 0.6 / 2009-11-21
|
2
|
+
More traits, better input, fixes
|
3
|
+
See github commithistory.
|
4
|
+
|
5
|
+
=== 0.5.7 / 2009-10-15
|
6
|
+
See github commithistory.
|
7
|
+
|
8
|
+
=== 0.5 / 2009-10-7
|
9
|
+
Big refactor of GameObject. Now has BasicGameObject as base.
|
10
|
+
A first basic "trait"-system where GameObject "has_traits :visual, :velocity" etc.
|
11
|
+
Tons of enhancements and fixes. Speed optimization. More examples.
|
12
|
+
|
13
|
+
=== 0.4.5 / 2009-08-27
|
14
|
+
Tons of small fixes across the board.
|
15
|
+
Started on GFX Helpers (fill, fill_rect, fill_gradient so far).
|
16
|
+
A basic particle system (see example7.rb)
|
17
|
+
|
18
|
+
=== 0.4.0 / 2009-08-19
|
19
|
+
Alot of game state love. Now also works stand alone with pure gosu.
|
20
|
+
|
21
|
+
=== 0.3.0 / 2009-08-14
|
18
22
|
Too much to list. remade inputsystem. gamestates are better. window.rb is cleaner. lots of small bugfixes. Bigger readme.
|
19
23
|
|
20
|
-
=== 0.2.0 / 2009-08-10
|
21
|
-
tons of new stuff and fixes. complete keymap. gamestate system. moreexamples/docs. better game_object.
|
22
|
-
|
23
|
-
=== 0.0.1 / 2009-08-05
|
24
|
+
=== 0.2.0 / 2009-08-10
|
25
|
+
tons of new stuff and fixes. complete keymap. gamestate system. moreexamples/docs. better game_object.
|
26
|
+
|
27
|
+
=== 0.0.1 / 2009-08-05
|
24
28
|
first release
|
data/Manifest.txt
CHANGED
@@ -17,6 +17,7 @@ examples/example10.rb
|
|
17
17
|
examples/example11.rb
|
18
18
|
examples/example12.rb
|
19
19
|
examples/example13.rb
|
20
|
+
examples/example14.rb
|
20
21
|
examples/example2.rb
|
21
22
|
examples/example3.rb
|
22
23
|
examples/example4.rb
|
@@ -83,8 +84,10 @@ lib/chingu/particle.rb
|
|
83
84
|
lib/chingu/rect.rb
|
84
85
|
lib/chingu/require_all.rb
|
85
86
|
lib/chingu/text.rb
|
87
|
+
lib/chingu/traits/bounding_box.rb
|
86
88
|
lib/chingu/traits/collision_detection.rb
|
87
89
|
lib/chingu/traits/effect.rb
|
90
|
+
lib/chingu/traits/radius.rb
|
88
91
|
lib/chingu/traits/retrofy.rb
|
89
92
|
lib/chingu/traits/timer.rb
|
90
93
|
lib/chingu/traits/velocity.rb
|
data/README.rdoc
CHANGED
@@ -66,7 +66,7 @@ For example, inside game state Menu you call push_game_state(Level). When Level
|
|
66
66
|
Traits are extensions (or plugins if you so will) to BasicGameObjects.
|
67
67
|
The aim is so encapsulate common behaivor into modules for easy inclusion in your game classes.
|
68
68
|
Making a trait is easy, just an ordinary module with the methods setup_trait(), update_trait() and/or draw_trait().
|
69
|
-
It currently has to be namespaced to Chingu::Traits for "
|
69
|
+
It currently has to be namespaced to Chingu::Traits for "has_traits" to work inside GameObject-classes.
|
70
70
|
|
71
71
|
== OTHER CLASSES / HELPERS
|
72
72
|
|
@@ -454,7 +454,7 @@ Each of those 3 methods must call "super" to continue the trait-chain.
|
|
454
454
|
Example:
|
455
455
|
|
456
456
|
class Ogre < Chingu::GameObject
|
457
|
-
|
457
|
+
has_traits :velocity, :timer
|
458
458
|
|
459
459
|
def initialize(options)
|
460
460
|
super
|
@@ -481,7 +481,10 @@ Example:
|
|
481
481
|
|
482
482
|
The flow for a game object then becomes:
|
483
483
|
|
484
|
-
-- creating
|
484
|
+
-- creating a GameObject class X ( with a "has_trait :bounding_box, :scale => 0.80" )
|
485
|
+
1) trait gets merged into X, instance and class methods are added
|
486
|
+
2) GameObject.initialize_trait(:scale => 0.80)
|
487
|
+
-- creating an instance of X
|
485
488
|
1) GameObject#initialize(options)
|
486
489
|
2) GameObject#setup_trait(options)
|
487
490
|
-- each game iteration
|
@@ -503,6 +506,20 @@ Adds timer functionality to your game object
|
|
503
506
|
Adds accessors velocity_x, velocity_y, acceleration_x, acceleration_y, max_velocity to game object.
|
504
507
|
They modify x, y as you would expect. *speed / angle will come*
|
505
508
|
|
509
|
+
==== Trait "bounding_box"
|
510
|
+
Adds accessor 'bounding_box', which returns a Rect based on current image size,x,y,factor_x,factor_y,center_x,center_y
|
511
|
+
You can also scale the calculated rect with has_trait-options:
|
512
|
+
|
513
|
+
# This would return a rect slightly smaller then the image.
|
514
|
+
# Make player think he's better @ dodging bullets then he really is ;)
|
515
|
+
has_trait :bounding_box, :scale => 0.80
|
516
|
+
|
517
|
+
==== Trait "radius"
|
518
|
+
Adds accessor 'radius', which returns a Fixnum based on current image size,factor_x and factor_y
|
519
|
+
You can also scale the calculated radius with has_trait-options:
|
520
|
+
|
521
|
+
# This would return a radius slightly bigger then what initialize was calculated
|
522
|
+
has_trait :radius, :scale => 1.10
|
506
523
|
|
507
524
|
==== Trait "effect"
|
508
525
|
Adds accessors rotation_rate, fade_rate and scale_rate to game object.
|
@@ -651,3 +668,10 @@ As far as possible, use correct rubyfied english game_objects, not gameobjects.
|
|
651
668
|
* gem 'texplay' for some bonus Image-pixel operations, not needed otherwise
|
652
669
|
|
653
670
|
|
671
|
+
|
672
|
+
|
673
|
+
|
674
|
+
"If you program and want any longevity to your work, make a game.
|
675
|
+
All else recycles, but people rewrite architectures to keep games alive.", _why
|
676
|
+
|
677
|
+
|
data/chingu.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{chingu}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.6"
|
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-11-
|
9
|
+
s.date = %q{2009-11-21}
|
10
10
|
s.description = %q{OpenGL accelerated 2D game framework for Ruby.
|
11
11
|
Builds on the awesome Gosu (Ruby/C++) which provides all the core functionality.
|
12
12
|
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.}
|
13
13
|
s.email = ["ippa@rubylicio.us"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "benchmarks/README.txt"]
|
15
|
-
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/example12.rb", "examples/example13.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/game1.rb", "examples/high_score_list.yml", "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/bullet.png", "examples/media/bullet_hit.wav", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.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/edit.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.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/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
|
15
|
+
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/example12.rb", "examples/example13.rb", "examples/example14.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/game1.rb", "examples/high_score_list.yml", "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/bullet.png", "examples/media/bullet_hit.wav", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_extensions.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/edit.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.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/bounding_box.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/radius.rb", "lib/chingu/traits/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
|
16
16
|
s.homepage = %q{http://github.com/ippa/chingu/tree/master}
|
17
17
|
s.rdoc_options = ["--main", "README.rdoc"]
|
18
18
|
s.require_paths = ["lib"]
|
data/examples/example11.rb
CHANGED
@@ -15,20 +15,21 @@ class Game < Chingu::Window
|
|
15
15
|
@factor = 6
|
16
16
|
self.input = { :escape => :exit }
|
17
17
|
self.caption = "Chingu::Animation / retrofy example. Move with arrows!"
|
18
|
-
Droid.create(:x => $window.width
|
18
|
+
Droid.create(:x => $window.width/2, :y => $window.height/2)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
class Droid < Chingu::GameObject
|
23
|
-
|
23
|
+
has_traits :timer
|
24
24
|
|
25
25
|
def initialize(options = {})
|
26
26
|
super
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
#
|
29
|
+
# This shows up the shorten versio of input-maps, where each key calls a method of the very same name.
|
30
|
+
# Use this by giving an array of symbols to self.input
|
31
|
+
#
|
32
|
+
self.input = [:holding_left, :holding_right, :holding_up, :holding_down]
|
32
33
|
|
33
34
|
# Load the full animation from tile-file media/droid.bmp
|
34
35
|
@full_animation = Chingu::Animation.new(:file => "droid.bmp", :size => [11,16]).retrofy
|
@@ -49,23 +50,23 @@ class Droid < Chingu::GameObject
|
|
49
50
|
update
|
50
51
|
end
|
51
52
|
|
52
|
-
def
|
53
|
-
@x -=
|
53
|
+
def holding_left
|
54
|
+
@x -= 2
|
54
55
|
@animation = @animations[:left]
|
55
56
|
end
|
56
57
|
|
57
|
-
def
|
58
|
-
@x +=
|
58
|
+
def holding_right
|
59
|
+
@x += 2
|
59
60
|
@animation = @animations[:right]
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
@y -=
|
63
|
+
def holding_up
|
64
|
+
@y -= 2
|
64
65
|
@animation = @animations[:up]
|
65
66
|
end
|
66
67
|
|
67
|
-
def
|
68
|
-
@y +=
|
68
|
+
def holding_down
|
69
|
+
@y += 2
|
69
70
|
@animation = @animations[:down]
|
70
71
|
end
|
71
72
|
|
data/examples/example13.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname($0), "..", "lib", "chingu")
|
3
|
+
include Gosu
|
4
|
+
include Chingu
|
5
|
+
|
6
|
+
#
|
7
|
+
# Demonstrating Chingus HighScoreList-class
|
8
|
+
# I couldn't keep myself from spicying it up some though :P
|
9
|
+
#
|
10
|
+
class Game < Chingu::Window
|
11
|
+
def initialize
|
12
|
+
super(640,400)
|
13
|
+
self.input = {:esc => :exit, :space => :remote_high_score, :a => :add}
|
14
|
+
self.caption = "Example of Chingus HighScore class. Press Space to go to fetch high scores remotely!"
|
15
|
+
|
16
|
+
@title = PulsatingText.create("HIGH SCORES", :x => $window.width/2, :y => 50, :size => 70)
|
17
|
+
|
18
|
+
#
|
19
|
+
# Load a list from disk, defaults to "high_score_list.yml"
|
20
|
+
# Argument :size forces list to this size
|
21
|
+
#
|
22
|
+
@high_score_list = HighScoreList.load(:size => 10)
|
23
|
+
|
24
|
+
#
|
25
|
+
# Add some new high scores to the list. :name and :score are required but you can put whatever.
|
26
|
+
# They will mix with the old scores, automatic default sorting on :score
|
27
|
+
#
|
28
|
+
10.times do
|
29
|
+
data = {:name => "NEW", :score => rand(10000)}
|
30
|
+
|
31
|
+
position = @high_score_list.add(data)
|
32
|
+
if position
|
33
|
+
puts "#{data[:name]} - #{data[:score]} got position #{position}"
|
34
|
+
else
|
35
|
+
puts "#{data[:name]} - #{data[:score]} didn't make it"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
create_text
|
40
|
+
|
41
|
+
# @high_score_list.save_to_file # Uncomment to save list to disk
|
42
|
+
end
|
43
|
+
|
44
|
+
def remote_high_score
|
45
|
+
game_objects.destroy_all
|
46
|
+
|
47
|
+
@title = PulsatingText.create("REMOTE WEBSERVICE HIGH SCORES", :x => $window.width/2, :y => 50, :size => 30)
|
48
|
+
|
49
|
+
#
|
50
|
+
# :game_id is the unique ID the game has on www.gamercv.com
|
51
|
+
# :user is the login for that specific game (set by owner)
|
52
|
+
# :password is the password for that specific game (set by owner)
|
53
|
+
#
|
54
|
+
# To read a high score list only :game_id is required
|
55
|
+
# To write to a high score list :user and :password is required as well
|
56
|
+
#
|
57
|
+
@high_score_list = HighScoreList.load_remote(:game_id => 1, :user => "chingu", :password => "chingu", :size => 10)
|
58
|
+
create_text
|
59
|
+
end
|
60
|
+
|
61
|
+
def add
|
62
|
+
data = {:name => "NEW", :score => 1600}
|
63
|
+
position = @high_score_list.add(data)
|
64
|
+
puts "Got position: #{position.to_s}"
|
65
|
+
create_text
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_text
|
69
|
+
@score_texts ||= []
|
70
|
+
@score_texts.each { |text| text.destroy }
|
71
|
+
|
72
|
+
#
|
73
|
+
# Iterate through all high scores and create the visual represenation of it
|
74
|
+
#
|
75
|
+
@high_score_list.each_with_index do |high_score, index|
|
76
|
+
y = index * 25 + 100
|
77
|
+
@score_texts << Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
|
78
|
+
@score_texts << Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
|
79
|
+
end
|
80
|
+
|
81
|
+
5.times do
|
82
|
+
score = rand(20000)
|
83
|
+
puts "position for possible score #{score}: #{@high_score_list.position_by_score(score)}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# colorful pulsating text...
|
91
|
+
#
|
92
|
+
class PulsatingText < Text
|
93
|
+
has_traits :timer, :effect
|
94
|
+
@@red = Color.new(0xFFFF0000)
|
95
|
+
@@green = Color.new(0xFF00FF00)
|
96
|
+
@@blue = Color.new(0xFF0000FF)
|
97
|
+
|
98
|
+
def initialize(text, options = {})
|
99
|
+
super(text, options)
|
100
|
+
|
101
|
+
options = text if text.is_a? Hash
|
102
|
+
@pulse = options[:pulse] || false
|
103
|
+
self.rotation_center(:center_center)
|
104
|
+
every(20) { create_pulse } if @pulse == false
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_pulse
|
108
|
+
pulse = PulsatingText.create(@text, :x => @x, :y => @y, :height => @height, :pulse => true, :image => @image, :zorder => @zorder+1)
|
109
|
+
colors = [@@red, @@green, @@blue]
|
110
|
+
pulse.color = colors[rand(colors.size)].dup
|
111
|
+
pulse.mode = :additive
|
112
|
+
pulse.alpha -= 150
|
113
|
+
pulse.scale_rate = 0.002
|
114
|
+
pulse.fade_rate = -3 + rand(2)
|
115
|
+
pulse.rotation_rate = rand(2)==0 ? 0.05 : -0.05
|
116
|
+
end
|
117
|
+
|
118
|
+
def update
|
119
|
+
destroy if self.alpha == 0
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
Game.new.show
|
data/examples/example2.rb
CHANGED
@@ -60,13 +60,17 @@ class Play < Chingu::GameState
|
|
60
60
|
def initialize
|
61
61
|
super
|
62
62
|
@player = Player.create(:x => 200, :y => 200)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
|
64
|
+
#
|
65
|
+
# More advanced input-maps, showing of multiple keys leading to the same method
|
66
|
+
#
|
67
|
+
@player.input = { [:holding_a, :holding_left, :holding_pad_left] => :move_left,
|
68
|
+
[:holding_d, :holding_right, :holding_pad_right] => :move_right,
|
69
|
+
[:holding_w, :holding_up, :holding_pad_up] => :move_up,
|
70
|
+
[:holding_s, :holding_down, :holding_pad_down] => :move_down,
|
71
|
+
[:space, :return, :pad_button_2] => :fire
|
68
72
|
}
|
69
|
-
self.input = { :f1 => :debug, :escape => :exit }
|
73
|
+
self.input = { :f1 => :debug, [:q, :escape] => :exit }
|
70
74
|
end
|
71
75
|
|
72
76
|
def debug
|
data/examples/example9.rb
CHANGED
@@ -18,14 +18,7 @@ class Game < Chingu::Window
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class FireCube < Chingu::GameObject
|
21
|
-
|
22
|
-
has_trait :collision_detection
|
23
|
-
#
|
24
|
-
# TODO:
|
25
|
-
# has_trait :collision_detection, :type => :bounding_box
|
26
|
-
# has_trait :collision_detection, :type => :radius
|
27
|
-
#
|
28
|
-
|
21
|
+
has_traits :velocity, :collision_detection
|
29
22
|
attr_accessor :color, :radius
|
30
23
|
|
31
24
|
def initialize(options)
|
@@ -36,7 +29,7 @@ class FireCube < Chingu::GameObject
|
|
36
29
|
@velocity_x = options[:velocity_x] || 1 + rand(2)
|
37
30
|
@velocity_y = options[:velocity_y] || 1 + rand(2)
|
38
31
|
|
39
|
-
@
|
32
|
+
@box = Rect.new([@x, @y, 10, 10])
|
40
33
|
@radius = 6
|
41
34
|
|
42
35
|
@blue = Color.new(255,100,255,255)
|
@@ -45,17 +38,14 @@ class FireCube < Chingu::GameObject
|
|
45
38
|
end
|
46
39
|
|
47
40
|
def draw
|
48
|
-
$window.fill_rect(@
|
41
|
+
$window.fill_rect(@box, @color)
|
49
42
|
end
|
50
43
|
|
51
44
|
def update
|
45
|
+
@box.x, @box.y = @x, @y
|
52
46
|
@color = @blue
|
53
47
|
end
|
54
48
|
|
55
|
-
def collides?(object2)
|
56
|
-
radius_collision?(object2)
|
57
|
-
end
|
58
|
-
|
59
49
|
def die!
|
60
50
|
@color = @red
|
61
51
|
end
|
data/examples/game1.rb
CHANGED
@@ -9,7 +9,6 @@ require 'rubygems'
|
|
9
9
|
require File.join(File.dirname($0), "..", "lib", "chingu")
|
10
10
|
|
11
11
|
require 'texplay' # adds Image#get_pixel
|
12
|
-
#require 'devil/gosu' # adds Gosu::Window#screenshot and better file support
|
13
12
|
require 'opengl' # adds raw gl stuff so Image#retrofy works (in some setups this seems to be 'gl')
|
14
13
|
|
15
14
|
include Gosu
|
@@ -26,59 +25,22 @@ class Game < Chingu::Window
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
#
|
30
|
-
# GAME STATE: GAME OVER
|
31
|
-
#
|
32
|
-
class GameOver < Chingu::GameState
|
33
|
-
def setup
|
34
|
-
@text = Text.create(:text => "GAME OVER (ESC to quit, RETURN to try again!)", :size => 40, :x => 30, :y => 100)
|
35
|
-
self.input = { :esc => :exit, :return => :try_again}
|
36
|
-
@layover = Color.new(0x99000000)
|
37
|
-
end
|
38
|
-
|
39
|
-
def draw
|
40
|
-
super
|
41
|
-
previous_game_state.draw
|
42
|
-
fill(@layover)
|
43
|
-
end
|
44
|
-
|
45
|
-
def try_again
|
46
|
-
pop_game_state # pop back to our playing game state
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
#
|
51
|
-
# GAME STATE: GAME OVER
|
52
|
-
#
|
53
|
-
class Done < Chingu::GameState
|
54
|
-
def initialize(options)
|
55
|
-
@score = options[:score]
|
56
|
-
end
|
57
|
-
|
58
|
-
def setup
|
59
|
-
@text = Text.create(:text => "You made it! Score #{@score} (ESC to quit, RETURN to try again!)", :size => 40, :x => 30, :y => 100)
|
60
|
-
self.input = { :esc => :exit, :return => :try_again}
|
61
|
-
end
|
62
|
-
|
63
|
-
def try_again
|
64
|
-
pop_game_state # pop back to our playing game state
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
28
|
|
69
29
|
#
|
70
30
|
# GAME STATE: LEVEL
|
71
31
|
#
|
72
32
|
class Level < Chingu::GameState
|
33
|
+
has_trait :timer
|
34
|
+
|
73
35
|
def initialize(options = {})
|
74
36
|
super
|
75
37
|
|
76
38
|
@parallax = Parallax.create
|
77
|
-
ParallaxLayer.has_trait :retrofy
|
39
|
+
#ParallaxLayer.has_trait :retrofy
|
78
40
|
#@parallax << ParallaxLayer.new(:image => Image["city3.png"].retrofy, :center => 0, :damping => 4, :factor => $window.factor)
|
79
41
|
@parallax << ParallaxLayer.new(:image => Image["city2.png"].retrofy, :center => 0, :damping => 2, :factor => $window.factor)
|
80
42
|
@parallax << ParallaxLayer.new(:image => Image["city1.png"].retrofy, :center => 0, :damping => 1, :factor => $window.factor)
|
81
|
-
@player = Player.create(:x => 10, :y =>
|
43
|
+
@player = Player.create(:x => 10, :y => 10)
|
82
44
|
|
83
45
|
@bg1 = Color.new(0xFFCE28FF)
|
84
46
|
@bg2 = Color.new(0xFF013E87)
|
@@ -88,7 +50,7 @@ class Level < Chingu::GameState
|
|
88
50
|
# This is called each time this GameState is switched/pushed/poped to.
|
89
51
|
#
|
90
52
|
def setup
|
91
|
-
# Remove all lingering
|
53
|
+
# Remove all lingering game objects
|
92
54
|
Enemy.destroy_all
|
93
55
|
Bullet.destroy_all
|
94
56
|
|
@@ -107,7 +69,11 @@ class Level < Chingu::GameState
|
|
107
69
|
#
|
108
70
|
def solid_pixel_at?(x, y)
|
109
71
|
begin
|
110
|
-
@parallax.layers.last.get_pixel(x, y)
|
72
|
+
#pixel = @parallax.layers.last.get_pixel(x/$window.factor, y/$window.factor)
|
73
|
+
#return false if pixel.nil?
|
74
|
+
#return
|
75
|
+
|
76
|
+
@parallax.layers.last.get_pixel(x/$window.factor, y/$window.factor)[3] != 0
|
111
77
|
rescue
|
112
78
|
puts "Error in get_pixel(#{x}, #{y})"
|
113
79
|
end
|
@@ -145,13 +111,13 @@ class Level < Chingu::GameState
|
|
145
111
|
@timer = @timer * 0.9999
|
146
112
|
@total_ticks += 1
|
147
113
|
if @total_ticks > @timer
|
148
|
-
Enemy.create(:x => $window.width
|
114
|
+
Enemy.create(:x => $window.width, :y => rand(300))
|
149
115
|
@total_ticks = 0
|
150
116
|
end
|
151
117
|
|
152
118
|
#push_game_state(Done.new(:score => @player.score)) if @game_steps == 1
|
153
119
|
|
154
|
-
$window.caption = "City Battle! Score: #{@player.score}
|
120
|
+
$window.caption = "City Battle! Player x/y: #{@player.x}/#{@player.y} - Score: #{@player.score} - FPS: #{$window.fps} - game objects: #{game_objects.size}"
|
155
121
|
end
|
156
122
|
|
157
123
|
def draw
|
@@ -164,7 +130,9 @@ end
|
|
164
130
|
# OUR PLAYER
|
165
131
|
#
|
166
132
|
class Player < GameObject
|
167
|
-
|
133
|
+
has_traits :velocity, :collision_detection, :timer
|
134
|
+
has_trait :radius, :scale => 0.50, :debug => true
|
135
|
+
|
168
136
|
attr_accessor :score
|
169
137
|
|
170
138
|
def initialize(options = {})
|
@@ -179,40 +147,39 @@ class Player < GameObject
|
|
179
147
|
:holding_down => :down,
|
180
148
|
:holding_space => :fire }
|
181
149
|
|
182
|
-
@max_velocity =
|
183
|
-
@radius = 10
|
150
|
+
@max_velocity = 2
|
184
151
|
@score = 0
|
185
152
|
@cooling_down = false
|
186
153
|
end
|
187
154
|
|
188
155
|
def up
|
189
|
-
|
156
|
+
self.velocity_y = -@max_velocity
|
190
157
|
end
|
191
158
|
def down
|
192
|
-
|
159
|
+
self.velocity_y = @max_velocity
|
193
160
|
end
|
194
161
|
def right
|
195
|
-
|
162
|
+
self.velocity_x = @max_velocity
|
196
163
|
end
|
197
164
|
def left
|
198
|
-
|
165
|
+
self.velocity_x = -@max_velocity
|
199
166
|
end
|
200
167
|
|
201
168
|
def fire
|
202
169
|
return if @cooling_down
|
203
170
|
@cooling_down = true
|
204
|
-
after(100) { @cooling_down = false}
|
171
|
+
after(100) { @cooling_down = false }
|
205
172
|
|
206
173
|
Bullet.create(:x => self.x, :y => self.y)
|
207
174
|
Sound["laser.wav"].play(0.1)
|
208
175
|
end
|
209
176
|
|
210
177
|
def update
|
211
|
-
|
212
|
-
|
178
|
+
self.velocity_y *= 0.6
|
179
|
+
self.velocity_x *= 0.6
|
213
180
|
|
214
|
-
@x = @last_x if @x < 0 || @x > $window.width
|
215
|
-
@y = @last_y if @y < 0 || @y > $window.height
|
181
|
+
@x = @last_x if @x < 0 || @x > $window.width#/$window.factor
|
182
|
+
@y = @last_y if @y < 0 || @y > $window.height#/$window.factor
|
216
183
|
@last_x, @last_y = @x, @y
|
217
184
|
end
|
218
185
|
|
@@ -222,14 +189,14 @@ end
|
|
222
189
|
# OUR PLAYERS BULLETS
|
223
190
|
#
|
224
191
|
class Bullet < GameObject
|
225
|
-
|
226
|
-
attr_reader :status
|
192
|
+
has_traits :timer, :collision_detection, :velocity
|
193
|
+
attr_reader :status, :radius
|
227
194
|
|
228
195
|
def initialize(options)
|
229
196
|
super
|
230
197
|
@image = Image["bullet.png"].retrofy
|
231
198
|
self.factor = $window.factor
|
232
|
-
|
199
|
+
self.velocity_x = 10
|
233
200
|
@status = :default
|
234
201
|
@radius = 3
|
235
202
|
end
|
@@ -241,10 +208,10 @@ class Bullet < GameObject
|
|
241
208
|
during(50) { @factor_x += 1; @factor_y += 1; @x -= 1; }.then { self.destroy }
|
242
209
|
end
|
243
210
|
|
244
|
-
def update
|
245
|
-
return if @status == :dying
|
246
|
-
|
247
|
-
end
|
211
|
+
#def update
|
212
|
+
#return if @status == :dying
|
213
|
+
#@x += self.velocity_x
|
214
|
+
#end
|
248
215
|
end
|
249
216
|
|
250
217
|
#
|
@@ -254,12 +221,12 @@ class EnemyBullet < Bullet
|
|
254
221
|
def initialize(options)
|
255
222
|
super
|
256
223
|
@image = Image["enemy_bullet.png"].retrofy
|
257
|
-
|
224
|
+
self.velocity_x = -3
|
258
225
|
end
|
259
226
|
end
|
260
227
|
|
261
228
|
class Explosion < GameObject
|
262
|
-
|
229
|
+
has_traits :timer
|
263
230
|
|
264
231
|
def initialize(options)
|
265
232
|
super
|
@@ -271,8 +238,7 @@ class Explosion < GameObject
|
|
271
238
|
|
272
239
|
@image = @@image.dup if @image.nil?
|
273
240
|
|
274
|
-
|
275
|
-
self.rotation_center(:center)
|
241
|
+
self.rotation_center = :center
|
276
242
|
self.factor = options[:factor] ? options[:factor] : $window.factor
|
277
243
|
during(100) { self.alpha -= 30}.then { destroy }
|
278
244
|
end
|
@@ -287,7 +253,7 @@ class Explosion < GameObject
|
|
287
253
|
end
|
288
254
|
|
289
255
|
class Shrapnel < GameObject
|
290
|
-
|
256
|
+
has_traits :timer, :effect, :velocity
|
291
257
|
|
292
258
|
def initialize(options)
|
293
259
|
super
|
@@ -296,8 +262,7 @@ class Shrapnel < GameObject
|
|
296
262
|
self.velocity_x = 4 - rand(8)
|
297
263
|
self.velocity_y = 4 - rand(10)
|
298
264
|
self.acceleration_y = 0.2 # gravity = downards acceleration
|
299
|
-
|
300
|
-
rotation_center(:center)
|
265
|
+
self.rotation_center = :center
|
301
266
|
self.factor = $window.factor
|
302
267
|
@status = :default
|
303
268
|
end
|
@@ -325,15 +290,16 @@ end
|
|
325
290
|
# OUR ENEMY SAUCER
|
326
291
|
#
|
327
292
|
class Enemy < GameObject
|
328
|
-
|
293
|
+
has_traits :collision_detection, :timer
|
294
|
+
attr_reader :radius
|
329
295
|
|
330
296
|
def initialize(options)
|
331
297
|
super
|
332
298
|
@velocity = options[:velocity] || 2
|
333
299
|
@health = options[:health] || 100
|
334
300
|
|
335
|
-
@anim = Animation.new(:file => "media/saucer.png", :size => [32,13], :delay => 100)
|
336
|
-
@anim.retrofy
|
301
|
+
@anim = Animation.new(:file => "media/saucer.png", :size => [32,13], :delay => 100).retrofy
|
302
|
+
# @anim.retrofy
|
337
303
|
@image = @anim.first
|
338
304
|
|
339
305
|
self.factor = $window.factor
|
@@ -403,4 +369,49 @@ class Enemy < GameObject
|
|
403
369
|
end
|
404
370
|
end
|
405
371
|
|
406
|
-
|
372
|
+
|
373
|
+
#
|
374
|
+
# GAME STATE: GAME OVER
|
375
|
+
#
|
376
|
+
class GameOver < Chingu::GameState
|
377
|
+
def setup
|
378
|
+
@text = Text.create("GAME OVER (ESC to quit, RETURN to try again!)", :size => 40, :x => 30, :y => 100)
|
379
|
+
self.input = { :esc => :exit, :return => :try_again }
|
380
|
+
@layover = Color.new(0x99000000)
|
381
|
+
end
|
382
|
+
|
383
|
+
def draw
|
384
|
+
super
|
385
|
+
previous_game_state.draw
|
386
|
+
fill(@layover)
|
387
|
+
end
|
388
|
+
|
389
|
+
def try_again
|
390
|
+
pop_game_state # pop back to our playing game state
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
#
|
395
|
+
# GAME STATE: GAME OVER
|
396
|
+
#
|
397
|
+
class Done < Chingu::GameState
|
398
|
+
def initialize(options)
|
399
|
+
@score = options[:score]
|
400
|
+
end
|
401
|
+
|
402
|
+
def setup
|
403
|
+
@text = Text.create("You made it! Score #{@score} (ESC to quit, RETURN to try again!)", :size => 40, :x => 30, :y => 100)
|
404
|
+
self.input = { :esc => :exit, :return => :try_again}
|
405
|
+
end
|
406
|
+
|
407
|
+
def try_again
|
408
|
+
pop_game_state # pop back to our playing game state
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
|
413
|
+
Game.new.show
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
|