chingu 0.7.5 → 0.7.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.
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require File.join(File.dirname($0), "..", "lib", "chingu")
4
+ include Gosu
5
+ include Chingu
6
+
7
+ #
8
+ # Press 'E' when demo is running to edit the playfield!
9
+ #
10
+ class Game < Chingu::Window
11
+ def initialize
12
+ super(1000,700)
13
+ end
14
+
15
+ def setup
16
+ Gosu::enable_undocumented_retrofication
17
+ switch_game_state(Example21.new)
18
+ end
19
+ end
20
+
21
+ #
22
+ # The Game
23
+ #
24
+ class Example21 < GameState
25
+ traits :viewport, :timer
26
+
27
+ def setup
28
+ self.input = { :escape => :exit, :e => :edit }
29
+ self.viewport.game_area = [0, 0, 3000, 1000]
30
+
31
+ @droid = Droid.create(:x => 100, :y => 300)
32
+ #@droid = Droid.create(:x => 2500, :y => 1200)
33
+ #@droid = Droid.create(:x => 500, :y => 1500)
34
+
35
+ load_game_objects
36
+
37
+ # Reverse the cog wheels in relation to eachother
38
+ CogWheel.each_collision(CogWheel) do |cog_wheel, cog_wheel_2|
39
+ cog_wheel_2.angle_velocity = -cog_wheel.angle_velocity
40
+ end
41
+
42
+ @saved_x, @saved_y = [100, 300]
43
+ every(5000) { save_player_position }
44
+ end
45
+
46
+ def edit
47
+ push_game_state(GameStates::Edit.new(:grid => [32,32], :classes => [Tube, CogWheel, Block, Saw, Battery]))
48
+ end
49
+
50
+ def restore_player_position
51
+ @droid.x, @droid.y = @saved_x, @saved_y
52
+ end
53
+
54
+ def save_player_position
55
+ @saved_x, @saved_y = @droid.x, @droid.y if @droid.velocity_y >= 0 && @droid.collidable
56
+ end
57
+
58
+ def update
59
+ super
60
+
61
+ visible_blocks = Block.inside_viewport
62
+
63
+ FireBall.each_collision(visible_blocks) do |fire_ball, block|
64
+ fire_ball.destroy
65
+ end
66
+
67
+ # Makes all saw pendle up and down between Y-coordinate 1000 - 1500
68
+ # TODO: Not a very flexible sollution, how about setting out circle,rects,lines in editor..
69
+ # .. when then can be used for this kind of stuff?
70
+ Saw.all.select {|saw| saw.y < 1300 || saw.y > 1550 }.each do |saw|
71
+ saw.velocity_y = -saw.velocity_y
72
+ saw.y += saw.velocity_y * saw.factor_y
73
+ end
74
+
75
+ @droid.each_collision(FireBall, Saw) do |player, evil_object|
76
+ player.die
77
+ end
78
+
79
+ @droid.each_collision(Battery) do |player, battery|
80
+ battery.die
81
+ #after(3000) { push_game_state(GameFinished) }
82
+ end
83
+
84
+
85
+ self.viewport.center_around(@droid)
86
+
87
+ $window.caption = "Haunted Factory. TAB toggles Edit. x/y: #{@droid.x.to_i}/#{@droid.y.to_i} - viewport x/y: #{self.viewport.x.to_i}/#{self.viewport.y.to_i} - FPS: #{$window.fps}"
88
+ end
89
+ end
90
+
91
+ #
92
+ #
93
+ class GameFinished < GameState
94
+ def setup
95
+ self.input
96
+ Text.create("MMMM... Battery ACID, YUM!")
97
+ end
98
+ end
99
+
100
+ #
101
+ # DROID
102
+ #
103
+ class Droid < Chingu::GameObject
104
+ trait :bounding_box, :scale => 0.80
105
+ traits :timer, :collision_detection , :timer, :velocity
106
+
107
+ def setup
108
+ self.input = { [:holding_left, :holding_a] => :holding_left,
109
+ [:holding_right, :holding_d] => :holding_right,
110
+ [:up, :w] => :jump,
111
+ :space => :fire
112
+ }
113
+
114
+ # Load the full animation from tile-file media/droid.bmp
115
+ @animations = Chingu::Animation.new(:file => "droid_11x15.bmp")
116
+ @animations.frame_names = { :scan => 0..5, :up => 6..7, :down => 8..9, :left => 10..11, :right => 12..13 }
117
+
118
+ @animation = @animations[:scan]
119
+ @speed = 3
120
+
121
+ self.zorder = 300
122
+ self.factor = 3
123
+ self.acceleration_y = 0.5
124
+ self.max_velocity = 10
125
+ self.rotation_center = :bottom_center
126
+
127
+ update
128
+ end
129
+
130
+ def die
131
+ self.collidable = false
132
+ @color = Color::RED
133
+ between(1,600) { self.velocity_y = 0; self.scale += 0.2; self.alpha -= 5; }.then { resurrect }
134
+ end
135
+
136
+ def resurrect
137
+ self.alpha = 255
138
+ self.factor = 3
139
+ self.collidable = true
140
+ @color = Color::WHITE
141
+ game_state.restore_player_position
142
+ end
143
+
144
+ def holding_left
145
+ move(-@speed, 0)
146
+ @animation = @animations[:left]
147
+ end
148
+
149
+ def holding_right
150
+ move(@speed, 0)
151
+ @animation = @animations[:right]
152
+ end
153
+
154
+ def jump
155
+ return if self.velocity_y < 0
156
+ self.velocity_y = -10
157
+ @animation = @animations[:up]
158
+ end
159
+
160
+ def move(x,y)
161
+ @x += x
162
+ self.each_collision(Block.inside_viewport) do |me, stone_wall|
163
+ me.x = previous_x
164
+ end
165
+ end
166
+
167
+ def update
168
+ @image = @animation.next
169
+ self.each_collision(Block.inside_viewport) do |me, stone_wall|
170
+ if self.velocity_y < 0
171
+ me.y = stone_wall.bb.bottom + me.image.height * self.factor_y
172
+ self.velocity_y = 0
173
+ else
174
+ me.y = stone_wall.bb.top-1
175
+ end
176
+ end
177
+
178
+ @animation = @animations[:scan] unless moved?
179
+ end
180
+ end
181
+
182
+ #
183
+ # TUBE
184
+ #
185
+ class Tube < GameObject
186
+ traits :bounding_box, :timer
187
+ def setup
188
+ @image = Image["tube.png"]
189
+ every(3000) { fire }
190
+ cache_bounding_box
191
+ end
192
+
193
+ def fire
194
+ return if game_state.viewport.outside?(self.bb.centerx, self.bb.bottom)
195
+ FireBall.create(:x => self.bb.centerx - rand(10), :y => self.bb.bottom - rand(10))
196
+ end
197
+ end
198
+
199
+ #
200
+ # BATTERY
201
+ #
202
+ class Battery < GameObject
203
+ traits :timer, :effect
204
+ trait :bounding_box, :debug => false
205
+
206
+ def setup
207
+ @image = Image["battery.png"]
208
+ cache_bounding_box
209
+ end
210
+
211
+ def die
212
+ self.collidable = false # Stops further collisions in each_collsiion() etc.
213
+ self.rotation_rate = 5
214
+ self.scale_rate = 0.005
215
+ self.fade_rate = -5
216
+ after(2000) { destroy }
217
+ end
218
+ end
219
+
220
+ #
221
+ # A FIREBALL
222
+ #
223
+ class FireBall < GameObject
224
+ traits :velocity, :collision_detection
225
+ trait :bounding_circle, :scale => 0.7
226
+
227
+ def setup
228
+ @animation = Animation.new(:file => "fireball.png", :size => [32,32], :delay => 20)
229
+ @image = @animation.first
230
+ self.mode = :additive
231
+ self.factor = 3
232
+ self.velocity_y = 1
233
+ self.zorder = 200
234
+ self.rotation_center = :center
235
+ end
236
+
237
+ def update
238
+ @image = @animation.next
239
+ @angle += 2
240
+ end
241
+ end
242
+
243
+ #
244
+ # COG WHEEL
245
+ #
246
+ class CogWheel < GameObject
247
+ traits :bounding_circle, :collision_detection, :timer
248
+ attr_accessor :angle_velocity
249
+
250
+ def setup
251
+ @image = Image["cog_wheel.png"]
252
+ @angle_velocity = 1 / self.factor_x
253
+ end
254
+
255
+ def update
256
+ self.angle += @angle_velocity
257
+ end
258
+ end
259
+
260
+ #
261
+ # SAW
262
+ #
263
+ class Saw < GameObject
264
+ traits :bounding_circle, :collision_detection, :timer, :velocity
265
+ attr_accessor :angle_velocity
266
+
267
+ def setup
268
+ @image = Image["saw.png"]
269
+ @angle_velocity = 3.0 / self.factor_x.to_f
270
+ self.velocity_y = 1.0 / self.factor_x.to_f
271
+ end
272
+
273
+ def update
274
+ self.angle += @angle_velocity
275
+ end
276
+ end
277
+
278
+ #
279
+ # BLOCK, our basic level building block
280
+ #
281
+ class Block < GameObject
282
+ trait :bounding_box, :debug => false
283
+ trait :collision_detection
284
+
285
+ def self.solid
286
+ all.select { |block| block.alpha == 255 }
287
+ end
288
+
289
+ def self.inside_viewport
290
+ all.select { |block| block.game_state.viewport.inside?(block) }
291
+ end
292
+
293
+ def setup
294
+ @image = Image["black_block.png"]
295
+ end
296
+ end
297
+
298
+ Game.new.show
@@ -34,8 +34,8 @@ class GameOfLife < Chingu::GameState
34
34
  :z => :reset,
35
35
  :n => :update_grid,
36
36
  :space => :toggle_running,
37
- :left_arrow => :prev_pattern,
38
- :right_arrow => :next_pattern
37
+ [:mouse_wheel_up,:left_arrow] => :prev_pattern,
38
+ [:mouse_wheel_down,:right_arrow] => :next_pattern
39
39
  }
40
40
 
41
41
  @pattern = :pixel
@@ -49,7 +49,7 @@ class GameOfLife < Chingu::GameState
49
49
  end
50
50
 
51
51
  def update_pattern_info
52
- @pattern_info.text = "Current pattern: #{@pattern}. Change patterns with left/right arrow keys."
52
+ @pattern_info.text = "Current pattern: #{@pattern}. Change patterns with mousewheel."
53
53
  end
54
54
 
55
55
  def prev_pattern
Binary file
Binary file
@@ -33,7 +33,7 @@ require_all "#{CHINGU_ROOT}/chingu/traits"
33
33
  require_all "#{CHINGU_ROOT}/chingu"
34
34
 
35
35
  module Chingu
36
- VERSION = "0.7.5"
36
+ VERSION = "0.7.6"
37
37
 
38
38
  DEBUG_COLOR = Gosu::Color.new(0xFFFF0000)
39
39
  DEBUG_ZORDER = 9999
@@ -66,11 +66,16 @@ module Chingu
66
66
 
67
67
  #
68
68
  # Remove transparent space from each frame so the actual sprite is touching the border of the image.
69
+ # This requires TexPlay
69
70
  #
70
71
  def trim
71
- @frames.each do |frame|
72
- # TODO!
73
- end
72
+ #@frames.each do |frame|
73
+ # y = 0
74
+ # x2, y2, color = frame.line 0,y,frame.width,y, :trace => { :while_color => :alpha }
75
+ # puts "final y: #{y}"
76
+ # #frame.image.trace 0,0,image
77
+ # #frame.splice(frame,0,0, :crop => [10, 10, 20, 20])
78
+ #end
74
79
  end
75
80
 
76
81
  #
@@ -60,7 +60,9 @@ module Chingu
60
60
  # subclass.initialize_inherited_trait if subclass.method_defined?(:initialize_inherited_trait)
61
61
  #end
62
62
 
63
-
63
+ alias :game_state :parent
64
+ alias :game_state= :parent=
65
+
64
66
  #
65
67
  # BasicGameObject initialize
66
68
  # - call .setup_trait() on all traits that implements it
@@ -32,7 +32,7 @@ module Chingu
32
32
  #
33
33
  class GameObject < Chingu::BasicGameObject
34
34
  attr_accessor :image, :x, :y, :angle, :center_x, :center_y, :factor_x, :factor_y, :color, :mode, :zorder
35
- attr_reader :factor, :center#, :rotation_center
35
+ attr_reader :factor, :center
36
36
 
37
37
  include Chingu::Helpers::InputClient # Adds input and input=
38
38
  include Chingu::Helpers::RotationCenter # Adds easy and verbose modification of @center_x and @center_y
@@ -42,17 +42,17 @@ module Chingu
42
42
 
43
43
  #
44
44
  # All encapsulated Gosu::Image.draw_rot arguments can be set with hash-options at creation time
45
- #
45
+ #
46
46
  if options[:image].is_a?(Gosu::Image)
47
47
  @image = options[:image]
48
48
  elsif options[:image].is_a? String
49
- begin
50
- # 1) Try loading the image the normal way
51
- @image = Gosu::Image.new($window, options[:image])
52
- rescue
53
- # 2) Try looking up the picture using Chingus Image-cache
54
- @image = Gosu::Image[options[:image]]
55
- end
49
+ begin
50
+ # 1) Try loading the image the normal way
51
+ @image = Gosu::Image.new($window, options[:image])
52
+ rescue
53
+ # 2) Try looking up the picture using Chingus Image-cache
54
+ @image = Gosu::Image[options[:image]]
55
+ end
56
56
  end
57
57
 
58
58
  @x = options[:x] || 0
@@ -115,7 +115,19 @@ module Chingu
115
115
  value = 255 if value > 255
116
116
  @color.alpha = value
117
117
  end
118
-
118
+
119
+ #
120
+ # Sets angle, normalize it to between 0..360
121
+ #
122
+ def angle=(value)
123
+ if value < 0
124
+ value = 360+value
125
+ elsif value > 360
126
+ value = value-360
127
+ end
128
+ @angle = value
129
+ end
130
+
119
131
 
120
132
  # Returns true if object is inside the game window, false if outside
121
133
  def inside_window?(x = @x, y = @y)
@@ -127,7 +139,7 @@ module Chingu
127
139
  not inside_window?(x,y)
128
140
  end
129
141
 
130
- # Calculates the distance from self to a given objevt
142
+ # Calculates the distance from self to a given object
131
143
  def distance_to(object)
132
144
  distance(self.x, self.y, object.x, object.y)
133
145
  end
@@ -128,6 +128,17 @@ module Chingu
128
128
  self.class.to_s
129
129
  end
130
130
 
131
+ #
132
+ # Returns a filename-friendly string from the current class-name
133
+ #
134
+ # "Level19" -> "level19"
135
+ # "BigBossLevel" -> "big_boss_level"
136
+ #
137
+ def filename
138
+ Chingu::Inflector.underscore(self.class.to_s)
139
+ end
140
+
141
+
131
142
  def setup
132
143
  # Your game state setup logic here.
133
144
  end