zyps 0.7.2 → 0.7.3
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/README.txt +1 -1
- data/README_windows.txt +55 -0
- data/bin/zyps +21 -7
- data/bin/zyps_demo +1 -1
- data/lib/zyps/actions.rb +1 -1
- data/lib/zyps/conditions.rb +1 -1
- data/lib/zyps/environmental_factors.rb +1 -1
- data/lib/zyps/remote.rb +1 -1
- data/lib/zyps/views/canvas/wx.rb +1 -1
- data/lib/zyps/views/trails.rb +8 -13
- data/lib/zyps.rb +1 -1
- data/test/test_zyps.rb +1 -1
- data/test/zyps/test_actions.rb +1 -1
- data/test/zyps/test_conditions.rb +1 -1
- data/test/zyps/test_environmental_factors.rb +1 -1
- data/test/zyps/test_remote.rb +1 -1
- metadata +3 -4
- data/bin/zyps-175 +0 -514
- data/lib/zyps/views/canvas/gtk2.rb +0 -152
data/README.txt
CHANGED
data/README_windows.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
About Zyps
|
2
|
+
----------
|
3
|
+
|
4
|
+
Zyps are small creatures with minds of their own. You can
|
5
|
+
choose whether you want a Zyp to chase the others, run away
|
6
|
+
from them, or eat them for lunch. Then drop it in the
|
7
|
+
midst of the crowd, and see what it does. If it's cool,
|
8
|
+
create a dozen more just like it. If not, choose from the
|
9
|
+
many other actions and make something else.
|
10
|
+
|
11
|
+
|
12
|
+
== Development
|
13
|
+
|
14
|
+
This is the demonstration program for the Zyps game library
|
15
|
+
for Ruby. With the library, you can easily make your own
|
16
|
+
actions, or even your own games. You can get the source
|
17
|
+
code from the site at:
|
18
|
+
|
19
|
+
http://jay.mcgavren.com/zyps
|
20
|
+
|
21
|
+
|
22
|
+
== Thanks
|
23
|
+
|
24
|
+
Glen Franta, Scott McGinty, and so many other math,
|
25
|
+
science, and computer science teachers whose names I've
|
26
|
+
forgotten. Nothing I do today would be possible without
|
27
|
+
your efforts so long ago.
|
28
|
+
|
29
|
+
Alex Fenton and Mario Steele for wxRuby advice.
|
30
|
+
|
31
|
+
My lovely wife, Diana, for patience and usability testing.
|
32
|
+
|
33
|
+
|
34
|
+
== Author
|
35
|
+
|
36
|
+
Copyright 2007-2008 Jay McGavren, jay@mcgavren.com
|
37
|
+
|
38
|
+
|
39
|
+
== License
|
40
|
+
|
41
|
+
Zyps is free software; you can redistribute it and/or
|
42
|
+
modify it under the terms of the GNU Lesser General Public
|
43
|
+
License as published by the Free Software Foundation;
|
44
|
+
either version 3 of the License, or (at your option) any
|
45
|
+
later version.
|
46
|
+
|
47
|
+
This program is distributed in the hope that it will be
|
48
|
+
useful, but WITHOUT ANY WARRANTY; without even the implied
|
49
|
+
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
50
|
+
PURPOSE. See the GNU General Public License for more
|
51
|
+
details.
|
52
|
+
|
53
|
+
You should have received a copy of the GNU Lesser General
|
54
|
+
Public License along with this program. If not, see
|
55
|
+
<http://www.gnu.org/licenses/>.
|
data/bin/zyps
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/local/bin/ruby
|
2
2
|
|
3
|
-
# Copyright 2007 Jay McGavren, jay@mcgavren.com.
|
3
|
+
# Copyright 2007-2008 Jay McGavren, jay@mcgavren.com.
|
4
4
|
#
|
5
5
|
# This file is part of Zyps.
|
6
6
|
#
|
@@ -131,9 +131,6 @@ class Application < Wx::App
|
|
131
131
|
@controls.length_slider.evt_slider(@controls.length_slider.get_id) do |event|
|
132
132
|
@view.trail_length = @controls.length_slider.value
|
133
133
|
end
|
134
|
-
@controls.trails_flag.evt_checkbox(@controls.trails_flag.get_id) do |event|
|
135
|
-
@view.erase_flag = ! @controls.trails_flag.is_checked
|
136
|
-
end
|
137
134
|
frame.sizer.add(@controls, 0, Wx::GROW)
|
138
135
|
|
139
136
|
@log.debug "Create an environment, and link it to the view."
|
@@ -182,6 +179,12 @@ class Application < Wx::App
|
|
182
179
|
end
|
183
180
|
#Update environment.
|
184
181
|
@environment.interact
|
182
|
+
#If there are no Creatures, show instructions on creating them.
|
183
|
+
if @environment.objects.empty?
|
184
|
+
@view.canvas.buffer.draw do |dc|
|
185
|
+
render_text_centered("Click and drag the mouse here to create creatures.", dc)
|
186
|
+
end
|
187
|
+
end
|
185
188
|
#Update viewing area.
|
186
189
|
@drawing_area.paint do |dc|
|
187
190
|
#Copy from View to drawing area.
|
@@ -377,6 +380,19 @@ EOD
|
|
377
380
|
end
|
378
381
|
|
379
382
|
|
383
|
+
#Draw the given text in the center of the given Wx::DC.
|
384
|
+
def render_text_centered(string, dc)
|
385
|
+
dc.text_foreground = Wx::Colour.new(255, 255, 255)
|
386
|
+
dc.text_background = Wx::Colour.new(0, 0, 0)
|
387
|
+
text_size = dc.get_text_extent(string)
|
388
|
+
dc.draw_text(
|
389
|
+
string,
|
390
|
+
dc.size.width / 2 - (text_size[0] / 2),
|
391
|
+
dc.size.height / 2 - (text_size[1] / 2)
|
392
|
+
)
|
393
|
+
end
|
394
|
+
|
395
|
+
|
380
396
|
end
|
381
397
|
|
382
398
|
|
@@ -491,7 +507,6 @@ class ControlPanel < Wx::Panel
|
|
491
507
|
attr_accessor :breed_flag
|
492
508
|
attr_accessor :eat_flag
|
493
509
|
attr_accessor :length_slider
|
494
|
-
attr_accessor :trails_flag
|
495
510
|
attr_accessor :clear_button
|
496
511
|
|
497
512
|
|
@@ -515,7 +530,6 @@ class ControlPanel < Wx::Panel
|
|
515
530
|
add_label(display_controls, :label => "Length")
|
516
531
|
@length_slider = add_slider(display_controls, :min_value => 2, :max_value => 100)
|
517
532
|
@length_slider.value = 5
|
518
|
-
@trails_flag = add_check_box(display_controls, :label => "Trails")
|
519
533
|
|
520
534
|
environment_controls = add_panel(self, :proportion => 1)
|
521
535
|
add_label(environment_controls, :label => "Environment")
|
@@ -688,7 +702,7 @@ class CreatureGenerator
|
|
688
702
|
)
|
689
703
|
|
690
704
|
#Set up actions and merge colors according to selected behaviors.
|
691
|
-
color = Color.new(0.
|
705
|
+
color = Color.new(0.5, 0.5, 0.5)
|
692
706
|
if options[:turn]
|
693
707
|
color.blue += 1
|
694
708
|
creature.behaviors << Behavior.new(
|
data/bin/zyps_demo
CHANGED
data/lib/zyps/actions.rb
CHANGED
data/lib/zyps/conditions.rb
CHANGED
data/lib/zyps/remote.rb
CHANGED
data/lib/zyps/views/canvas/wx.rb
CHANGED
data/lib/zyps/views/trails.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2007 Jay McGavren, jay@mcgavren.com.
|
1
|
+
# Copyright 2007-2008 Jay McGavren, jay@mcgavren.com.
|
2
2
|
#
|
3
3
|
# This file is part of Zyps.
|
4
4
|
#
|
@@ -40,19 +40,16 @@ class TrailsView
|
|
40
40
|
# :width => 600
|
41
41
|
# :height => 400
|
42
42
|
# :trail_length => 5
|
43
|
-
# :erase_flag => true
|
44
43
|
def initialize (options = {})
|
45
44
|
|
46
45
|
options = {
|
47
46
|
:width => 600,
|
48
47
|
:height => 400,
|
49
48
|
:trail_length => 5,
|
50
|
-
:erase_flag => true
|
51
49
|
}.merge(options)
|
52
50
|
@width = options[:width]
|
53
51
|
@height = options[:height]
|
54
52
|
@trail_length = options[:trail_length]
|
55
|
-
@erase_flag = options[:erase_flag]
|
56
53
|
@canvas = options[:canvas]
|
57
54
|
|
58
55
|
#Set canvas's size to match view's.
|
@@ -83,15 +80,13 @@ class TrailsView
|
|
83
80
|
#GameObject.size will be used as the line thickness at the object's head, diminishing to 1 at the tail.
|
84
81
|
def update(environment)
|
85
82
|
|
86
|
-
#Clear
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
)
|
94
|
-
end
|
83
|
+
#Clear view.
|
84
|
+
@canvas.draw_rectangle(
|
85
|
+
:color => Color.new(0, 0, 0),
|
86
|
+
:filled => true,
|
87
|
+
:x => 0, :y => 0,
|
88
|
+
:width => @width, :height => @height
|
89
|
+
)
|
95
90
|
|
96
91
|
#For each GameObject in the environment:
|
97
92
|
environment.objects.each do |object|
|
data/lib/zyps.rb
CHANGED
data/test/test_zyps.rb
CHANGED
data/test/zyps/test_actions.rb
CHANGED
data/test/zyps/test_remote.rb
CHANGED
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: zyps
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.7.
|
7
|
-
date: 2008-
|
6
|
+
version: 0.7.3
|
7
|
+
date: 2008-02-04 00:00:00 -07:00
|
8
8
|
summary: A game library for Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,8 +32,8 @@ files:
|
|
32
32
|
- COPYING.LESSER.txt
|
33
33
|
- COPYING.txt
|
34
34
|
- README.txt
|
35
|
+
- README_windows.txt
|
35
36
|
- bin/zyps
|
36
|
-
- bin/zyps-175
|
37
37
|
- bin/zyps_demo
|
38
38
|
- lib/zyps
|
39
39
|
- lib/zyps/actions.rb
|
@@ -42,7 +42,6 @@ files:
|
|
42
42
|
- lib/zyps/remote.rb
|
43
43
|
- lib/zyps/views
|
44
44
|
- lib/zyps/views/canvas
|
45
|
-
- lib/zyps/views/canvas/gtk2.rb
|
46
45
|
- lib/zyps/views/canvas/wx.rb
|
47
46
|
- lib/zyps/views/trails.rb
|
48
47
|
- lib/zyps.rb
|
data/bin/zyps-175
DELETED
@@ -1,514 +0,0 @@
|
|
1
|
-
#!/usr/local/bin/ruby
|
2
|
-
|
3
|
-
# Copyright 2007 Jay McGavren, jay@mcgavren.com.
|
4
|
-
#
|
5
|
-
# This file is part of Zyps.
|
6
|
-
#
|
7
|
-
# Zyps is free software; you can redistribute it and/or modify
|
8
|
-
# it under the terms of the GNU Lesser General Public License as published by
|
9
|
-
# the Free Software Foundation; either version 3 of the License, or
|
10
|
-
# (at your option) any later version.
|
11
|
-
#
|
12
|
-
# This program is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
# GNU General Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU Lesser General Public License
|
18
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
|
20
|
-
|
21
|
-
gems_loaded = false
|
22
|
-
begin
|
23
|
-
require 'gtk2'
|
24
|
-
require 'optparse'
|
25
|
-
require 'zyps'
|
26
|
-
require 'zyps/actions'
|
27
|
-
require 'zyps/conditions'
|
28
|
-
require 'zyps/environmental_factors'
|
29
|
-
require 'zyps/remote'
|
30
|
-
require 'zyps/views/trails'
|
31
|
-
require 'zyps/views/canvas/gtk2'
|
32
|
-
rescue LoadError
|
33
|
-
if gems_loaded == false
|
34
|
-
require 'rubygems'
|
35
|
-
gems_loaded = true
|
36
|
-
retry
|
37
|
-
else
|
38
|
-
raise
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
include Zyps
|
44
|
-
|
45
|
-
|
46
|
-
DEFAULT_VIEW_WIDTH = 800
|
47
|
-
DEFAULT_VIEW_HEIGHT = 600
|
48
|
-
DEFAULT_MAX_SPEED = 200
|
49
|
-
DEFAULT_MAX_POPULATION = 100
|
50
|
-
DEFAULT_FPS = 60
|
51
|
-
|
52
|
-
|
53
|
-
class Application
|
54
|
-
|
55
|
-
#Port to open service on.
|
56
|
-
attr_accessor :uri
|
57
|
-
#Maximum allowed number of objects.
|
58
|
-
attr_accessor :max_population
|
59
|
-
#View dimensions.
|
60
|
-
attr_accessor :view_width, :view_height
|
61
|
-
|
62
|
-
#Create app window, game environment, and view.
|
63
|
-
#Set up default values.
|
64
|
-
#Takes a hash with these keys and defaults:
|
65
|
-
# :uri => nil,
|
66
|
-
# :view_width => DEFAULT_VIEW_WIDTH,
|
67
|
-
# :view_height => DEFAULT_VIEW_HEIGHT,
|
68
|
-
# :fps => DEFAULT_FPS,
|
69
|
-
# :max_population => DEFAULT_MAX_POPULATION,
|
70
|
-
# :max_speed => DEFAULT_MAX_SPEED,
|
71
|
-
# :enclosure => true
|
72
|
-
def initialize(options = {})
|
73
|
-
|
74
|
-
options = {
|
75
|
-
:uri => nil,
|
76
|
-
:view_width => DEFAULT_VIEW_WIDTH,
|
77
|
-
:view_height => DEFAULT_VIEW_HEIGHT,
|
78
|
-
:fps => DEFAULT_FPS,
|
79
|
-
:max_population => DEFAULT_MAX_POPULATION,
|
80
|
-
:max_speed => DEFAULT_MAX_SPEED,
|
81
|
-
:enclosure => true
|
82
|
-
}.merge(options)
|
83
|
-
|
84
|
-
@uri, @view_width, @view_height, @fps, @max_population, @max_speed, @enclosure =
|
85
|
-
options[:uri], options[:view_width], options[:view_height], options[:fps], options[:max_population], options[:max_speed], options[:enclosure]
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
def main
|
91
|
-
|
92
|
-
#Create a window, and set GTK up to quit when it is closed.
|
93
|
-
window = Gtk::Window.new
|
94
|
-
window.resizable = false
|
95
|
-
window.signal_connect("delete_event") {false}
|
96
|
-
window.signal_connect("destroy") {Gtk.main_quit}
|
97
|
-
|
98
|
-
#Create environment.
|
99
|
-
@environment = Environment.new
|
100
|
-
|
101
|
-
#Set up controls.
|
102
|
-
#Also initializes @view.
|
103
|
-
window.add(
|
104
|
-
create_controls(
|
105
|
-
:view_width => @view_width,
|
106
|
-
:view_height => @view_height,
|
107
|
-
:spacing => 2
|
108
|
-
)
|
109
|
-
)
|
110
|
-
|
111
|
-
#Show all widgets.
|
112
|
-
window.show_all
|
113
|
-
|
114
|
-
#Point view at environment.
|
115
|
-
@environment.add_observer(@view)
|
116
|
-
|
117
|
-
#Keep objects on screen.
|
118
|
-
if @enclosure
|
119
|
-
enclosure = Enclosure.new(
|
120
|
-
:left => 0,
|
121
|
-
:bottom => 0,
|
122
|
-
:top => @view_height,
|
123
|
-
:right => @view_width
|
124
|
-
)
|
125
|
-
@environment.environmental_factors << enclosure
|
126
|
-
end
|
127
|
-
|
128
|
-
#Keep all objects under a certain speed.
|
129
|
-
@environment.environmental_factors << SpeedLimit.new(@max_speed) if @max_speed
|
130
|
-
|
131
|
-
#Limit population.
|
132
|
-
@environment.environmental_factors << PopulationLimit.new(@max_population) if @max_population
|
133
|
-
|
134
|
-
#Set up a creature generator.
|
135
|
-
@generator = CreatureGenerator.new(@environment)
|
136
|
-
|
137
|
-
#Create thread to update environment.
|
138
|
-
thread = Thread.new do
|
139
|
-
|
140
|
-
begin
|
141
|
-
|
142
|
-
drawing_clock = Clock.new
|
143
|
-
time_per_frame = 1.0 / @fps
|
144
|
-
|
145
|
-
loop do
|
146
|
-
|
147
|
-
@environment.interact
|
148
|
-
|
149
|
-
#Determine how much time is left in this frame.
|
150
|
-
time_left_in_frame = (time_per_frame) - drawing_clock.elapsed_time
|
151
|
-
#Sleep for the remaining time.
|
152
|
-
if time_left_in_frame > 0
|
153
|
-
sleep time_left_in_frame
|
154
|
-
#Skip a frame if things are going too slow.
|
155
|
-
else
|
156
|
-
sleep time_per_frame
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
rescue Exception => exception
|
162
|
-
puts exception, exception.backtrace
|
163
|
-
end
|
164
|
-
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
#Start a network service.
|
169
|
-
if @uri
|
170
|
-
server = EnvironmentServer.new(@environment, @uri)
|
171
|
-
server.start
|
172
|
-
#Disable file system access.
|
173
|
-
$SAFE = 2
|
174
|
-
end
|
175
|
-
|
176
|
-
|
177
|
-
#Activate the GUI.
|
178
|
-
Gtk.main
|
179
|
-
|
180
|
-
end
|
181
|
-
|
182
|
-
|
183
|
-
#Create a view and controls.
|
184
|
-
#Takes a hash with these defaults:
|
185
|
-
# :view_width => @view_width
|
186
|
-
# :view_height => @view_height
|
187
|
-
# :homogeneous => false
|
188
|
-
# :spacing => 0
|
189
|
-
# :expand => false
|
190
|
-
# :fill => false
|
191
|
-
# :padding => 0
|
192
|
-
def create_controls(options = {})
|
193
|
-
|
194
|
-
options = {
|
195
|
-
:view_width => @view_width,
|
196
|
-
:view_height => @view_height,
|
197
|
-
:homogeneous => false,
|
198
|
-
:spacing => 0,
|
199
|
-
:expand => false,
|
200
|
-
:fill => false,
|
201
|
-
:padding => 0,
|
202
|
-
}.merge(options)
|
203
|
-
|
204
|
-
#Create a container for the view and controls.
|
205
|
-
interface = Gtk::HBox.new(options[:homogeneous], options[:spacing])
|
206
|
-
|
207
|
-
#Add view to interface.
|
208
|
-
@view = TrailsView.new(
|
209
|
-
:width => options[:view_width],
|
210
|
-
:height => options[:view_height],
|
211
|
-
:trail_length => 5
|
212
|
-
)
|
213
|
-
drawing_window = Gtk::DrawingArea.new
|
214
|
-
@view.canvas = GTK2Canvas.new(drawing_window)
|
215
|
-
interface.pack_start(drawing_window, options[:expand], options[:fill], options[:padding])
|
216
|
-
|
217
|
-
#When mouse button pressed, record location for use in release event handler.
|
218
|
-
drawing_window.add_events(Gdk::Event::BUTTON_PRESS_MASK)
|
219
|
-
drawing_window.signal_connect("button-press-event") do |canvas, event|
|
220
|
-
@press_location = Location.new(event.x, event.y)
|
221
|
-
end
|
222
|
-
|
223
|
-
#Create a creature on button release.
|
224
|
-
drawing_window.add_events(Gdk::Event::BUTTON_RELEASE_MASK)
|
225
|
-
drawing_window.signal_connect("button-release-event") do |canvas, event|
|
226
|
-
#Ensure the mouse was pressed within the canvas.
|
227
|
-
if @press_location
|
228
|
-
#Create creature at release location.
|
229
|
-
@release_location = Location.new(event.x, event.y)
|
230
|
-
@generator.create_creature(
|
231
|
-
:x => event.x,
|
232
|
-
:y => event.y,
|
233
|
-
:speed => Utility.find_distance(@press_location, @release_location) * 2, #Use distance dragged as speed.
|
234
|
-
:pitch => Utility.find_angle(@press_location, @release_location), #Move in direction of drag.
|
235
|
-
:turn => @turn_flag.active?,
|
236
|
-
:approach => @approach_flag.active?,
|
237
|
-
:flee => @flee_flag.active?,
|
238
|
-
:push => @push_flag.active?,
|
239
|
-
:pull => @pull_flag.active?,
|
240
|
-
:breed => @breed_flag.active?,
|
241
|
-
:eat => @eat_flag.active?
|
242
|
-
)
|
243
|
-
#Nullify press location, as it is no longer applicable.
|
244
|
-
@press_location = nil
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
#Create a VBox for all controls.
|
249
|
-
control_panel = Gtk::VBox.new(options[:homogeneous], options[:spacing])
|
250
|
-
|
251
|
-
#Create a group for the actions.
|
252
|
-
action_controls = Gtk::VBox.new(options[:homogeneous], options[:spacing])
|
253
|
-
action_controls.pack_start(Gtk::Label.new("Actions"), options[:expand], options[:fill], options[:padding])
|
254
|
-
@turn_flag = Gtk::CheckButton.new("Turn")
|
255
|
-
action_controls.pack_start(@turn_flag, options[:expand], options[:fill], options[:padding])
|
256
|
-
@approach_flag = Gtk::CheckButton.new("Chase")
|
257
|
-
action_controls.pack_start(@approach_flag, options[:expand], options[:fill], options[:padding])
|
258
|
-
@flee_flag = Gtk::CheckButton.new("Flee")
|
259
|
-
action_controls.pack_start(@flee_flag, options[:expand], options[:fill], options[:padding])
|
260
|
-
@push_flag = Gtk::CheckButton.new("Push")
|
261
|
-
action_controls.pack_start(@push_flag, options[:expand], options[:fill], options[:padding])
|
262
|
-
@pull_flag = Gtk::CheckButton.new("Pull")
|
263
|
-
action_controls.pack_start(@pull_flag, options[:expand], options[:fill], options[:padding])
|
264
|
-
@breed_flag = Gtk::CheckButton.new("Breed")
|
265
|
-
action_controls.pack_start(@breed_flag, options[:expand], options[:fill], options[:padding])
|
266
|
-
@eat_flag = Gtk::CheckButton.new("Eat")
|
267
|
-
action_controls.pack_start(@eat_flag, options[:expand], options[:fill], options[:padding])
|
268
|
-
#Add the action controls to the panel.
|
269
|
-
control_panel.pack_start(action_controls, options[:expand], options[:fill], options[:padding])
|
270
|
-
|
271
|
-
#Create a group for environment controls.
|
272
|
-
environment_controls = Gtk::VBox.new(options[:homogeneous], options[:spacing])
|
273
|
-
environment_controls.pack_start(Gtk::Label.new("Length"), options[:expand], options[:fill], options[:padding])
|
274
|
-
@trail_length_slider = Gtk::HScale.new(2, 100, 1)
|
275
|
-
@trail_length_slider.signal_connect("value-changed") {
|
276
|
-
@view.trail_length = @trail_length_slider.value
|
277
|
-
}
|
278
|
-
@trail_length_slider.value = 5
|
279
|
-
environment_controls.pack_start(@trail_length_slider, options[:expand], options[:fill], options[:padding])
|
280
|
-
@trails_flag = Gtk::CheckButton.new("Trails")
|
281
|
-
@trails_flag.signal_connect("toggled") {
|
282
|
-
@view.erase_flag = ! @trails_flag.active?
|
283
|
-
}
|
284
|
-
@trails_flag.active = false
|
285
|
-
environment_controls.pack_start(@trails_flag, options[:expand], options[:fill], options[:padding])
|
286
|
-
@clear_button = Gtk::Button.new("Clear")
|
287
|
-
@clear_button.signal_connect("clicked") {
|
288
|
-
@environment.objects = []
|
289
|
-
}
|
290
|
-
environment_controls.pack_start(@clear_button, options[:expand], options[:fill], options[:padding])
|
291
|
-
#Add the environment controls to the BOTTOM of the panel.
|
292
|
-
control_panel.pack_end(environment_controls, options[:expand], options[:fill], options[:padding])
|
293
|
-
|
294
|
-
#Add the control panel to the interface.
|
295
|
-
interface.pack_start(control_panel, options[:expand], options[:fill], options[:padding])
|
296
|
-
|
297
|
-
interface
|
298
|
-
|
299
|
-
end
|
300
|
-
|
301
|
-
|
302
|
-
#Set attributes according to command-line arguments.
|
303
|
-
def process_options(arguments)
|
304
|
-
|
305
|
-
#Set up option parser.
|
306
|
-
options = OptionParser.new
|
307
|
-
|
308
|
-
#Define valid options.
|
309
|
-
options.on("-h", "--help", TrueClass, "Display program help.") {
|
310
|
-
puts options.help
|
311
|
-
exit
|
312
|
-
}
|
313
|
-
options.on(
|
314
|
-
"-m",
|
315
|
-
"--max-population [number]",
|
316
|
-
Integer,
|
317
|
-
"The maximum number of allowed game objects. #{DEFAULT_MAX_POPULATION} by default."
|
318
|
-
) {|value| @max_population = value}
|
319
|
-
options.on(
|
320
|
-
"-s",
|
321
|
-
"--max-speed [number]",
|
322
|
-
Integer,
|
323
|
-
"The fastest an object can go. #{DEFAULT_MAX_SPEED ? DEFAULT_MAX_SPEED : 'No limit'} by default."
|
324
|
-
) {|value| @max_speed = value}
|
325
|
-
options.on(
|
326
|
-
"-n",
|
327
|
-
"--no-enclosure",
|
328
|
-
"Disables the barrier that normally keeps objects on the screen."
|
329
|
-
) {|value| @enclosure = false}
|
330
|
-
options.on(
|
331
|
-
"-u",
|
332
|
-
"--uri [uri]",
|
333
|
-
String,
|
334
|
-
"URI to serve the environment on via dRuby. If not specified, no server will be started."
|
335
|
-
) {|value| @uri = value}
|
336
|
-
options.on(
|
337
|
-
"-f",
|
338
|
-
"--fps [frames]",
|
339
|
-
Integer,
|
340
|
-
"Number of frames to draw per second. #{DEFAULT_FPS} by default."
|
341
|
-
) {|value| @fps = value}
|
342
|
-
options.on(
|
343
|
-
"--view-width [pixels]",
|
344
|
-
Integer,
|
345
|
-
"Window width. #{DEFAULT_VIEW_WIDTH} by default."
|
346
|
-
) {|value| @view_width = value}
|
347
|
-
options.on(
|
348
|
-
"--view-height [pixels]",
|
349
|
-
Integer,
|
350
|
-
"Window height. #{DEFAULT_VIEW_HEIGHT} by default."
|
351
|
-
) {|value| @view_height = value}
|
352
|
-
|
353
|
-
#Parse the options, printing usage if parsing fails.
|
354
|
-
options.parse(arguments) rescue puts "#{$!}\nType '#{$0} --help' for valid options."
|
355
|
-
|
356
|
-
end
|
357
|
-
|
358
|
-
|
359
|
-
end
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
class CreatureGenerator
|
364
|
-
|
365
|
-
#Environment creatures will be added to.
|
366
|
-
attr_accessor :environment
|
367
|
-
#Default required proximity for actions.
|
368
|
-
attr_accessor :default_proximity
|
369
|
-
#Rate of new TurnActions.
|
370
|
-
attr_accessor :turn_rate
|
371
|
-
#Acceleration rate of new ApproachActions.
|
372
|
-
attr_accessor :approach_rate
|
373
|
-
#Acceleration rate of new FleeActions.
|
374
|
-
attr_accessor :flee_rate
|
375
|
-
#Strength of new PullActions.
|
376
|
-
attr_accessor :pull_strength
|
377
|
-
#Strength of new PushActions.
|
378
|
-
attr_accessor :push_strength
|
379
|
-
|
380
|
-
def initialize(environment)
|
381
|
-
|
382
|
-
@environment = environment
|
383
|
-
|
384
|
-
#Set up defaults for attributes.
|
385
|
-
@default_proximity = 200
|
386
|
-
@approach_rate = 200
|
387
|
-
@flee_rate = @approach_rate
|
388
|
-
@push_strength = @approach_rate * 2
|
389
|
-
@pull_strength = @push_strength * 0.75
|
390
|
-
@turn_rate = @approach_rate * 1.1
|
391
|
-
@turn_angle = 90
|
392
|
-
@breed_rate = 10
|
393
|
-
|
394
|
-
end
|
395
|
-
|
396
|
-
|
397
|
-
#Create a creature and add it to the environment.
|
398
|
-
def create_creature(options = {})
|
399
|
-
|
400
|
-
options = {
|
401
|
-
:x => 0,
|
402
|
-
:y => 0,
|
403
|
-
:speed => 1,
|
404
|
-
:pitch => 0,
|
405
|
-
:action_proximity => @default_proximity,
|
406
|
-
:turn => false,
|
407
|
-
:approach => false,
|
408
|
-
:flee => false,
|
409
|
-
:push => false,
|
410
|
-
:pull => false,
|
411
|
-
:breed => false,
|
412
|
-
:eat => false,
|
413
|
-
}.merge(options)
|
414
|
-
|
415
|
-
#Create a creature.
|
416
|
-
creature = Creature.new(
|
417
|
-
:location => Location.new(options[:x], options[:y]),
|
418
|
-
:vector => Vector.new(options[:speed], options[:pitch]),
|
419
|
-
:size => 5
|
420
|
-
)
|
421
|
-
|
422
|
-
#Set up actions and merge colors according to selected behaviors.
|
423
|
-
color = Color.new(0.25, 0.25, 0.25)
|
424
|
-
if options[:turn]
|
425
|
-
color.blue += 1
|
426
|
-
creature.behaviors << Behavior.new(
|
427
|
-
:actions => [TurnAction.new(@turn_rate, @turn_angle)],
|
428
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 2)]
|
429
|
-
)
|
430
|
-
end
|
431
|
-
if options[:approach]
|
432
|
-
color.red += 1
|
433
|
-
creature.behaviors << create_behavior(
|
434
|
-
:actions => [ApproachAction.new(@approach_rate)],
|
435
|
-
:conditions => [ProximityCondition.new(options[:action_proximity])]
|
436
|
-
)
|
437
|
-
end
|
438
|
-
if options[:flee]
|
439
|
-
color.red += 0.5; color.green += 0.5 #Yellow.
|
440
|
-
creature.behaviors << create_behavior(
|
441
|
-
:actions => [FleeAction.new(@flee_rate)],
|
442
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.5)]
|
443
|
-
)
|
444
|
-
end
|
445
|
-
if options[:push]
|
446
|
-
color.red += 0.5; color.blue += 0.5 #Purple.
|
447
|
-
creature.behaviors << create_behavior(
|
448
|
-
:actions => [PushAction.new(@push_strength)],
|
449
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.25)]
|
450
|
-
)
|
451
|
-
end
|
452
|
-
if options[:pull]
|
453
|
-
color.blue += 0.75; color.green += 0.75 #Aqua.
|
454
|
-
creature.behaviors << create_behavior(
|
455
|
-
:actions => [PullAction.new(@pull_strength)],
|
456
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.75)]
|
457
|
-
)
|
458
|
-
end
|
459
|
-
if options[:breed]
|
460
|
-
color.green -= 0.1 #Make a bit redder.
|
461
|
-
color.blue -= 0.1
|
462
|
-
creature.behaviors << create_behavior(
|
463
|
-
:actions => [BreedAction.new(@environment, @breed_rate)],
|
464
|
-
:conditions => [CollisionCondition.new] #The default ProximityCondition won't do.
|
465
|
-
)
|
466
|
-
end
|
467
|
-
if options[:eat]
|
468
|
-
color.green += 1
|
469
|
-
creature.behaviors << create_behavior(
|
470
|
-
:actions => [EatAction.new(@environment)],
|
471
|
-
:conditions => [
|
472
|
-
CollisionCondition.new, #The default ProximityCondition won't do.
|
473
|
-
StrengthCondition.new #The eater should be as strong or stronger than its dinner.
|
474
|
-
]
|
475
|
-
)
|
476
|
-
end
|
477
|
-
|
478
|
-
creature.color = color
|
479
|
-
|
480
|
-
@environment.objects << creature
|
481
|
-
|
482
|
-
end
|
483
|
-
|
484
|
-
|
485
|
-
def create_behavior(options = {})
|
486
|
-
|
487
|
-
options = {
|
488
|
-
:actions => [],
|
489
|
-
:conditions => [ProximityCondition.new(@default_proximity)],
|
490
|
-
}.merge(options)
|
491
|
-
|
492
|
-
behavior = Behavior.new
|
493
|
-
behavior.actions = options[:actions]
|
494
|
-
behavior.conditions = options[:conditions]
|
495
|
-
behavior
|
496
|
-
|
497
|
-
end
|
498
|
-
|
499
|
-
|
500
|
-
end
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
begin
|
505
|
-
#Create a server.
|
506
|
-
application = Application.new
|
507
|
-
#Parse the command line.
|
508
|
-
application.process_options(ARGV)
|
509
|
-
#Start the server.
|
510
|
-
application.main
|
511
|
-
rescue => exception
|
512
|
-
#Print error to STDERR and exit with an abnormal status.
|
513
|
-
abort "Error: " + exception.message + exception.backtrace.join("\n")
|
514
|
-
end
|
@@ -1,152 +0,0 @@
|
|
1
|
-
# Copyright 2007 Jay McGavren, jay@mcgavren.com.
|
2
|
-
#
|
3
|
-
# This file is part of Zyps.
|
4
|
-
#
|
5
|
-
# Zyps is free software; you can redistribute it and/or modify
|
6
|
-
# it under the terms of the GNU Lesser General Public License as published by
|
7
|
-
# the Free Software Foundation; either version 3 of the License, or
|
8
|
-
# (at your option) any later version.
|
9
|
-
#
|
10
|
-
# This program is distributed in the hope that it will be useful,
|
11
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
-
# GNU General Public License for more details.
|
14
|
-
#
|
15
|
-
# You should have received a copy of the GNU Lesser General Public License
|
16
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
-
|
18
|
-
|
19
|
-
require 'gtk2'
|
20
|
-
|
21
|
-
|
22
|
-
module Zyps
|
23
|
-
|
24
|
-
|
25
|
-
#Called by View objects for use in Ruby-GNOME2 applications.
|
26
|
-
#Assign an instance to a View, then add the drawing_area attribute to a GUI container object.
|
27
|
-
#The drawing area will be updated whenever the View is.
|
28
|
-
class GTK2Canvas
|
29
|
-
|
30
|
-
|
31
|
-
#A Gtk::DrawingArea that will be painted on.
|
32
|
-
attr_reader :drawing_area
|
33
|
-
#Dimensions of the drawing area.
|
34
|
-
#Control should normally be left to the owner View object.
|
35
|
-
attr_reader :width, :height
|
36
|
-
|
37
|
-
def initialize
|
38
|
-
|
39
|
-
#Will be resized later.
|
40
|
-
@width = 1
|
41
|
-
@height = 1
|
42
|
-
|
43
|
-
#Create a drawing area.
|
44
|
-
@drawing_area = Gtk::DrawingArea.new
|
45
|
-
#Set to correct size.
|
46
|
-
resize
|
47
|
-
|
48
|
-
#Whenever the drawing area needs updating...
|
49
|
-
@drawing_area.signal_connect("expose_event") do
|
50
|
-
#Copy buffer bitmap to canvas.
|
51
|
-
@drawing_area.window.draw_drawable(
|
52
|
-
@drawing_area.style.fg_gc(@drawing_area.state), #Gdk::GC (graphics context) to use when drawing.
|
53
|
-
buffer, #Gdk::Drawable source to copy onto canvas.
|
54
|
-
0, 0, #Pull from upper left of source.
|
55
|
-
0, 0, #Copy to upper left of canvas.
|
56
|
-
-1, -1 #-1 width and height signals to copy entire source over.
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def width= (pixels) #:nodoc:
|
63
|
-
@width = pixels
|
64
|
-
resize
|
65
|
-
end
|
66
|
-
|
67
|
-
def height= (pixels) #:nodoc:
|
68
|
-
@height = pixels
|
69
|
-
resize
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
#Takes a hash with these keys and defaults:
|
74
|
-
# :color => nil
|
75
|
-
# :border_width => 1
|
76
|
-
# :filled => true
|
77
|
-
# :x => nil
|
78
|
-
# :y => nil
|
79
|
-
# :width => nil
|
80
|
-
# :height => nil
|
81
|
-
def draw_rectangle(options = {})
|
82
|
-
options = {
|
83
|
-
:filled => true
|
84
|
-
}.merge(options)
|
85
|
-
graphics_context = Gdk::GC.new(buffer)
|
86
|
-
graphics_context.rgb_fg_color = convert_color(options[:color])
|
87
|
-
buffer.draw_rectangle(
|
88
|
-
graphics_context,
|
89
|
-
options[:filled],
|
90
|
-
options[:x], options[:y],
|
91
|
-
options[:width], options[:height]
|
92
|
-
)
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
#Takes a hash with these keys and defaults:
|
97
|
-
# :color => nil
|
98
|
-
# :width => nil
|
99
|
-
# :x1 => nil
|
100
|
-
# :y1 => nil
|
101
|
-
# :x2 => nil
|
102
|
-
# :y2 => nil
|
103
|
-
def draw_line(options = {})
|
104
|
-
graphics_context = Gdk::GC.new(buffer)
|
105
|
-
graphics_context.rgb_fg_color = convert_color(options[:color])
|
106
|
-
graphics_context.set_line_attributes(
|
107
|
-
options[:width].ceil,
|
108
|
-
Gdk::GC::LINE_SOLID,
|
109
|
-
Gdk::GC::CAP_ROUND,
|
110
|
-
Gdk::GC::JOIN_MITER #Only used for polygons.
|
111
|
-
)
|
112
|
-
buffer.draw_line(
|
113
|
-
graphics_context,
|
114
|
-
options[:x1], options[:y1],
|
115
|
-
options[:x2], options[:y2]
|
116
|
-
)
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
#Draw all objects to the drawing area.
|
121
|
-
def render
|
122
|
-
@drawing_area.queue_draw_area(0, 0, @width, @height)
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
#Converts a Zyps Color to a Gdk::Color.
|
129
|
-
def convert_color(color)
|
130
|
-
Gdk::Color.new(
|
131
|
-
color.red * 65535,
|
132
|
-
color.green * 65535,
|
133
|
-
color.blue * 65535
|
134
|
-
)
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
def resize
|
139
|
-
@drawing_area.set_size_request(@width, @height)
|
140
|
-
@buffer = nil #Causes buffer to reset its size next time it's accessed.
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
def buffer
|
145
|
-
@buffer ||= Gdk::Pixmap.new(@drawing_area.window, @width, @height, -1)
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
end #module Zyps
|