chingu 0.7.0 → 0.7.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 +1 -1
- data/README.rdoc +110 -49
- data/benchmarks/game_objects_benchmark.rb +50 -0
- data/chingu.gemspec +24 -12
- data/examples/example10_traits_retrofy.rb +6 -4
- data/examples/example11_animation.rb +14 -23
- data/examples/example12_trait_timer.rb +1 -1
- data/examples/example13_high_scores.rb +1 -1
- data/examples/example14_bounding_box_circle.rb +6 -10
- data/examples/example15_trait_timer2.rb +1 -1
- data/examples/example16_online_high_scores.rb +1 -1
- data/examples/example17_gosu_tutorial.rb +4 -4
- data/examples/example18_animation_trait.rb +98 -0
- data/examples/example19_edit_viewport.rb +223 -0
- data/examples/example19_game_objects.yml +1591 -0
- data/examples/example20_trait_inheritence_test.rb +58 -0
- data/examples/example3_parallax.rb +1 -1
- data/examples/example4_gamestates.rb +1 -1
- data/examples/example7_gfx_helpers.rb +14 -9
- data/examples/example8_traits.rb +4 -4
- data/examples/example9_collision_detection.rb +1 -1
- data/examples/game1.rb +33 -38
- data/examples/game_of_life.rb +291 -0
- data/examples/media/droid_11x15.bmp +0 -0
- data/examples/media/droid_11x15.gal +0 -0
- data/examples/media/heli.bmp +0 -0
- data/examples/media/heli.gal +0 -0
- data/examples/media/star_25x25_default.png +0 -0
- data/examples/media/star_25x25_explode.gal +0 -0
- data/examples/media/star_25x25_explode.png +0 -0
- data/examples/media/stone_wall.bmp +0 -0
- data/lib/chingu.rb +1 -1
- data/lib/chingu/animation.rb +78 -9
- data/lib/chingu/basic_game_object.rb +16 -8
- data/lib/chingu/game_object.rb +36 -7
- data/lib/chingu/game_object_list.rb +20 -3
- data/lib/chingu/game_state.rb +8 -7
- data/lib/chingu/game_states/edit.rb +177 -90
- data/lib/chingu/helpers/class_inheritable_accessor.rb +12 -5
- data/lib/chingu/helpers/game_object.rb +45 -4
- data/lib/chingu/helpers/gfx.rb +150 -172
- data/lib/chingu/helpers/input_client.rb +7 -0
- data/lib/chingu/inflector.rb +16 -2
- data/lib/chingu/traits/animation.rb +84 -0
- data/lib/chingu/traits/bounding_box.rb +16 -3
- data/lib/chingu/traits/bounding_circle.rb +18 -4
- data/lib/chingu/traits/collision_detection.rb +10 -1
- data/lib/chingu/traits/velocity.rb +26 -3
- data/lib/chingu/traits/viewport.rb +10 -9
- data/lib/chingu/viewport.rb +103 -22
- data/lib/chingu/window.rb +8 -2
- metadata +46 -16
- data/examples/example18_viewport.rb +0 -173
- data/examples/media/city1.csv +0 -2
- data/examples/media/plane.csv +0 -2
- data/examples/media/saucer.csv +0 -4
- data/examples/media/stickfigure.bmp +0 -0
- data/examples/media/stickfigure.png +0 -0
@@ -0,0 +1,58 @@
|
|
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
|
+
# This is more of a technical test to sort out the class inheritable accessor ..
|
9
|
+
# ..more then it's a fun-to-watch demo.
|
10
|
+
#
|
11
|
+
class Game < Chingu::Window
|
12
|
+
def initialize
|
13
|
+
super
|
14
|
+
self.input = { :escape => :exit }
|
15
|
+
|
16
|
+
star = SpinningStar.create(:x => 400, :y => 100)
|
17
|
+
star2 = MovingStar.create(:x => 10, :y => 200)
|
18
|
+
|
19
|
+
p star.class.superclass
|
20
|
+
p "=== Should only have collision detection"
|
21
|
+
p star.class
|
22
|
+
p star.class.trait_options
|
23
|
+
p "=== Should have collision detection and velocity"
|
24
|
+
p star2.class
|
25
|
+
p star2.class.trait_options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
class Star < GameObject
|
31
|
+
trait :collision_detection
|
32
|
+
|
33
|
+
def initialize(options={})
|
34
|
+
super
|
35
|
+
|
36
|
+
@animation = Chingu::Animation.new(:file => "Star.png", :size => 25)
|
37
|
+
@image = @animation.next
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class MovingStar < Star
|
43
|
+
trait :velocity
|
44
|
+
|
45
|
+
def initialize(options={})
|
46
|
+
super
|
47
|
+
self.velocity_x = 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class SpinningStar < Star
|
52
|
+
def update
|
53
|
+
@image = @animation.next
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
Game.new.show
|
@@ -35,7 +35,7 @@ class Game < Chingu::Window
|
|
35
35
|
push_game_state(Intro)
|
36
36
|
|
37
37
|
# Yes you can do crazy things like this :)
|
38
|
-
self.input = { :left_mouse_button => lambda{Chingu::Text.create(:text => "
|
38
|
+
self.input = { :left_mouse_button => lambda{Chingu::Text.create(:text => "Woof!")}, :esc => :exit}
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -17,6 +17,7 @@ class Game < Chingu::Window
|
|
17
17
|
push_game_state(FillRect)
|
18
18
|
push_game_state(FillGradient)
|
19
19
|
push_game_state(FillGradientRect)
|
20
|
+
push_game_state(FillGradientMultipleColors)
|
20
21
|
push_game_state(Particles)
|
21
22
|
end
|
22
23
|
|
@@ -25,24 +26,17 @@ class Game < Chingu::Window
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
29
|
class Fill < Chingu::GameState
|
30
|
-
def setup
|
31
|
-
@white = Color.new(255,255,255,255)
|
32
|
-
end
|
33
30
|
def draw
|
34
31
|
$window.caption = "fill (space to continue)"
|
35
|
-
fill(
|
32
|
+
fill(Color::RED)
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
39
36
|
class FillRect < Chingu::GameState
|
40
|
-
def setup
|
41
|
-
@white = Color.new(255,255,255,255)
|
42
|
-
end
|
43
37
|
def draw
|
44
38
|
$window.caption = "fill_rect (space to continue)"
|
45
|
-
fill_rect([10,10,100,100],
|
39
|
+
fill_rect([10,10,100,100], Color::WHITE)
|
46
40
|
end
|
47
41
|
end
|
48
42
|
|
@@ -58,6 +52,17 @@ class FillGradient < Chingu::GameState
|
|
58
52
|
end
|
59
53
|
end
|
60
54
|
|
55
|
+
class FillGradientMultipleColors < Chingu::GameState
|
56
|
+
def setup
|
57
|
+
@colors = [ 0xffff0000, 0xff00ff00, 0xff0000ff ].map { |c| Color.new(c) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def draw
|
61
|
+
$window.caption = "fill_gradient with more than two colors (space to continue)"
|
62
|
+
fill_gradient(:colors => @colors, :orientation => :horizontal)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
61
66
|
class FillGradientRect < Chingu::GameState
|
62
67
|
def setup
|
63
68
|
@color1 = Color.new(0xFFFFEA02)
|
data/examples/example8_traits.rb
CHANGED
@@ -19,11 +19,10 @@ class Game < Chingu::Window
|
|
19
19
|
end
|
20
20
|
|
21
21
|
class Plasma < Chingu::GameObject
|
22
|
-
|
22
|
+
traits :velocity
|
23
23
|
attr_accessor :fade_rate
|
24
24
|
|
25
|
-
def
|
26
|
-
super
|
25
|
+
def setup
|
27
26
|
@image = Image["particle.png"]
|
28
27
|
@mode = :additive
|
29
28
|
|
@@ -59,10 +58,11 @@ class Particles < Chingu::GameState
|
|
59
58
|
# first optimization: 490 particles, 47 fps (350 @ 60)
|
60
59
|
# optimized GameObject if/elsif: 490 particles, 50 fps
|
61
60
|
#
|
62
|
-
Plasma.create(:x => 0, :y => 0 + rand(5), :color => Color.
|
61
|
+
Plasma.create(:x => 0, :y => 0 + rand(5), :color => Color::RED.dup, :velocity_x => 10)
|
63
62
|
Plasma.create(:x => 0, :y => 50 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 14)
|
64
63
|
Plasma.create(:x => 0, :y => 100 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 7)
|
65
64
|
Plasma.create(:x => 0, :y => 200 + rand(5), :color => Color.new(0xFF86EFFF), :velocity_x => 6)
|
65
|
+
#p pl.mode
|
66
66
|
|
67
67
|
Plasma.all.each do |particle|
|
68
68
|
#
|
data/examples/game1.rb
CHANGED
@@ -3,25 +3,25 @@
|
|
3
3
|
#
|
4
4
|
# A "full" simple game in Chingu, using GameState, GameObject, Paralaxx, has_traits etc
|
5
5
|
#
|
6
|
-
# TODO: clean up code as Chingu moves along :). Comments.
|
6
|
+
# TODO: clean up code as Chingu moves along :). Comments. Get it working ;).
|
7
7
|
#
|
8
8
|
#
|
9
9
|
require 'rubygems'
|
10
10
|
require File.join(File.dirname($0), "..", "lib", "chingu")
|
11
|
-
|
12
11
|
require 'texplay' # adds Image#get_pixel
|
13
|
-
require 'opengl'
|
12
|
+
#require 'opengl' # adds raw gl stuff so Image#retrofy works (in some setups this seems to be 'gl')
|
14
13
|
|
15
14
|
include Gosu
|
16
15
|
include Chingu
|
17
16
|
|
18
17
|
class Game < Chingu::Window
|
19
|
-
attr_reader :factor
|
18
|
+
#attr_reader :factor
|
20
19
|
|
21
20
|
def initialize
|
22
|
-
super(1000,
|
21
|
+
super(1000,400,false)
|
23
22
|
self.input = { :escape => :exit }
|
24
|
-
|
23
|
+
self.factor = 1
|
24
|
+
Gosu::enable_undocumented_retrofication
|
25
25
|
switch_game_state(Level)
|
26
26
|
end
|
27
27
|
end
|
@@ -37,8 +37,12 @@ class Level < Chingu::GameState
|
|
37
37
|
super
|
38
38
|
|
39
39
|
@parallax = Parallax.create(:rotation_center => :top_left)
|
40
|
-
|
41
|
-
@parallax << { :image =>
|
40
|
+
#@parallax = Parallax.create(:rotation_center => :center)
|
41
|
+
@parallax << { :image => "city2.png", :damping => 2}#, :factor => $window.factor }
|
42
|
+
@parallax << { :image => "city1.png", :damping => 1}#, :factor => $window.factor }
|
43
|
+
#@parallax.x = $window.width / 2
|
44
|
+
#@parallax.y = $window.height / 2
|
45
|
+
|
42
46
|
@player = Player.create(:x => 30, :y => 10)
|
43
47
|
|
44
48
|
@bg1 = Color.new(0xFFCE28FF)
|
@@ -72,7 +76,8 @@ class Level < Chingu::GameState
|
|
72
76
|
#return false if pixel.nil?
|
73
77
|
#return
|
74
78
|
|
75
|
-
@parallax.layers.last.get_pixel(x
|
79
|
+
@parallax.layers.last.get_pixel(x * $window.factor, y * $window.factor)[3] != 0
|
80
|
+
#@parallax.layers.last.get_pixel(x, y)[3] != 0
|
76
81
|
rescue
|
77
82
|
puts "Error in get_pixel(#{x}, #{y})"
|
78
83
|
end
|
@@ -91,7 +96,7 @@ class Level < Chingu::GameState
|
|
91
96
|
Bullet.all.select { |o| solid_pixel_at?(o.x, o.y)}.each { |o| o.die }
|
92
97
|
|
93
98
|
# Collide player with terrain
|
94
|
-
push_game_state(GameOver) if solid_pixel_at?(@player.x, @player.y)
|
99
|
+
#push_game_state(GameOver) if solid_pixel_at?(@player.x, @player.y)
|
95
100
|
|
96
101
|
# Collide player with enemies and enemy bullets
|
97
102
|
@player.each_bounding_circle_collision(Enemy) do |player, enemy|
|
@@ -106,7 +111,6 @@ class Level < Chingu::GameState
|
|
106
111
|
end
|
107
112
|
end
|
108
113
|
|
109
|
-
|
110
114
|
@timer = @timer * 0.9999
|
111
115
|
@total_ticks += 1
|
112
116
|
if @total_ticks > @timer
|
@@ -130,14 +134,12 @@ end
|
|
130
134
|
#
|
131
135
|
class Player < GameObject
|
132
136
|
has_traits :velocity, :collision_detection, :timer
|
133
|
-
has_trait :bounding_circle, :scale => 0.50, :debug => true
|
134
|
-
|
137
|
+
has_trait :bounding_circle, :scale => 0.50, :debug => true
|
135
138
|
attr_accessor :score
|
136
139
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
self.factor = $window.factor
|
140
|
+
def setup
|
141
|
+
@image = Image["plane.png"]
|
142
|
+
#self.factor = $window.factor
|
141
143
|
|
142
144
|
self.input = {
|
143
145
|
:holding_left => :left,
|
@@ -150,7 +152,7 @@ class Player < GameObject
|
|
150
152
|
@score = 0
|
151
153
|
@cooling_down = false
|
152
154
|
end
|
153
|
-
|
155
|
+
|
154
156
|
def up
|
155
157
|
self.velocity_y = -@max_velocity
|
156
158
|
end
|
@@ -191,10 +193,9 @@ class Bullet < GameObject
|
|
191
193
|
has_traits :timer, :collision_detection, :velocity
|
192
194
|
attr_reader :status, :radius
|
193
195
|
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
self.factor = $window.factor
|
196
|
+
def setup
|
197
|
+
@image = Image["bullet.png"]
|
198
|
+
#self.factor = $window.factor
|
198
199
|
self.velocity_x = 10
|
199
200
|
@status = :default
|
200
201
|
@radius = 3
|
@@ -217,9 +218,8 @@ end
|
|
217
218
|
# ENEMY BULLET
|
218
219
|
#
|
219
220
|
class EnemyBullet < Bullet
|
220
|
-
def
|
221
|
-
|
222
|
-
@image = Image["enemy_bullet.png"].retrofy
|
221
|
+
def setup
|
222
|
+
@image = Image["enemy_bullet.png"]
|
223
223
|
self.velocity_x = -3
|
224
224
|
end
|
225
225
|
end
|
@@ -238,7 +238,7 @@ class Explosion < GameObject
|
|
238
238
|
@image = @@image.dup if @image.nil?
|
239
239
|
|
240
240
|
self.rotation_center = :center
|
241
|
-
self.factor = options[:factor] ? options[:factor] : $window.factor
|
241
|
+
#self.factor = options[:factor] ? options[:factor] : $window.factor
|
242
242
|
during(100) { self.alpha -= 30}.then { destroy }
|
243
243
|
end
|
244
244
|
|
@@ -254,15 +254,15 @@ end
|
|
254
254
|
class Shrapnel < GameObject
|
255
255
|
has_traits :timer, :effect, :velocity
|
256
256
|
|
257
|
-
def initialize(options)
|
258
|
-
|
259
|
-
|
257
|
+
#def initialize(options)
|
258
|
+
# super
|
259
|
+
def setup
|
260
260
|
self.rotation_rate = 1 + rand(10)
|
261
261
|
self.velocity_x = 4 - rand(8)
|
262
262
|
self.velocity_y = 4 - rand(10)
|
263
263
|
self.acceleration_y = 0.2 # gravity = downards acceleration
|
264
264
|
self.rotation_center = :center
|
265
|
-
self.factor = $window.factor
|
265
|
+
#self.factor = $window.factor
|
266
266
|
@status = :default
|
267
267
|
end
|
268
268
|
|
@@ -292,16 +292,15 @@ class Enemy < GameObject
|
|
292
292
|
has_traits :collision_detection, :timer
|
293
293
|
attr_reader :radius
|
294
294
|
|
295
|
-
def
|
296
|
-
super
|
295
|
+
def setup
|
297
296
|
@velocity = options[:velocity] || 2
|
298
297
|
@health = options[:health] || 100
|
299
298
|
|
300
|
-
@anim = Animation.new(:file => "media/saucer.png", :size => [32,13], :delay => 100)
|
299
|
+
@anim = Animation.new(:file => "media/saucer.png", :size => [32,13], :delay => 100)
|
301
300
|
# @anim.retrofy
|
302
301
|
@image = @anim.first
|
303
302
|
|
304
|
-
self.factor = $window.factor
|
303
|
+
#self.factor = $window.factor
|
305
304
|
@radius = 5
|
306
305
|
@black = Color.new(0xFF000000)
|
307
306
|
@status == :default
|
@@ -410,7 +409,3 @@ end
|
|
410
409
|
|
411
410
|
|
412
411
|
Game.new.show
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
@@ -0,0 +1,291 @@
|
|
1
|
+
#
|
2
|
+
# Conway's game of life in Gosu/Chingu
|
3
|
+
# http://toastymofo.blogspot.com/2010/06/conways-game-of-life-in-ruby-gosu.html
|
4
|
+
#
|
5
|
+
# Developed by r.kachowski ( http://www.toastymofo.net/ )
|
6
|
+
# Additions by ippa ( http://ippa.se/gaming )
|
7
|
+
#
|
8
|
+
require 'chingu'
|
9
|
+
require 'gosu'
|
10
|
+
|
11
|
+
class Main < Chingu::Window
|
12
|
+
def initialize
|
13
|
+
super(640,480,false)
|
14
|
+
self.input={:esc=>:exit}
|
15
|
+
push_game_state(GameOfLife)
|
16
|
+
end
|
17
|
+
def draw
|
18
|
+
super
|
19
|
+
fill_rect([0,0,640,480], 0xffffffff, -2)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class GameOfLife < Chingu::GameState
|
24
|
+
CELL_SIZE = 4
|
25
|
+
@@tick =0
|
26
|
+
def initialize
|
27
|
+
super
|
28
|
+
@grid = generate_grid
|
29
|
+
|
30
|
+
self.input={ :left_mouse_button => :start_painting,
|
31
|
+
:released_left_mouse_button => :stop_painting,
|
32
|
+
:right_mouse_button => :start_erasing,
|
33
|
+
:releasedright_mouse_button => :stop_erasing,
|
34
|
+
:z => :reset,
|
35
|
+
:n => :update_grid,
|
36
|
+
:space => :toggle_running,
|
37
|
+
:left_arrow => :prev_pattern,
|
38
|
+
:right_arrow => :next_pattern
|
39
|
+
}
|
40
|
+
|
41
|
+
@pattern = :pixel
|
42
|
+
@pattern_nr = 0
|
43
|
+
@painting = false
|
44
|
+
@erasing = false
|
45
|
+
@running = false
|
46
|
+
|
47
|
+
@pattern_info = Chingu::Text.create(:x => 1, :y => 1, :size => 16, :color => Gosu::Color::BLACK)
|
48
|
+
update_pattern_info
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_pattern_info
|
52
|
+
@pattern_info.text = "Current pattern: #{@pattern}. Change patterns with left/right arrow keys."
|
53
|
+
end
|
54
|
+
|
55
|
+
def prev_pattern
|
56
|
+
@pattern_nr -= 1
|
57
|
+
@pattern_nr = PATTERNS.keys.size-1 if @pattern_nr < 0
|
58
|
+
@pattern = PATTERNS.keys[@pattern_nr]
|
59
|
+
update_pattern_info
|
60
|
+
end
|
61
|
+
|
62
|
+
def next_pattern
|
63
|
+
@pattern_nr += 1
|
64
|
+
@pattern_nr = 0 if @pattern_nr >= PATTERNS.keys.size
|
65
|
+
@pattern = PATTERNS.keys[@pattern_nr]
|
66
|
+
update_pattern_info
|
67
|
+
end
|
68
|
+
|
69
|
+
def draw_pattern_at_mouse(pattern = :pixel, to_grid = false)
|
70
|
+
start_x = ($window.mouse_x/CELL_SIZE).floor
|
71
|
+
y = ($window.mouse_y/CELL_SIZE).floor - 1
|
72
|
+
|
73
|
+
PATTERNS[pattern].each_line do |line|
|
74
|
+
x = start_x
|
75
|
+
line.each_char do |char|
|
76
|
+
@grid[x][y] = true if char == "o" && to_grid
|
77
|
+
draw_cell(x, y) if char == "o"
|
78
|
+
x += 1
|
79
|
+
end
|
80
|
+
|
81
|
+
y += 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def update
|
86
|
+
super
|
87
|
+
|
88
|
+
if @painting
|
89
|
+
draw_pattern_at_mouse(@pattern, true)
|
90
|
+
@painting = false if @running # Only put out pattern Once if game is running
|
91
|
+
else
|
92
|
+
draw_pattern_at_mouse(@pattern)
|
93
|
+
end
|
94
|
+
|
95
|
+
update_grid if @running
|
96
|
+
|
97
|
+
$window.caption = "Conway Generation #{@@tick}. Start/Stop with 'Space'. Run 1 generation with 'N'. Reset with 'Z'."
|
98
|
+
end
|
99
|
+
|
100
|
+
def draw
|
101
|
+
super
|
102
|
+
draw_grid
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def generate_grid
|
108
|
+
width = $window.width/CELL_SIZE
|
109
|
+
height = $window.height/CELL_SIZE
|
110
|
+
|
111
|
+
grid = Array.new(width)
|
112
|
+
col = Array.new(height)
|
113
|
+
col.map!{false}
|
114
|
+
grid.map!{Array.new(col)}
|
115
|
+
grid
|
116
|
+
end
|
117
|
+
|
118
|
+
def draw_grid
|
119
|
+
@grid.each_with_index do |a,x|
|
120
|
+
a.each_with_index do |c,y|
|
121
|
+
if c === true
|
122
|
+
$window.fill_rect([x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE],0xff000000,0)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def reset
|
129
|
+
@grid = generate_grid
|
130
|
+
@@tick = 0
|
131
|
+
@running = false
|
132
|
+
end
|
133
|
+
|
134
|
+
def update_grid
|
135
|
+
@new_grid = Marshal.load(Marshal.dump(@grid))
|
136
|
+
|
137
|
+
@grid.each_with_index do |a,x|
|
138
|
+
a.each_with_index do |c,y|
|
139
|
+
minus_x =x-1
|
140
|
+
minus_y = y-1
|
141
|
+
plus_x = x+1
|
142
|
+
plus_y = y+1
|
143
|
+
minus_x = @grid.length-1 if minus_x <0
|
144
|
+
minus_y = a.length-1 if minus_y <0
|
145
|
+
plus_y = 0 if plus_y >= a.length
|
146
|
+
plus_x = 0 if plus_x >= @grid.length
|
147
|
+
|
148
|
+
live_neighbours = 0
|
149
|
+
|
150
|
+
@grid[minus_x][y] == true ? live_neighbours+=1 : nil
|
151
|
+
@grid[plus_x][y] == true ? live_neighbours+=1 : nil
|
152
|
+
@grid[x][minus_y] == true ? live_neighbours+=1 : nil
|
153
|
+
@grid[x][plus_y] == true ? live_neighbours+=1 : nil
|
154
|
+
@grid[minus_x][plus_y] == true ? live_neighbours+=1 : nil
|
155
|
+
@grid[plus_x][minus_y] == true ? live_neighbours+=1 : nil
|
156
|
+
@grid[minus_x][minus_y] == true ? live_neighbours+=1 : nil
|
157
|
+
@grid[plus_x][plus_y] == true ? live_neighbours+=1 : nil
|
158
|
+
|
159
|
+
case live_neighbours
|
160
|
+
when 0..1 then @new_grid[x][y] = false
|
161
|
+
when 2 then @new_grid[x][y] = true if @new_grid[x][y] == true
|
162
|
+
when 3 then @new_grid[x][y] = true
|
163
|
+
when 4..8 then @new_grid[x][y] = false
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
@grid = @new_grid
|
170
|
+
@@tick+=1
|
171
|
+
end
|
172
|
+
|
173
|
+
def toggle_running
|
174
|
+
@running = !@running
|
175
|
+
end
|
176
|
+
|
177
|
+
def start_painting; @painting = true; end
|
178
|
+
def stop_painting; @painting = false; end
|
179
|
+
def start_erasing; @erasing = true; end
|
180
|
+
def stop_erasing; @erasing = false; end
|
181
|
+
|
182
|
+
def draw_cell(x, y, color = 0xaaff0000)
|
183
|
+
$window.fill_rect([x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE],0xaa0000ff,1)
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
PATTERNS = Hash.new
|
190
|
+
|
191
|
+
PATTERNS[:pixel] = %q{
|
192
|
+
o
|
193
|
+
}
|
194
|
+
|
195
|
+
#
|
196
|
+
# Spaceships
|
197
|
+
#
|
198
|
+
PATTERNS[:glider] = %q{
|
199
|
+
---o
|
200
|
+
-o-o
|
201
|
+
--oo
|
202
|
+
}
|
203
|
+
|
204
|
+
PATTERNS[:lightweight_spaceship] = %q{
|
205
|
+
-oooo
|
206
|
+
o---o
|
207
|
+
----o
|
208
|
+
o--o-
|
209
|
+
}
|
210
|
+
|
211
|
+
#
|
212
|
+
# Oscillators
|
213
|
+
#
|
214
|
+
PATTERNS[:blinker] = %q{
|
215
|
+
ooo
|
216
|
+
}
|
217
|
+
|
218
|
+
PATTERNS[:beacon] = %q{
|
219
|
+
-ooo
|
220
|
+
ooo-
|
221
|
+
}
|
222
|
+
|
223
|
+
PATTERNS[:toad] = %q{
|
224
|
+
oo--
|
225
|
+
o---
|
226
|
+
---o
|
227
|
+
--oo
|
228
|
+
}
|
229
|
+
|
230
|
+
PATTERNS[:pulsar] = %q{
|
231
|
+
---ooo---ooo--
|
232
|
+
--------------
|
233
|
+
-o----o-o----o
|
234
|
+
-o----o-o----o
|
235
|
+
-o----o-o----o
|
236
|
+
---ooo---ooo--
|
237
|
+
--------------
|
238
|
+
---ooo---ooo--
|
239
|
+
-o----o-o----o
|
240
|
+
-o----o-o----o
|
241
|
+
-o----o-o----o
|
242
|
+
--------------
|
243
|
+
---ooo---ooo--
|
244
|
+
}
|
245
|
+
|
246
|
+
#
|
247
|
+
# Guns
|
248
|
+
#
|
249
|
+
PATTERNS[:gospel_glider_gun] = %q{
|
250
|
+
------------------------o-----------
|
251
|
+
----------------------o-o-----------
|
252
|
+
------------oo------oo------------oo
|
253
|
+
-----------o---o----oo------------oo
|
254
|
+
oo--------o-----o---oo--------------
|
255
|
+
oo--------o---o-oo----o-o-----------
|
256
|
+
----------o-----o-------o-----------
|
257
|
+
-----------o---o--------------------
|
258
|
+
------------oo----------------------
|
259
|
+
}
|
260
|
+
|
261
|
+
PATTERNS[:block_laying_switch_engine] = %q{
|
262
|
+
----------o-o--
|
263
|
+
oo-------o-----
|
264
|
+
oo--------o--o-
|
265
|
+
------------ooo
|
266
|
+
}
|
267
|
+
|
268
|
+
|
269
|
+
|
270
|
+
#
|
271
|
+
# Long lived patterns
|
272
|
+
#
|
273
|
+
PATTERNS[:rpentomino] = %q{
|
274
|
+
--oo
|
275
|
+
-oo
|
276
|
+
--o
|
277
|
+
}
|
278
|
+
|
279
|
+
PATTERNS[:diehard] = %q{
|
280
|
+
oo---o-o
|
281
|
+
oo----o-
|
282
|
+
------o-
|
283
|
+
}
|
284
|
+
|
285
|
+
PATTERNS[:acorn] = %q{
|
286
|
+
--o-----
|
287
|
+
----o---
|
288
|
+
-oo--ooo
|
289
|
+
}
|
290
|
+
|
291
|
+
Main.new.show
|