chingu 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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