ippa-chingu 0.4.8 → 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -0
- data/README.rdoc +43 -23
- data/chingu.gemspec +4 -4
- data/examples/example1.rb +2 -0
- data/examples/example2.rb +63 -33
- data/examples/example4.rb +16 -3
- data/examples/example5.rb +3 -3
- data/examples/example6.rb +1 -40
- data/examples/example7.rb +9 -8
- data/examples/example8.rb +109 -0
- data/examples/example9.rb +83 -0
- data/lib/chingu.rb +17 -2
- data/lib/chingu/actor.rb +15 -0
- data/lib/chingu/animation.rb +27 -2
- data/lib/chingu/basic_game_object.rb +140 -0
- data/lib/chingu/core_extensions.rb +15 -5
- data/lib/chingu/effects.rb +1 -1
- data/lib/chingu/fpscounter.rb +0 -1
- data/lib/chingu/game_object.rb +85 -155
- data/lib/chingu/game_state.rb +4 -3
- data/lib/chingu/game_state_manager.rb +3 -4
- data/lib/chingu/game_states/debug.rb +43 -0
- data/lib/chingu/game_states/fade_to.rb +2 -2
- data/lib/chingu/helpers.rb +2 -0
- data/lib/chingu/parallax.rb +2 -2
- data/lib/chingu/particle.rb +5 -4
- data/lib/chingu/traits/collision_detection.rb +33 -0
- data/lib/chingu/traits/deprecated_module_visual.rb +108 -0
- data/lib/chingu/traits/deprecated_visual.rb +100 -0
- data/lib/chingu/traits/effect.rb +80 -0
- data/lib/chingu/traits/input.rb +15 -0
- data/lib/chingu/traits/velocity.rb +59 -0
- data/lib/chingu/window.rb +18 -3
- metadata +16 -4
data/lib/chingu/parallax.rb
CHANGED
@@ -30,9 +30,9 @@ module Chingu
|
|
30
30
|
end
|
31
31
|
|
32
32
|
#
|
33
|
-
# TODO: make use of
|
33
|
+
# TODO: make use of $window.milliseconds_since_last_update here!
|
34
34
|
#
|
35
|
-
def update
|
35
|
+
def update
|
36
36
|
@backgrounds.each do |background|
|
37
37
|
background.x = -@x / background.damping
|
38
38
|
background.y = @y / background.damping
|
data/lib/chingu/particle.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
#
|
2
2
|
# Our basic particle class
|
3
3
|
#
|
4
|
-
include Chingu
|
5
4
|
module Chingu
|
6
|
-
class Particle < Chingu::GameObject
|
5
|
+
class Particle < Chingu::GameObject
|
6
|
+
add_component :effect
|
7
|
+
|
7
8
|
def initialize(options)
|
8
9
|
super({:mode => :additive}.merge(options))
|
9
10
|
@rotation = options[:rotation] || 0
|
10
11
|
@zoom = options[:zoom] || 0
|
11
|
-
@fade = options[:fade] || 0
|
12
|
+
@fade = options[:fade] || 0
|
12
13
|
@animation = options[:animation] || nil
|
13
14
|
end
|
14
15
|
|
15
|
-
def update
|
16
|
+
def update
|
16
17
|
self.image = @animation.next! if @animation
|
17
18
|
self.rotate(@rotation)
|
18
19
|
self.zoom(@zoom)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Components
|
3
|
+
#
|
4
|
+
# TODO: everything. convert to class?
|
5
|
+
#
|
6
|
+
# Use QuadTrees: http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
|
7
|
+
#
|
8
|
+
module CollisionDetection
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.extend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
def collision?(object2)
|
15
|
+
self.rect.collide_rect?(object2.rect)
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def each_collision(klasses = [])
|
20
|
+
# Make sure klasses is always an array.
|
21
|
+
Array(klasses).each do |klass|
|
22
|
+
self.all.each do |object1|
|
23
|
+
klass.all.each do |object2|
|
24
|
+
yield object1, object2 if object1.collision?(object2)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Components
|
3
|
+
module Visual
|
4
|
+
attr_accessor :image, :x, :y, :angle, :center_x, :center_y, :factor_x, :factor_y, :color, :mode, :zorder
|
5
|
+
|
6
|
+
#
|
7
|
+
# :x screen x-coordinate (default 0, to the left)
|
8
|
+
# :y screen y-coordinate (default 0, top of screen)
|
9
|
+
# :angle angle of object, used in draw_rot, (default 0, no rotation)
|
10
|
+
# :zorder a gameclass "foo" with higher zorder then gameclass "bar" is drawn on top of "foo".
|
11
|
+
# :center_x relative horizontal position of the rotation center on the image.
|
12
|
+
# 0 is the left border, 1 is the right border, 0.5 is the center (default 0.5)
|
13
|
+
# :center_y see center_x. (default 0.5)
|
14
|
+
# :factor_x horizontal zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
15
|
+
# :factor_y vertical zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
16
|
+
#
|
17
|
+
# :update [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
18
|
+
# :draw [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
19
|
+
#
|
20
|
+
|
21
|
+
def self.included(base)
|
22
|
+
#base.__send__(:alias_method, :orig_initialize, :initialize)
|
23
|
+
#base.__send__(:alias_method, :initialize, :orig_initialize)
|
24
|
+
|
25
|
+
#base.__send__( :alias_method, :initialize_without_extras, :initialize )
|
26
|
+
#base.__send__( :alias_method, :initialize, :initialize_with_extras )
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :orig_initialize, :initialize
|
30
|
+
def initialize(options = {})
|
31
|
+
|
32
|
+
puts "Visual#initialize"
|
33
|
+
|
34
|
+
# draw_rot arguments
|
35
|
+
@image = options[:image] if options[:image].is_a? Gosu::Image
|
36
|
+
@image = Image[options[:image]] if options[:image].is_a? String
|
37
|
+
@x = options[:x] || 0
|
38
|
+
@y = options[:y] || 0
|
39
|
+
@angle = options[:angle] || 0
|
40
|
+
@zorder = options[:zorder] || 100
|
41
|
+
@center_x = options[:center_x] || options[:center] || 0.5
|
42
|
+
@center_y = options[:center_y] || options[:center] || 0.5
|
43
|
+
@factor_x = options[:factor_x] || options[:factor] || 1.0
|
44
|
+
@factor_y = options[:factor_y] || options[:factor] || 1.0
|
45
|
+
@mode = options[:mode] || :default # :additive is also available.
|
46
|
+
@color = Gosu::Color.new(options[:color]) if options[:color].is_a? Bignum
|
47
|
+
@color = options[:color] if options[:color].respond_to?(:alpha)
|
48
|
+
@color = Gosu::Color.new(0xFFFFFFFF) if @color.nil?
|
49
|
+
|
50
|
+
# Shortcuts for draw_rot arguments
|
51
|
+
@factor = 1
|
52
|
+
|
53
|
+
# gameloop/framework logic
|
54
|
+
@update = options[:update] || true
|
55
|
+
@draw = options[:draw] || true
|
56
|
+
|
57
|
+
orig_initialize(options)
|
58
|
+
#orig_initialize
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Quick way of setting both factor_x and factor_y
|
63
|
+
#
|
64
|
+
def factor=(factor)
|
65
|
+
@factor_x = @factor_y = factor
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Quick way of setting both center_x and center_y
|
70
|
+
#
|
71
|
+
def center=(factor)
|
72
|
+
@center_x = @center_y = factor
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Returns true if object is inside the game window, false if outside
|
77
|
+
#
|
78
|
+
def inside_window?(x = @x, y = @y)
|
79
|
+
x >= 0 && x <= $window.width && y >= 0 && y <= $window.height
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Returns true object is outside the game window
|
84
|
+
#
|
85
|
+
def outside_window?(x = @x, y = @y)
|
86
|
+
not inside_window?(x,y)
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# The core of the gameclass, the draw_rot encapsulation. Draws the sprite on screen.
|
91
|
+
# Calling #to_i on @x and @y enables thoose to be Float's, for subpixel slow movement in #update
|
92
|
+
#
|
93
|
+
def draw(parent)
|
94
|
+
@image.draw_rot(@x.to_i, @y.to_i, @zorder, @angle, @center_x, @center_y, @factor_x, @factor_y, @color, @mode)
|
95
|
+
#parent.image.draw_rot( parent.x.to_i,
|
96
|
+
# parent.y.to_i,
|
97
|
+
# parent.zorder,
|
98
|
+
# parent.angle,
|
99
|
+
# parent.center_x,
|
100
|
+
# parent.center_y,
|
101
|
+
# parent.factor_x,
|
102
|
+
# parent.factor_y,
|
103
|
+
# parent.color,
|
104
|
+
# parent.mode)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Components
|
3
|
+
class Visual
|
4
|
+
|
5
|
+
def initialize(parent_class, options)
|
6
|
+
@parent_class = parent_class
|
7
|
+
@parent_class.class_eval do
|
8
|
+
attr_accessor :image, :x, :y, :angle, :center_x, :center_y, :factor_x, :factor_y, :color, :mode, :zorder
|
9
|
+
|
10
|
+
# Quick way of setting both factor_x and factor_y
|
11
|
+
def factor=(factor)
|
12
|
+
@factor_x = @factor_y = factor
|
13
|
+
end
|
14
|
+
|
15
|
+
# Quick way of setting both center_x and center_y
|
16
|
+
def center=(factor)
|
17
|
+
@center_x = @center_y = factor
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns true if object is inside the game window, false if outside
|
21
|
+
def inside_window?(x = @x, y = @y)
|
22
|
+
x >= 0 && x <= $window.width && y >= 0 && y <= $window.height
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns true object is outside the game window
|
26
|
+
def outside_window?(x = @x, y = @y)
|
27
|
+
not inside_window?(x,y)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# :x screen x-coordinate (default 0, to the left)
|
35
|
+
# :y screen y-coordinate (default 0, top of screen)
|
36
|
+
# :angle angle of object, used in draw_rot, (default 0, no rotation)
|
37
|
+
# :zorder a gameclass "foo" with higher zorder then gameclass "bar" is drawn on top of "foo".
|
38
|
+
# :center_x relative horizontal position of the rotation center on the image.
|
39
|
+
# 0 is the left border, 1 is the right border, 0.5 is the center (default 0.5)
|
40
|
+
# :center_y see center_x. (default 0.5)
|
41
|
+
# :factor_x horizontal zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
42
|
+
# :factor_y vertical zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
43
|
+
#
|
44
|
+
# :update [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
45
|
+
# :draw [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
46
|
+
#
|
47
|
+
def setup(parent_instance, options)
|
48
|
+
@parent_instance = parent_instance
|
49
|
+
@parent_instance.instance_eval do
|
50
|
+
# draw_rot arguments
|
51
|
+
@image = options[:image] if options[:image].is_a? Gosu::Image
|
52
|
+
@image = Image[options[:image]] if options[:image].is_a? String
|
53
|
+
@x = options[:x] || 0
|
54
|
+
@y = options[:y] || 0
|
55
|
+
@angle = options[:angle] || 0
|
56
|
+
@zorder = options[:zorder] || 100
|
57
|
+
@center_x = options[:center_x] || options[:center] || 0.5
|
58
|
+
@center_y = options[:center_y] || options[:center] || 0.5
|
59
|
+
@factor_x = options[:factor_x] || options[:factor] || 1.0
|
60
|
+
@factor_y = options[:factor_y] || options[:factor] || 1.0
|
61
|
+
|
62
|
+
@color = Gosu::Color.new(options[:color]) if options[:color].is_a? Bignum
|
63
|
+
@color = options[:color] if options[:color].respond_to?(:alpha)
|
64
|
+
@color = Gosu::Color.new(0xFFFFFFFF) if @color.nil?
|
65
|
+
|
66
|
+
@mode = options[:mode] || :default # :additive is also available.
|
67
|
+
|
68
|
+
# Shortcuts for draw_rot arguments
|
69
|
+
@factor = 1
|
70
|
+
|
71
|
+
# gameloop/framework logic
|
72
|
+
@update = options[:update] || true
|
73
|
+
@draw = options[:draw] || true
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
def update(parent)
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# The core of the gameclass, the draw_rot encapsulation. Draws the sprite on screen.
|
83
|
+
# Calling #to_i on @x and @y enables thoose to be Float's, for subpixel slow movement in #update
|
84
|
+
#
|
85
|
+
def draw(parent)
|
86
|
+
## @image.draw_rot(@x.to_i, @y.to_i, @zorder, @angle, @center_x, @center_y, @factor_x, @factor_y, @color, @mode)
|
87
|
+
parent.image.draw_rot( parent.x.to_i,
|
88
|
+
parent.y.to_i,
|
89
|
+
parent.zorder,
|
90
|
+
parent.angle,
|
91
|
+
parent.center_x,
|
92
|
+
parent.center_y,
|
93
|
+
parent.factor_x,
|
94
|
+
parent.factor_y,
|
95
|
+
parent.color,
|
96
|
+
parent.mode)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Components
|
3
|
+
class 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
|
+
def initialize(parent_class, options)
|
16
|
+
@parent_class = parent_class
|
17
|
+
@parent_class.class_eval do
|
18
|
+
attr_accessor :rotating, :fading, :zooming
|
19
|
+
|
20
|
+
# Zoom - increase @factor_x and @factor_y at the same time.
|
21
|
+
def zoom(amount = 0.1)
|
22
|
+
@factor_x += amount
|
23
|
+
@factor_y += amount
|
24
|
+
end
|
25
|
+
|
26
|
+
# Zoom Out - decrease @factor_x and @factor_y at the same time.
|
27
|
+
def zoom_out(amount = 0.1)
|
28
|
+
@factor_x -= amount
|
29
|
+
@factor_y -= amount
|
30
|
+
end
|
31
|
+
|
32
|
+
# Rotate object 'amount' degrees
|
33
|
+
def rotate(amount = 1)
|
34
|
+
@angle += amount
|
35
|
+
end
|
36
|
+
|
37
|
+
# Fade object by decreasing/increasing color.alpha
|
38
|
+
def fade(amount = 1)
|
39
|
+
return if amount == 0
|
40
|
+
|
41
|
+
new_alpha = @color.alpha + amount
|
42
|
+
if amount < 0
|
43
|
+
@color.alpha = [0, new_alpha].max
|
44
|
+
else
|
45
|
+
@color.alpha = [0, new_alpha].min
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Fade out objects color by decreasing color.alpha
|
50
|
+
def fade_out(amount = 1)
|
51
|
+
fade(-amount)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Fade in objects color by increasing color.alpha
|
55
|
+
def fade_in(amount = 1)
|
56
|
+
fade(amount)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Setup
|
63
|
+
#
|
64
|
+
def setup(parent_instance, options)
|
65
|
+
@parent_instance = parent_instance
|
66
|
+
@parent_instance.instance_eval do
|
67
|
+
@rotating = options[:rotating] || nil
|
68
|
+
@zooming = options[:zooming] || nil
|
69
|
+
@fading = options[:fading] || nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def update(parent)
|
74
|
+
parent.rotate(parent.rotating) if parent.rotating
|
75
|
+
parent.fade(parent.fading) if parent.fading
|
76
|
+
parent.zoom(parent.zooming) if parent.zooming
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Components
|
3
|
+
#
|
4
|
+
# A chingu component providing velocity and acceleration logic.
|
5
|
+
#
|
6
|
+
class Velocity
|
7
|
+
|
8
|
+
def initialize(parent_class, options)
|
9
|
+
@parent_class = parent_class
|
10
|
+
@parent_class.class_eval do
|
11
|
+
attr_accessor :velocity_x, :velocity_y, :acceleration_x, :acceleration_y, :max_velocity
|
12
|
+
|
13
|
+
def stop
|
14
|
+
@acceleration_y = @acceleration_x = @velocity_y = @acceleration_y = 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Setup
|
21
|
+
#
|
22
|
+
def setup(parent_instance, options)
|
23
|
+
@parent_instance = parent_instance
|
24
|
+
@parent_instance.instance_eval do
|
25
|
+
@velocity_x = options[:velocity_x] || 0
|
26
|
+
@velocity_y = options[:velocity_y] || 0
|
27
|
+
@acceleration_x = options[:acceleration_x] || 0
|
28
|
+
@acceleration_y = options[:acceleration_y] || 0
|
29
|
+
@max_velocity = options[:max_velocity] || 1000
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Modifies X & Y of parent
|
35
|
+
#
|
36
|
+
def update(parent)
|
37
|
+
#
|
38
|
+
# This is slower oddly enough?
|
39
|
+
#
|
40
|
+
#parent.velocity_y += parent.acceleration_y if (parent.velocity_y + parent.acceleration_y).abs < parent.max_velocity
|
41
|
+
#parent.velocity_x += parent.acceleration_x if (parent.velocity_x + parent.acceleration_x).abs < parent.max_velocity
|
42
|
+
#parent.y += parent.velocity_y
|
43
|
+
#parent.x += parent.velocity_x
|
44
|
+
|
45
|
+
parent.instance_eval do
|
46
|
+
@velocity_y += @acceleration_y if (@velocity_y + @acceleration_y).abs < @max_velocity
|
47
|
+
@velocity_x += @acceleration_x if (@velocity_x + @acceleration_x).abs < @max_velocity
|
48
|
+
#vel_y = (@velocity_y + @acceleration_y).abs
|
49
|
+
#@velocity_y = vel_y if vel_y < @max_velocity
|
50
|
+
#vel_x = (@velocity_x + @acceleration_x).abs
|
51
|
+
#@velocity_x = vel_x if vel_x < @max_velocity
|
52
|
+
|
53
|
+
@y += @velocity_y
|
54
|
+
@x += @velocity_x
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/chingu/window.rb
CHANGED
@@ -44,6 +44,7 @@ module Chingu
|
|
44
44
|
|
45
45
|
@fps_counter = FPSCounter.new
|
46
46
|
@game_state_manager = GameStateManager.new
|
47
|
+
@milliseconds_since_last_tick = 0
|
47
48
|
end
|
48
49
|
|
49
50
|
def add_game_object(object)
|
@@ -67,6 +68,13 @@ module Chingu
|
|
67
68
|
def ticks
|
68
69
|
@fps_counter.ticks
|
69
70
|
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Mathematical short name for "milliseconds since last tick"
|
74
|
+
#
|
75
|
+
def dt
|
76
|
+
@milliseconds_since_last_tick
|
77
|
+
end
|
70
78
|
|
71
79
|
#
|
72
80
|
# Chingus core-logic / loop. Gosu will call this each game-iteration.
|
@@ -78,8 +86,15 @@ module Chingu
|
|
78
86
|
# Without this self.fps would return an incorrect value.
|
79
87
|
# If you override this in your Chingu::Window class, make sure to call super.
|
80
88
|
#
|
81
|
-
@milliseconds_since_last_tick = @fps_counter.register_tick
|
89
|
+
@milliseconds_since_last_tick = @fps_counter.register_tick
|
82
90
|
|
91
|
+
intermediate_update
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# "game logic" update that is safe to call even between Gosus update-calls
|
96
|
+
#
|
97
|
+
def intermediate_update
|
83
98
|
#
|
84
99
|
# Dispatch inputmap for main window
|
85
100
|
#
|
@@ -123,7 +138,7 @@ module Chingu
|
|
123
138
|
# Call update() on all game objects in main game window.
|
124
139
|
#
|
125
140
|
def update_game_objects
|
126
|
-
@game_objects.each { |object| object.update
|
141
|
+
@game_objects.each { |object| object.update }
|
127
142
|
end
|
128
143
|
|
129
144
|
#
|
@@ -132,7 +147,7 @@ module Chingu
|
|
132
147
|
# -> call update on all game objects in that state
|
133
148
|
#
|
134
149
|
def update_game_state_manager
|
135
|
-
@game_state_manager.update
|
150
|
+
@game_state_manager.update
|
136
151
|
end
|
137
152
|
|
138
153
|
#
|