chingu 0.5.9.4 → 0.6
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.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/lib/chingu.rb
CHANGED
@@ -8,22 +8,38 @@ module Chingu
|
|
8
8
|
class BasicGameObject
|
9
9
|
attr_reader :options, :paused, :visible
|
10
10
|
attr_accessor :parent
|
11
|
-
|
11
|
+
|
12
|
+
def self.trait_options; @trait_options; end
|
13
|
+
def trait_options; self.class.trait_options; end
|
14
|
+
|
12
15
|
#
|
13
16
|
# Adds a trait or traits to a certain game class
|
14
17
|
# Executes a standard ruby "include" the specified module
|
15
18
|
#
|
16
|
-
def self.has_trait(
|
17
|
-
|
19
|
+
def self.has_trait(trait, options = {})
|
20
|
+
@trait_options ||= Hash.new
|
21
|
+
if trait.is_a?(::Symbol) || trait.is_a?(::String)
|
22
|
+
begin
|
23
|
+
# Convert user-given symbol (eg. :timer) to a Module (eg. Chingu::Traits::Timer)
|
24
|
+
mod = Chingu::Traits.const_get(Chingu::Inflector.camelize(trait))
|
25
|
+
|
26
|
+
# Include the module, which will add the containing methods as instance methods
|
27
|
+
include mod
|
28
|
+
|
29
|
+
# Add possible classmethods defined in sub-module ClassMethods (eg: Chingu::Traits::Timer::ClassMethods)
|
30
|
+
mod2 = mod.const_get("ClassMethods")
|
31
|
+
extend mod2
|
32
|
+
|
33
|
+
# If the newly included trait has a initialize_trait method...
|
34
|
+
# ... call it with the options provided with the has_trait-call
|
35
|
+
initialize_trait(options) if mod2.method_defined?(:initialize_trait)
|
36
|
+
rescue
|
37
|
+
end
|
38
|
+
end
|
18
39
|
end
|
19
40
|
|
20
|
-
# See #has_trait
|
21
41
|
def self.has_traits(*traits)
|
22
|
-
Array(traits).each
|
23
|
-
if trait.is_a?(::Symbol) || trait.is_a?(::String)
|
24
|
-
include Chingu::Traits.const_get(Chingu::Inflector.camelize(trait))
|
25
|
-
end
|
26
|
-
end
|
42
|
+
Array(traits).each { |trait| has_trait trait }
|
27
43
|
end
|
28
44
|
|
29
45
|
#
|
@@ -122,20 +138,15 @@ module Chingu
|
|
122
138
|
@visible == true
|
123
139
|
end
|
124
140
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
def
|
129
|
-
|
130
|
-
|
131
|
-
def draw_trait
|
132
|
-
end
|
133
|
-
|
134
|
-
def update
|
135
|
-
end
|
136
|
-
|
137
|
-
def draw
|
138
|
-
end
|
141
|
+
#
|
142
|
+
# Empty placeholders to be overridden
|
143
|
+
#
|
144
|
+
def self.initialize_trait(options); end
|
145
|
+
def setup_trait(options); end
|
146
|
+
def update_trait; end
|
147
|
+
def draw_trait; end
|
148
|
+
def update; end
|
149
|
+
def draw; end
|
139
150
|
|
140
151
|
|
141
152
|
#
|
data/lib/chingu/game_state.rb
CHANGED
@@ -58,21 +58,37 @@ module Chingu
|
|
58
58
|
attr_reader :options
|
59
59
|
attr_accessor :game_state_manager, :game_objects
|
60
60
|
|
61
|
+
def self.trait_options; @trait_options; end
|
62
|
+
def trait_options; self.class.trait_options; end
|
63
|
+
|
61
64
|
#
|
62
65
|
# Adds a trait or traits to a certain game class
|
63
66
|
# Executes a standard ruby "include" the specified module
|
64
67
|
#
|
65
|
-
def self.has_trait(
|
66
|
-
|
68
|
+
def self.has_trait(trait, options = {})
|
69
|
+
@trait_options ||= Hash.new
|
70
|
+
if trait.is_a?(::Symbol) || trait.is_a?(::String)
|
71
|
+
begin
|
72
|
+
# Convert user-given symbol (eg. :timer) to a Module (eg. Chingu::Traits::Timer)
|
73
|
+
mod = Chingu::Traits.const_get(Chingu::Inflector.camelize(trait))
|
74
|
+
|
75
|
+
# Include the module, which will add the containing methods as instance methods
|
76
|
+
include mod
|
77
|
+
|
78
|
+
# Add possible classmethods defined in sub-module ClassMethods (eg: Chingu::Traits::Timer::ClassMethods)
|
79
|
+
mod2 = mod.const_get("ClassMethods")
|
80
|
+
extend mod2
|
81
|
+
|
82
|
+
# If the newly included trait has a initialize_trait method...
|
83
|
+
# ... call it with the options provided with the has_trait-call
|
84
|
+
initialize_trait(options) if mod2.method_defined?(:initialize_trait)
|
85
|
+
rescue
|
86
|
+
end
|
87
|
+
end
|
67
88
|
end
|
68
89
|
|
69
|
-
# See #has_trait
|
70
90
|
def self.has_traits(*traits)
|
71
|
-
Array(traits).each
|
72
|
-
if trait.is_a?(::Symbol) || trait.is_a?(::String)
|
73
|
-
include Chingu::Traits.const_get(Chingu::Inflector.camelize(trait))
|
74
|
-
end
|
75
|
-
end
|
91
|
+
Array(traits).each { |trait| has_trait trait }
|
76
92
|
end
|
77
93
|
|
78
94
|
|
data/lib/chingu/helpers/gfx.rb
CHANGED
@@ -98,7 +98,7 @@ module Chingu
|
|
98
98
|
end
|
99
99
|
|
100
100
|
#
|
101
|
-
# Draws
|
101
|
+
# Draws an unfilled rect in given color
|
102
102
|
#
|
103
103
|
def draw_rect(rect, color, zorder)
|
104
104
|
$window.draw_line(rect.x, rect.y, color, rect.right, rect.y, color, zorder)
|
@@ -107,6 +107,18 @@ module Chingu
|
|
107
107
|
$window.draw_line(rect.x, rect.bottom, color, rect.x, rect.y, color, zorder)
|
108
108
|
end
|
109
109
|
|
110
|
+
|
111
|
+
#
|
112
|
+
# Draws an unfilled circle, thanks shawn24!
|
113
|
+
#
|
114
|
+
CIRCLE_STEP = 10
|
115
|
+
def draw_circle(cx,cy,r,color)
|
116
|
+
0.step(360, CIRCLE_STEP) do |a1|
|
117
|
+
a2 = a1 + CIRCLE_STEP
|
118
|
+
$window.draw_line cx + offset_x(a1, r), cy + offset_y(a1, r), color, cx + offset_x(a2, r), cy + offset_y(a2, r), color, 9999
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
110
122
|
#
|
111
123
|
# Fills a given Rect 'rect' with Color 'color', drawing with zorder 'zorder'
|
112
124
|
#
|
@@ -29,11 +29,48 @@ module Chingu
|
|
29
29
|
# 1) Initialized an inputmap
|
30
30
|
# 2) notifies the parent (could be main Window or a GameState) that the object wants input
|
31
31
|
#
|
32
|
-
# In Chingu this is mixed into Window, GameState and GameObject
|
32
|
+
# In Chingu this is mixed into Window, GameState and GameObject.
|
33
|
+
#
|
34
|
+
# You can specify input in 3 different natural formats, the bellow 3 lines does the same thing:
|
35
|
+
#
|
36
|
+
# The normal way, this makes left_arrow key call method "left", and the same thing for right.
|
37
|
+
# self.input = {:left => :left, :right => :right}
|
38
|
+
#
|
39
|
+
# The shortened way, does exaclty as the above.
|
40
|
+
# self.input = [:left, :right]
|
41
|
+
#
|
42
|
+
# The multi-way, adds :a as trigger for method left, and :d as trigger for method :right
|
43
|
+
# self.input = {[:a, :left] => :left, [:right, :d] => :right}
|
44
|
+
#
|
33
45
|
#
|
34
46
|
module InputClient
|
35
47
|
def input=(input_map)
|
36
|
-
@input
|
48
|
+
@input ||= Hash.new
|
49
|
+
#@input = input_map
|
50
|
+
|
51
|
+
if input_map.is_a? Array
|
52
|
+
#
|
53
|
+
# Un-nest input_map [:left, :right, :space]
|
54
|
+
# Into: { :left => :left, :right => :right, :space => :space}
|
55
|
+
#
|
56
|
+
input_map.each do |symbol|
|
57
|
+
@input[symbol] = symbol
|
58
|
+
end
|
59
|
+
elsif input_map.is_a? Hash
|
60
|
+
#
|
61
|
+
# Un-nest input: { [:pad_left, :arrow_left, :a] => :move_left }
|
62
|
+
# Into: { :pad_left => :move_left, :arrow_left => :move_left, :a => :move_left }
|
63
|
+
#
|
64
|
+
input_map.each_pair do |possible_array, action|
|
65
|
+
if possible_array.is_a? Array
|
66
|
+
possible_array.each do |symbol|
|
67
|
+
@input[symbol] = action
|
68
|
+
end
|
69
|
+
elsif possible_array.is_a? Symbol
|
70
|
+
@input[possible_array] = action
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
37
74
|
|
38
75
|
if @parent
|
39
76
|
if (@input == nil || @input == {})
|
@@ -74,10 +74,16 @@ module Chingu
|
|
74
74
|
# They're also available (hey, hashlookups are speedy) with "middle" instead of "center" since
|
75
75
|
# those 2 words basicly have the same meaning and are both understandable.
|
76
76
|
#
|
77
|
-
def rotation_center(alignment)
|
77
|
+
def rotation_center(alignment = nil)
|
78
|
+
#return @rotation_center unless alignment
|
79
|
+
#@rotation_center = alignment
|
78
80
|
@center_x, @center_y = @@rotation_centers[alignment.to_sym]
|
79
81
|
end
|
80
82
|
|
83
|
+
def rotation_center=(alignment)
|
84
|
+
rotation_center(alignment)
|
85
|
+
end
|
86
|
+
|
81
87
|
end
|
82
88
|
end
|
83
89
|
end
|
data/lib/chingu/input.rb
CHANGED
@@ -20,13 +20,13 @@
|
|
20
20
|
#++
|
21
21
|
|
22
22
|
module Chingu
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
module Input
|
24
|
+
include Gosu::Button
|
25
|
+
|
26
26
|
#
|
27
27
|
# Ruby symbols describing http://www.libgosu.org/rdoc/classes/Gosu.html
|
28
28
|
#
|
29
|
-
|
29
|
+
CONSTANT_TO_SYMBOL = {
|
30
30
|
Kb0 => [:zero],
|
31
31
|
Kb1 => [:one],
|
32
32
|
Kb2 => [:two],
|
@@ -75,11 +75,11 @@ module Chingu
|
|
75
75
|
MsWheelDown => [:mouse_wheel_down, :wheel_down],
|
76
76
|
MsWheelUp => [:mouse_wheel_up, :wheel_up],
|
77
77
|
|
78
|
-
GpDown
|
79
|
-
GpLeft
|
80
|
-
GpRight
|
78
|
+
GpDown => [:gamepad_down, :gp_down, :pad_down],
|
79
|
+
GpLeft => [:gamepad_left, :gp_left, :pad_left],
|
80
|
+
GpRight => [:gamepad_right, :gp_right, :pad_right],
|
81
81
|
GpUp => [:gamepad_up, :gp_up, :pad_up]
|
82
|
-
|
82
|
+
}
|
83
83
|
|
84
84
|
# Letters, A-Z
|
85
85
|
("A".."Z").each do |letter|
|
@@ -99,11 +99,16 @@ module Chingu
|
|
99
99
|
#F-keys, F1-F12
|
100
100
|
(1..12).each do |number|
|
101
101
|
CONSTANT_TO_SYMBOL[eval("KbF#{number.to_s}")] = ["f#{number.to_s}".to_sym]
|
102
|
+
CONSTANT_TO_SYMBOL[eval("KbF#{number.to_s}")] = ["F#{number.to_s}".to_sym]
|
102
103
|
end
|
103
104
|
|
104
105
|
# Gamepad-buttons 0-15
|
105
106
|
(0..15).each do |number|
|
106
107
|
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["gamepad_button_#{number.to_s}"]
|
108
|
+
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["gamepad_#{number.to_s}"]
|
109
|
+
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["pad_button_#{number.to_s}"]
|
110
|
+
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["pad_#{number.to_s}"]
|
111
|
+
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["gp_#{number.to_s}"]
|
107
112
|
end
|
108
113
|
|
109
114
|
#
|
@@ -117,5 +122,5 @@ module Chingu
|
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
120
|
-
|
125
|
+
end
|
121
126
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# Chingu -- OpenGL accelerated 2D game framework for Ruby
|
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
|
+
module Chingu
|
23
|
+
module Traits
|
24
|
+
#
|
25
|
+
# Providing a bounding_box-method which generates a AABB on the fly from:
|
26
|
+
# x, y, factor_x, factor_y and rotation_center
|
27
|
+
#
|
28
|
+
module BoundingBox
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
def initialize_trait(options = {})
|
32
|
+
## puts "bounding_box initialize_trait #{options}"
|
33
|
+
@trait_options[:bounding_box] = options
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def bounding_box
|
38
|
+
width = self.image.width * self.factor_x.abs
|
39
|
+
height = self.image.height * self.factor_y.abs
|
40
|
+
|
41
|
+
if trait_options[:bounding_box][:scale]
|
42
|
+
width = width * trait_options[:bounding_box][:scale]
|
43
|
+
height = height * trait_options[:bounding_box][:scale]
|
44
|
+
end
|
45
|
+
|
46
|
+
x = self.x - (width * self.center_x.abs)
|
47
|
+
y = self.y - (height * self.center_y.abs)
|
48
|
+
|
49
|
+
return Rect.new(x, y, width, height)
|
50
|
+
end
|
51
|
+
alias :bb :bounding_box
|
52
|
+
|
53
|
+
def draw_trait
|
54
|
+
if trait_options[:bounding_box][:debug]
|
55
|
+
$window.draw_rect(self.bounding_box, Chingu::DEBUG_COLOR, Chingu::DEBUG_ZORDER)
|
56
|
+
end
|
57
|
+
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -28,33 +28,16 @@ module Chingu
|
|
28
28
|
#
|
29
29
|
# SEE: http://www.shmup-dev.com/forum/index.php?board=65.0
|
30
30
|
#
|
31
|
-
# Makes use of
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# @detect_collisions - [true|false], should object be checked for collisions with Object.each_collision
|
31
|
+
# Makes use of 2 attributes
|
32
|
+
# bounding_box - a Rect-instance, uses in bounding_box collisions
|
33
|
+
# radius - a number
|
35
34
|
#
|
36
35
|
module CollisionDetection
|
37
|
-
attr_accessor :bounding_box, :radius
|
38
|
-
## attr_accessor :detect_collisions # slowed down example9 with 3 fps
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
# Automaticly try to set a bounding_box and radius. Don't overwrite if they already exists.
|
46
|
-
#
|
47
|
-
def setup_trait(options)
|
48
|
-
if @x and @y and @image
|
49
|
-
@bounding_box ||= Rect.new(@x, @y, @image.width, @image.height)
|
50
|
-
end
|
51
|
-
|
52
|
-
if @image
|
53
|
-
@radius ||= (@image.height + @image.width) / 2 * 0.80
|
37
|
+
module ClassMethods
|
38
|
+
def initialize_trait(options = {})
|
39
|
+
@trait_options[:collision_detection] = options
|
54
40
|
end
|
55
|
-
|
56
|
-
## @detect_collisions = true
|
57
|
-
super
|
58
41
|
end
|
59
42
|
|
60
43
|
#
|
@@ -83,18 +66,6 @@ module Chingu
|
|
83
66
|
distance(self.x, self.y, object2.x, object2.y) < self.radius + object2.radius
|
84
67
|
end
|
85
68
|
|
86
|
-
#
|
87
|
-
# Have bounding box follow game objects x/y
|
88
|
-
#
|
89
|
-
def update_trait
|
90
|
-
if defined?(@bounding_box) && @bounding_box.is_a?(Rect)
|
91
|
-
@bounding_box.x = self.x
|
92
|
-
@bounding_box.y = self.y
|
93
|
-
end
|
94
|
-
|
95
|
-
super
|
96
|
-
end
|
97
|
-
|
98
69
|
#
|
99
70
|
# Collides self with all objects of given classes
|
100
71
|
# Yields self and the objects it collides with
|
@@ -114,12 +85,11 @@ module Chingu
|
|
114
85
|
def each_radius_collision(klasses = [])
|
115
86
|
Array(klasses).each do |klass|
|
116
87
|
klass.all.each do |object|
|
117
|
-
yield(self, object) if distance(
|
88
|
+
yield(self, object) if distance(self.x, self.y, object.x, object.y) < self.radius + object.radius
|
118
89
|
end
|
119
90
|
end
|
120
91
|
end
|
121
92
|
|
122
|
-
|
123
93
|
#
|
124
94
|
# Explicit bounding_box-collision
|
125
95
|
# Works like each_collision but with inline-code for speedups
|
@@ -127,14 +97,13 @@ module Chingu
|
|
127
97
|
def each_bounding_box_collision(klasses = [])
|
128
98
|
Array(klasses).each do |klass|
|
129
99
|
klass.all.each do |object|
|
130
|
-
yield(self, object) if
|
100
|
+
yield(self, object) if self.bounding_box.collide_rect?(object.bounding_box)
|
131
101
|
end
|
132
102
|
end
|
133
103
|
end
|
134
104
|
|
135
105
|
|
136
106
|
module ClassMethods
|
137
|
-
|
138
107
|
#
|
139
108
|
# Works like each_collision but with inline-code for speedups
|
140
109
|
#
|