graphics 1.0.0b1 → 1.0.0b4
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +30 -0
- data/Manifest.txt +39 -7
- data/README.rdoc +48 -4
- data/Rakefile +8 -2
- data/examples/boid.rb +9 -18
- data/examples/bounce.rb +15 -23
- data/examples/canvas.rb +75 -0
- data/examples/collision.rb +6 -6
- data/examples/demo.rb +5 -7
- data/examples/editor.rb +12 -9
- data/examples/fluid.rb +2 -3
- data/examples/fluid2.rb +1 -1
- data/examples/{lito2.rb → gol.rb} +0 -0
- data/examples/{zenspider4.rb → gol2.rb} +0 -0
- data/examples/logo.rb +4 -7
- data/examples/maze.rb +136 -0
- data/examples/tank.rb +10 -11
- data/examples/tank2.rb +12 -17
- data/examples/targeting.rb +1 -1
- data/examples/vants.rb +1 -1
- data/examples/walker.rb +3 -12
- data/examples/walker2.rb +197 -0
- data/examples/zombies.rb +31 -35
- data/ext/sdl/extconf.rb +31 -0
- data/ext/sdl/sdl.c +1067 -0
- data/ext/sdl/sge/INSTALL +72 -0
- data/ext/sdl/sge/LICENSE +504 -0
- data/ext/sdl/sge/Makefile +83 -0
- data/ext/sdl/sge/Makefile.conf +63 -0
- data/ext/sdl/sge/README +219 -0
- data/ext/sdl/sge/Todo +7 -0
- data/ext/sdl/sge/WhatsNew +224 -0
- data/ext/sdl/sge/sge.h +31 -0
- data/ext/sdl/sge/sge_blib.cpp +1939 -0
- data/ext/sdl/sge/sge_blib.h +68 -0
- data/ext/sdl/sge/sge_bm_text.cpp +451 -0
- data/ext/sdl/sge/sge_bm_text.h +71 -0
- data/ext/sdl/sge/sge_collision.cpp +388 -0
- data/ext/sdl/sge/sge_collision.h +54 -0
- data/ext/sdl/sge/sge_config.h +6 -0
- data/ext/sdl/sge/sge_internal.h +152 -0
- data/ext/sdl/sge/sge_misc.cpp +92 -0
- data/ext/sdl/sge/sge_misc.h +37 -0
- data/ext/sdl/sge/sge_primitives.cpp +2516 -0
- data/ext/sdl/sge/sge_primitives.h +111 -0
- data/ext/sdl/sge/sge_rotation.cpp +683 -0
- data/ext/sdl/sge/sge_rotation.h +46 -0
- data/ext/sdl/sge/sge_shape.cpp +762 -0
- data/ext/sdl/sge/sge_shape.h +365 -0
- data/ext/sdl/sge/sge_surface.cpp +1090 -0
- data/ext/sdl/sge/sge_surface.h +100 -0
- data/ext/sdl/sge/sge_textpp.cpp +785 -0
- data/ext/sdl/sge/sge_textpp.h +270 -0
- data/ext/sdl/sge/sge_tt_text.cpp +1456 -0
- data/ext/sdl/sge/sge_tt_text.h +114 -0
- data/graphics_setup.sh +26 -0
- data/lib/graphics.rb +1 -1
- data/lib/graphics/body.rb +50 -3
- data/lib/graphics/extensions.rb +13 -7
- data/lib/graphics/simulation.rb +126 -46
- data/test/test_graphics.rb +52 -12
- data/test/test_sdl.rb +1 -0
- metadata +54 -23
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/examples/lito.rb +0 -108
- data/examples/zenspider1.rb +0 -93
- data/examples/zenspider2.rb +0 -123
- data/examples/zenspider3.rb +0 -104
- data/rubysdl_setup.sh +0 -34
data/examples/demo.rb
CHANGED
@@ -34,8 +34,6 @@ class Demo < Graphics::Simulation
|
|
34
34
|
super 800, 800, 16, "Boid"
|
35
35
|
self.ball = Ball.new self
|
36
36
|
|
37
|
-
r = color[:red]
|
38
|
-
|
39
37
|
self.img = sprite 10, 10 do
|
40
38
|
circle 5, 5, 5, :white, :filled
|
41
39
|
end
|
@@ -64,12 +62,14 @@ class Demo < Graphics::Simulation
|
|
64
62
|
|
65
63
|
circle 225, 50, 10, :white
|
66
64
|
|
67
|
-
ellipse 250, 50, 10,
|
65
|
+
ellipse 250, 50, 10, 20, :white
|
68
66
|
|
69
67
|
bezier 275, 50, 275, 100, 285, 0, 300, 50, :white
|
70
68
|
|
71
69
|
rect 300, 25, 50, 50, :white
|
72
|
-
|
70
|
+
|
71
|
+
blit img, 325, 50 # centered
|
72
|
+
put img, 335, 50 # cornered
|
73
73
|
|
74
74
|
text "blah", 350, 50, :white
|
75
75
|
|
@@ -85,6 +85,4 @@ class Demo < Graphics::Simulation
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
if $0 == __FILE__
|
89
|
-
Demo.new.run
|
90
|
-
end
|
88
|
+
Demo.new.run if $0 == __FILE__
|
data/examples/editor.rb
CHANGED
@@ -16,9 +16,14 @@ class Editor < Graphics::Simulation
|
|
16
16
|
self.lines = []
|
17
17
|
end
|
18
18
|
|
19
|
+
def initialize_keys
|
20
|
+
# no super
|
21
|
+
add_key_handler(:ESCAPE) { exit }
|
22
|
+
end
|
23
|
+
|
19
24
|
def handle_event e, n
|
20
25
|
case e
|
21
|
-
when SDL::Event::
|
26
|
+
when SDL::Event::Keydown then
|
22
27
|
if e.mod & (SDL::Key::MOD_LCTRL | SDL::Key::MOD_RCTRL) != 0 then
|
23
28
|
case e.sym.chr
|
24
29
|
when "t" then
|
@@ -55,16 +60,14 @@ class Editor < Graphics::Simulation
|
|
55
60
|
end
|
56
61
|
|
57
62
|
def draw_overlay
|
58
|
-
|
59
|
-
lines.each_with_index do |l, i|
|
60
|
-
text l, 10, ((lines.size-i)*font.height), :gray
|
61
|
-
end
|
63
|
+
return unless overlay?
|
62
64
|
|
63
|
-
|
65
|
+
lines.each_with_index do |l, i|
|
66
|
+
text l, 10, ((lines.size-i)*font.height), :gray
|
64
67
|
end
|
68
|
+
|
69
|
+
text "> #{s}_", 10, 0, :white
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
if $0 == __FILE__
|
69
|
-
Editor.new.run
|
70
|
-
end
|
73
|
+
Editor.new.run if $0 == __FILE__
|
data/examples/fluid.rb
CHANGED
@@ -111,15 +111,14 @@ class SPH
|
|
111
111
|
# Calculate fluid density around each particle
|
112
112
|
particles.each do |particle|
|
113
113
|
particles.each do |neighbor|
|
114
|
-
|
115
114
|
# If particles are close together, density increases
|
116
115
|
distance = particle.position - neighbor.position
|
117
116
|
|
118
|
-
if distance.magnitude < H
|
117
|
+
if distance.magnitude < H then
|
118
|
+
# Particles are close enough to matter
|
119
119
|
particle.density += MASS * weight(distance, H)
|
120
120
|
end
|
121
121
|
end
|
122
|
-
# p particle.density if particle.density > 2*H
|
123
122
|
end
|
124
123
|
end
|
125
124
|
|
data/examples/fluid2.rb
CHANGED
File without changes
|
File without changes
|
data/examples/logo.rb
CHANGED
@@ -34,9 +34,8 @@ class Turtle < Graphics::Body
|
|
34
34
|
self.a += $1.to_i
|
35
35
|
when /f (\d+)/ then
|
36
36
|
dist = $1.to_i
|
37
|
-
|
38
|
-
|
39
|
-
end
|
37
|
+
|
38
|
+
w.angle x, y, a, dist, :white if pen
|
40
39
|
move_by a, dist
|
41
40
|
else
|
42
41
|
src.delete line
|
@@ -51,7 +50,7 @@ class Turtle < Graphics::Body
|
|
51
50
|
p2 = w.project(x, y, a+90, 5)
|
52
51
|
p3 = w.project(x, y, a-90, 5)
|
53
52
|
|
54
|
-
polygon p1, p2, p3, :green
|
53
|
+
w.polygon p1, p2, p3, :green
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
@@ -68,6 +67,4 @@ class Logo < Editor
|
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
71
|
-
if $0 == __FILE__
|
72
|
-
Logo.new.run
|
73
|
-
end
|
70
|
+
Logo.new.run if $0 == __FILE__
|
data/examples/maze.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require "graphics"
|
5
|
+
|
6
|
+
##
|
7
|
+
# All code here is adapted from Jamis Buck's Mazes for Programmers.
|
8
|
+
# Used with Permission.
|
9
|
+
|
10
|
+
class Cell
|
11
|
+
attr_reader :row, :column
|
12
|
+
attr_accessor :north, :south, :east, :west
|
13
|
+
|
14
|
+
def initialize(row, column)
|
15
|
+
@row, @column = row, column
|
16
|
+
@links = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def link(cell, bidi=true)
|
20
|
+
@links[cell] = true
|
21
|
+
cell.link(self, false) if bidi
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def linked?(cell)
|
26
|
+
@links.key?(cell)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Grid
|
31
|
+
attr_reader :rows, :columns, :w
|
32
|
+
|
33
|
+
def initialize(rows, columns, w)
|
34
|
+
@rows = rows
|
35
|
+
@columns = columns
|
36
|
+
@w = w
|
37
|
+
|
38
|
+
@grid = prepare_grid
|
39
|
+
configure_cells
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare_grid
|
43
|
+
Array.new(rows) do |row|
|
44
|
+
Array.new(columns) do |column|
|
45
|
+
Cell.new(row, column)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def configure_cells
|
51
|
+
each_cell do |cell|
|
52
|
+
row, col = cell.row, cell.column
|
53
|
+
|
54
|
+
cell.north = self[row - 1, col]
|
55
|
+
cell.south = self[row + 1, col]
|
56
|
+
cell.west = self[row, col - 1]
|
57
|
+
cell.east = self[row, col + 1]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def [](row, column)
|
62
|
+
return nil unless row.between?(0, @rows - 1)
|
63
|
+
return nil unless column.between?(0, @grid[row].count - 1)
|
64
|
+
@grid[row][column]
|
65
|
+
end
|
66
|
+
|
67
|
+
def each_row
|
68
|
+
@grid.each do |row|
|
69
|
+
yield row
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def each_cell
|
74
|
+
each_row do |row|
|
75
|
+
row.each do |cell|
|
76
|
+
yield cell if cell
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def draw n
|
82
|
+
cell_size = w.w / columns
|
83
|
+
|
84
|
+
each_cell do |cell|
|
85
|
+
x1 = cell_size * cell.column
|
86
|
+
y1 = cell_size * cell.row
|
87
|
+
x2 = cell_size * (cell.column + 1)
|
88
|
+
y2 = cell_size * (cell.row + 1)
|
89
|
+
|
90
|
+
w.line x1, y1, x2, y1, :white unless cell.north
|
91
|
+
w.line x1, y1, x1, y2, :white unless cell.west
|
92
|
+
w.line x2, y1, x2, y2, :white unless cell.linked? cell.east
|
93
|
+
w.line x1, y2, x2, y2, :white unless cell.linked? cell.south
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class BinaryTree
|
99
|
+
def self.on(grid)
|
100
|
+
grid.each_cell do |cell|
|
101
|
+
neighbors = []
|
102
|
+
neighbors << cell.north if cell.north
|
103
|
+
neighbors << cell.east if cell.east
|
104
|
+
|
105
|
+
index = rand(neighbors.length)
|
106
|
+
neighbor = neighbors[index]
|
107
|
+
|
108
|
+
cell.link(neighbor) if neighbor
|
109
|
+
end
|
110
|
+
|
111
|
+
grid
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class Maze < Graphics::Simulation
|
116
|
+
attr_accessor :grid
|
117
|
+
|
118
|
+
def initialize
|
119
|
+
super 800, 800
|
120
|
+
|
121
|
+
self.grid = Grid.new 50, 50, self
|
122
|
+
BinaryTree.on grid
|
123
|
+
end
|
124
|
+
|
125
|
+
def update n
|
126
|
+
# do nothing
|
127
|
+
end
|
128
|
+
|
129
|
+
def draw n
|
130
|
+
clear
|
131
|
+
|
132
|
+
grid.draw n
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
Maze.new.run if $0 == __FILE__
|
data/examples/tank.rb
CHANGED
@@ -123,8 +123,6 @@ class TargetSimulation < Graphics::Simulation
|
|
123
123
|
def initialize
|
124
124
|
super 640, 640, 16, "Target Practice"
|
125
125
|
|
126
|
-
SDL::Key.enable_key_repeat 50, 10
|
127
|
-
|
128
126
|
self.tank = Tank.new self
|
129
127
|
self.bullets = []
|
130
128
|
|
@@ -132,15 +130,16 @@ class TargetSimulation < Graphics::Simulation
|
|
132
130
|
self.turret_img = image "resources/images/turret.png"
|
133
131
|
end
|
134
132
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
tank.
|
139
|
-
tank.
|
140
|
-
tank.
|
141
|
-
tank.
|
142
|
-
tank.
|
143
|
-
tank.
|
133
|
+
def initialize_keys
|
134
|
+
super
|
135
|
+
|
136
|
+
add_key_handler(:RIGHT) { tank.turn_right }
|
137
|
+
add_key_handler(:LEFT) { tank.turn_left }
|
138
|
+
add_key_handler(:UP) { tank.accelerate }
|
139
|
+
add_key_handler(:DOWN) { tank.decelerate }
|
140
|
+
add_key_handler(:SEMICOLON) { tank.aim_left }
|
141
|
+
add_key_handler(:Q, :remove){ tank.aim_right }
|
142
|
+
add_key_handler(:SPACE) { tank.fire }
|
144
143
|
end
|
145
144
|
|
146
145
|
def update n
|
data/examples/tank2.rb
CHANGED
@@ -97,13 +97,9 @@ class TargetSimulation < Graphics::Simulation
|
|
97
97
|
def initialize
|
98
98
|
super 640, 640, 16, "Target Practice"
|
99
99
|
|
100
|
-
SDL::Key.enable_key_repeat 50, 10
|
101
|
-
|
102
100
|
self.tank = Tank.new w/2, h/2
|
103
101
|
self.bullets = []
|
104
102
|
|
105
|
-
screen.set_alpha SDL::SRCALPHA, 128
|
106
|
-
|
107
103
|
self.body_img = sprite 40, 30 do
|
108
104
|
rect 0, 0, 39, 29, :white
|
109
105
|
rect 0, 4, 39, 21, :white
|
@@ -120,15 +116,16 @@ class TargetSimulation < Graphics::Simulation
|
|
120
116
|
end
|
121
117
|
end
|
122
118
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
tank.
|
127
|
-
tank.
|
128
|
-
tank.
|
129
|
-
tank.
|
130
|
-
tank.
|
131
|
-
|
119
|
+
def initialize_keys
|
120
|
+
super
|
121
|
+
|
122
|
+
add_key_handler(:RIGHT) { tank.turn_right }
|
123
|
+
add_key_handler(:LEFT) { tank.turn_left }
|
124
|
+
add_key_handler(:UP) { tank.accelerate }
|
125
|
+
add_key_handler(:DOWN) { tank.decelerate }
|
126
|
+
add_key_handler(:SEMICOLON) { tank.aim_left }
|
127
|
+
add_key_handler(:Q, :remove){ tank.aim_right }
|
128
|
+
add_key_handler(:SPACE) { fire }
|
132
129
|
end
|
133
130
|
|
134
131
|
def fire
|
@@ -152,13 +149,11 @@ class TargetSimulation < Graphics::Simulation
|
|
152
149
|
fps n
|
153
150
|
end
|
154
151
|
|
155
|
-
AA = SDL::Surface::TRANSFORM_AA
|
156
|
-
|
157
152
|
def draw_tank
|
158
153
|
x, y, a, t = tank.x, tank.y, tank.angle, tank.turret
|
159
154
|
|
160
|
-
blit body_img, x, y, a
|
161
|
-
blit turret_img, x, y, t
|
155
|
+
blit body_img, x, y, a
|
156
|
+
blit turret_img, x, y, t
|
162
157
|
|
163
158
|
debug "%3d @ %.2f @ %d", tank.angle, tank.speed, tank.energy
|
164
159
|
end
|
data/examples/targeting.rb
CHANGED
data/examples/vants.rb
CHANGED
data/examples/walker.rb
CHANGED
@@ -10,9 +10,7 @@ class Person < Graphics::Body
|
|
10
10
|
D_M = 0.25
|
11
11
|
M_M = 5.0
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
attr_accessor :trail, :attack
|
13
|
+
attr_accessor :trail
|
16
14
|
|
17
15
|
def initialize w
|
18
16
|
super
|
@@ -21,7 +19,6 @@ class Person < Graphics::Body
|
|
21
19
|
|
22
20
|
self.a = random_angle
|
23
21
|
self.ga = random_angle
|
24
|
-
self.attack = false
|
25
22
|
end
|
26
23
|
|
27
24
|
def update
|
@@ -43,16 +40,10 @@ class Person < Graphics::Body
|
|
43
40
|
def draw
|
44
41
|
trail.draw
|
45
42
|
|
46
|
-
if attack then
|
47
|
-
w.angle x, y, a-45, 50, :yellow
|
48
|
-
w.angle x, y, a, 60, :red
|
49
|
-
w.angle x, y, a+45, 50, :yellow
|
50
|
-
end
|
51
|
-
|
52
43
|
w.angle x, y, ga, 60, :red
|
53
44
|
|
54
45
|
# the blit looks HORRIBLE when rotated... dunno why
|
55
|
-
w.blit w.body_img, x, y
|
46
|
+
w.blit w.body_img, x, y
|
56
47
|
end
|
57
48
|
|
58
49
|
def turn_towards_goal
|
@@ -68,7 +59,7 @@ class Person < Graphics::Body
|
|
68
59
|
end
|
69
60
|
|
70
61
|
def collide_with? other
|
71
|
-
w.cmap.
|
62
|
+
w.cmap.check(x, y, w.cmap, other.x, other.y) != nil
|
72
63
|
end
|
73
64
|
|
74
65
|
def collide
|
data/examples/walker2.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# srand 42
|
4
|
+
|
5
|
+
require "graphics"
|
6
|
+
require "graphics/trail"
|
7
|
+
|
8
|
+
class Person < Graphics::Body
|
9
|
+
COUNT = 40
|
10
|
+
|
11
|
+
D_A = 5.0
|
12
|
+
D_M = 0.25
|
13
|
+
M_M = 5.0
|
14
|
+
|
15
|
+
VISIBILITY = 100
|
16
|
+
ATTACK_DISTANCE = 6 * 2
|
17
|
+
VISIBILITY_SQ = VISIBILITY**2
|
18
|
+
ATTACK_DISTANCE_SQ = ATTACK_DISTANCE**2
|
19
|
+
|
20
|
+
attr_accessor :attack, :debug
|
21
|
+
alias attack? attack
|
22
|
+
alias debug? debug
|
23
|
+
|
24
|
+
def initialize w
|
25
|
+
super
|
26
|
+
|
27
|
+
self.a = random_angle
|
28
|
+
self.ga = random_angle
|
29
|
+
self.attack = false
|
30
|
+
self.debug = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
return update_attack if attack?
|
35
|
+
|
36
|
+
normal_update
|
37
|
+
end
|
38
|
+
|
39
|
+
def normal_update
|
40
|
+
turn_towards_goal
|
41
|
+
possibly_change_goal
|
42
|
+
|
43
|
+
# accelerate
|
44
|
+
# move
|
45
|
+
|
46
|
+
wrap
|
47
|
+
end
|
48
|
+
|
49
|
+
def near? p
|
50
|
+
distance_to_squared(p) < VISIBILITY_SQ
|
51
|
+
end
|
52
|
+
|
53
|
+
def visible? o
|
54
|
+
pa = self.angle_to o
|
55
|
+
da = (pa - self.a + 90).degrees
|
56
|
+
da.between?(75, 150)
|
57
|
+
end
|
58
|
+
|
59
|
+
def nearby
|
60
|
+
@nearby ||= begin
|
61
|
+
all_but_me = w.ps.reject(&:attack?)
|
62
|
+
nearby = all_but_me.find_all { |p| self.near? p }
|
63
|
+
visible = nearby.select { |p| self.visible? p }
|
64
|
+
visible.sort_by { |p| self.distance_to_squared(p) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_attack
|
69
|
+
@nearby = nil
|
70
|
+
|
71
|
+
nearby.each do |p|
|
72
|
+
dist = self.distance_to_squared(p)
|
73
|
+
|
74
|
+
if dist <= ATTACK_DISTANCE_SQ then
|
75
|
+
p.kill
|
76
|
+
else
|
77
|
+
self.ga = self.angle_to(nearby.first)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
normal_update
|
82
|
+
end
|
83
|
+
|
84
|
+
def kill
|
85
|
+
w.ps.delete self unless attack?
|
86
|
+
end
|
87
|
+
|
88
|
+
def accelerate
|
89
|
+
max = attack ? 1.1 * M_M : M_M
|
90
|
+
self.m += D_M unless m >= max
|
91
|
+
end
|
92
|
+
|
93
|
+
def draw
|
94
|
+
if debug? and attack? then
|
95
|
+
w.angle x, y, a-75, VISIBILITY, :yellow
|
96
|
+
w.angle x, y, a-25, VISIBILITY, :yellow
|
97
|
+
w.angle x, y, a+25, VISIBILITY, :yellow
|
98
|
+
w.angle x, y, a+75, VISIBILITY, :yellow
|
99
|
+
nearby.each do |o|
|
100
|
+
w.line x, y, o.x, o.y, :yellow
|
101
|
+
end
|
102
|
+
# sleep 0.25 unless nearby.empty?
|
103
|
+
end
|
104
|
+
|
105
|
+
w.angle x, y, a, 20, :green
|
106
|
+
w.angle x, y, ga, 10, :red
|
107
|
+
|
108
|
+
# the blit looks HORRIBLE when rotated... dunno why
|
109
|
+
w.blit w.body_img, x, y
|
110
|
+
w.circle x, y, 5, :red, :filled if attack?
|
111
|
+
end
|
112
|
+
|
113
|
+
def turn_towards_goal
|
114
|
+
turn a.relative_angle(ga, D_A)
|
115
|
+
end
|
116
|
+
|
117
|
+
def change_goal
|
118
|
+
self.ga = (a + random_turn(180)).degrees
|
119
|
+
end
|
120
|
+
|
121
|
+
def possibly_change_goal
|
122
|
+
close = ga.close_to?(a)
|
123
|
+
change = close && 1 =~ 25
|
124
|
+
change_goal if change
|
125
|
+
end
|
126
|
+
|
127
|
+
def collide_with? other
|
128
|
+
w.cmap.check(x, y, w.cmap, other.x, other.y) != nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def collide b
|
132
|
+
return b.kill if self.attack?
|
133
|
+
self.a = (a + 180).degrees
|
134
|
+
change_goal
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class WalkerSimulation < Graphics::Simulation
|
139
|
+
attr_accessor :ps, :body_img, :cmap
|
140
|
+
|
141
|
+
def initialize
|
142
|
+
super 850, 850, 16, "Walker"
|
143
|
+
|
144
|
+
self.ps = populate Person, 2
|
145
|
+
|
146
|
+
# 5.times do |n|
|
147
|
+
# ps[n].attack = true
|
148
|
+
# end
|
149
|
+
|
150
|
+
ps[0].debug = true
|
151
|
+
ps[0].attack = true
|
152
|
+
|
153
|
+
ps.first.x = w/2
|
154
|
+
ps.first.y = h/2
|
155
|
+
ps.first.a = 90
|
156
|
+
ps.first.ga = 90
|
157
|
+
|
158
|
+
ps.last.x = w/2 + 50
|
159
|
+
ps.last.y = h/2 + 50
|
160
|
+
ps.last.a = 0
|
161
|
+
ps.last.ga = 0
|
162
|
+
|
163
|
+
self.body_img = sprite 20, 20 do
|
164
|
+
circle 10, 10, 5, :white, :filled
|
165
|
+
end
|
166
|
+
|
167
|
+
self.cmap = body_img.make_collision_map
|
168
|
+
end
|
169
|
+
|
170
|
+
def update n
|
171
|
+
ps.each(&:update)
|
172
|
+
detect_collisions(ps).each do |a, b|
|
173
|
+
a.collide b
|
174
|
+
end
|
175
|
+
|
176
|
+
exit if ps.all?(&:attack?)
|
177
|
+
end
|
178
|
+
|
179
|
+
def draw n
|
180
|
+
clear
|
181
|
+
|
182
|
+
ps.each(&:draw)
|
183
|
+
|
184
|
+
debug "#{ps.size}"
|
185
|
+
fps n
|
186
|
+
end
|
187
|
+
|
188
|
+
def detect_collisions sprites
|
189
|
+
collisions = []
|
190
|
+
sprites.combination(2).each do |a, b|
|
191
|
+
collisions << [a, b] if a.collide_with? b
|
192
|
+
end
|
193
|
+
collisions
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
WalkerSimulation.new.run
|