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.
@@ -30,9 +30,9 @@ module Chingu
30
30
  end
31
31
 
32
32
  #
33
- # TODO: make use of time here!
33
+ # TODO: make use of $window.milliseconds_since_last_update here!
34
34
  #
35
- def update(time)
35
+ def update
36
36
  @backgrounds.each do |background|
37
37
  background.x = -@x / background.damping
38
38
  background.y = @y / background.damping
@@ -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(time)
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,15 @@
1
+ module Chingu
2
+ module Components
3
+ module Input
4
+
5
+ def input=(input_map)
6
+ @input = input_map
7
+ @parent.add_input_client(self) if @parent
8
+ end
9
+
10
+ def input
11
+ @input
12
+ end
13
+ end
14
+ end
15
+ 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(@milliseconds_since_last_tick) }
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(@milliseconds_since_last_tick)
150
+ @game_state_manager.update
136
151
  end
137
152
 
138
153
  #