zyps 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.
- data/COPYING.txt +674 -674
- data/README_windows.txt +3 -0
- data/bin/zyps +17 -12
- data/bin/zyps-175 +514 -0
- data/bin/zyps_demo +139 -72
- data/lib/zyps.rb +71 -3
- data/lib/zyps/actions.rb +98 -9
- data/lib/zyps/conditions.rb +22 -0
- data/test/test_zyps.rb +51 -0
- data/test/zyps/test_actions.rb +78 -17
- data/test/zyps/test_conditions.rb +12 -0
- metadata +58 -64
data/bin/zyps_demo
CHANGED
@@ -149,30 +149,35 @@ class Demo < Wx::App
|
|
149
149
|
test_behaviors_2
|
150
150
|
say "-" * 30
|
151
151
|
when 600:
|
152
|
-
@environment.objects = []
|
153
|
-
test_change_color
|
154
|
-
say "-" * 30
|
155
|
-
when 800:
|
156
152
|
@environment.objects = []
|
157
153
|
test_accelerate
|
158
154
|
say "-" * 30
|
159
|
-
when
|
155
|
+
when 700:
|
160
156
|
@environment.objects = []
|
161
157
|
test_turn
|
162
158
|
say "-" * 30
|
163
|
-
when
|
159
|
+
when 900:
|
164
160
|
@environment.objects = []
|
165
161
|
test_approach
|
166
162
|
say "-" * 30
|
167
|
-
when
|
163
|
+
when 1100:
|
168
164
|
@environment.objects = []
|
169
165
|
test_flee
|
170
166
|
say "-" * 30
|
171
|
-
when
|
167
|
+
when 1300:
|
172
168
|
@environment.objects = []
|
173
169
|
test_eat
|
174
170
|
say "-" * 30
|
175
|
-
when
|
171
|
+
when 1400:
|
172
|
+
@environment.objects = []
|
173
|
+
test_explode
|
174
|
+
say "-" * 30
|
175
|
+
when 1500:
|
176
|
+
@environment.objects = []
|
177
|
+
@environment.environmental_factors = []
|
178
|
+
test_shoot
|
179
|
+
say "-" * 30
|
180
|
+
when 1600:
|
176
181
|
finish
|
177
182
|
end
|
178
183
|
@update_count += 1
|
@@ -180,11 +185,12 @@ class Demo < Wx::App
|
|
180
185
|
|
181
186
|
|
182
187
|
#Populate an environment with the given number of creatures.
|
183
|
-
def
|
184
|
-
@log.debug "
|
188
|
+
def generate_creatures(count = 50)
|
189
|
+
@log.debug "Generating #{count} creatures."
|
190
|
+
objects = []
|
185
191
|
count.times do |i|
|
186
192
|
multiplier = i / count.to_f
|
187
|
-
|
193
|
+
objects << Creature.new(
|
188
194
|
:name => i,
|
189
195
|
:location => Location.new(multiplier * WIDTH, multiplier * HEIGHT),
|
190
196
|
:color => Color.new(multiplier, 1 - multiplier, multiplier / 2 + 0.5),
|
@@ -192,6 +198,7 @@ class Demo < Wx::App
|
|
192
198
|
:size => DEFAULT_OBJECT_SIZE
|
193
199
|
)
|
194
200
|
end
|
201
|
+
objects
|
195
202
|
end
|
196
203
|
|
197
204
|
|
@@ -240,7 +247,7 @@ class Demo < Wx::App
|
|
240
247
|
#Demonstrates environmental factors by adding gravity to the environment.
|
241
248
|
def test_environmental_factors
|
242
249
|
|
243
|
-
|
250
|
+
@environment.objects = generate_creatures
|
244
251
|
|
245
252
|
say("Without gravity, objects just travel on forever.")
|
246
253
|
|
@@ -262,7 +269,7 @@ class Demo < Wx::App
|
|
262
269
|
#Demonstrates creature behaviors.
|
263
270
|
def test_behaviors
|
264
271
|
|
265
|
-
|
272
|
+
@environment.objects = generate_creatures
|
266
273
|
|
267
274
|
say("Let's add a Behavior to our creatures.")
|
268
275
|
chase = Behavior.new
|
@@ -288,7 +295,7 @@ class Demo < Wx::App
|
|
288
295
|
@environment.objects << GameObject.new(
|
289
296
|
:name => "target",
|
290
297
|
:location => Location.new(WIDTH / 2, HEIGHT / 2),
|
291
|
-
:color => Color.
|
298
|
+
:color => Color.white,
|
292
299
|
:vector => Vector.new(30, 315),
|
293
300
|
:size => DEFAULT_OBJECT_SIZE * 2, #Size.
|
294
301
|
:tags => ["food"]
|
@@ -300,61 +307,11 @@ class Demo < Wx::App
|
|
300
307
|
end
|
301
308
|
|
302
309
|
|
303
|
-
#A Creature that changes the colors of other objects.
|
304
|
-
class Morpher < Creature
|
305
|
-
#Changes an object's color.
|
306
|
-
def initialize(*arguments)
|
307
|
-
super
|
308
|
-
morph = Behavior.new
|
309
|
-
#Shift the target's color to match the creature's.
|
310
|
-
morph.actions << BlendAction.new(self.color)
|
311
|
-
#Act only on nearby targets.
|
312
|
-
morph.conditions << ProximityCondition.new(50)
|
313
|
-
@behaviors << morph
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
#Demonstrates changing object colors.
|
318
|
-
def test_change_color
|
319
|
-
|
320
|
-
populate(@environment)
|
321
|
-
|
322
|
-
say("Creatures can influence any attribute of their target, such as its color.")
|
323
|
-
say("This demo includes a Morpher class, which is a type of Creature.")
|
324
|
-
say("Morphers are created with a single behavior, which shifts the color of any nearby target to match the Morpher's color.")
|
325
|
-
|
326
|
-
say("Let's place a red Morpher...")
|
327
|
-
@environment.objects << Morpher.new(
|
328
|
-
:location => Location.new(0, 100),
|
329
|
-
:color => Color.new(1, 0, 0),
|
330
|
-
:vector => Vector.new(100, 0),
|
331
|
-
:size => DEFAULT_OBJECT_SIZE
|
332
|
-
)
|
333
|
-
say("a green one...")
|
334
|
-
@environment.objects << Morpher.new(
|
335
|
-
:location => Location.new(0, 150),
|
336
|
-
:color => Color.new(0, 1, 0),
|
337
|
-
:vector => Vector.new(200, 0),
|
338
|
-
:size => DEFAULT_OBJECT_SIZE
|
339
|
-
)
|
340
|
-
say("and a blue one...")
|
341
|
-
@environment.objects << Morpher.new(
|
342
|
-
:location => Location.new(0, 200),
|
343
|
-
:color => Color.new(0, 0, 1),
|
344
|
-
:vector => Vector.new(300, 0),
|
345
|
-
:size => DEFAULT_OBJECT_SIZE
|
346
|
-
)
|
347
|
-
|
348
|
-
say("...and see what they do.")
|
349
|
-
|
350
|
-
end
|
351
|
-
|
352
|
-
|
353
310
|
#Demonstrates altering object speed.
|
354
311
|
def test_accelerate
|
355
312
|
|
356
313
|
say("Here are some Creatures, just plodding along.")
|
357
|
-
|
314
|
+
@environment.objects = generate_creatures
|
358
315
|
|
359
316
|
say("We're going to have them pick up the pace.")
|
360
317
|
say("We add a Behavior with an AccelerateAction to all the creatures.")
|
@@ -371,7 +328,7 @@ class Demo < Wx::App
|
|
371
328
|
#Demonstrates altering object vectors.
|
372
329
|
def test_turn
|
373
330
|
|
374
|
-
|
331
|
+
@environment.objects = generate_creatures
|
375
332
|
|
376
333
|
say("This time we'll use the TurnAction class.")
|
377
334
|
say("We tell each creature it should turn 90 degrees.")
|
@@ -387,7 +344,7 @@ class Demo < Wx::App
|
|
387
344
|
#Demonstrates adding vectors.
|
388
345
|
def test_approach
|
389
346
|
|
390
|
-
|
347
|
+
@environment.objects = generate_creatures
|
391
348
|
|
392
349
|
say("When your car skids on ice, you might steer in a different direction, but you're going to keep following your original vector for a while.")
|
393
350
|
say("Our ApproachAction adds the vector the creature WANTS to follow to the vector it's ACTUALLY following.")
|
@@ -418,12 +375,12 @@ class Demo < Wx::App
|
|
418
375
|
#Demonstrates adding vectors.
|
419
376
|
def test_flee
|
420
377
|
|
421
|
-
|
378
|
+
@environment.objects = generate_creatures
|
422
379
|
|
423
380
|
say("A FleeAction is just like an ApproachAction, but we head in the OPPOSITE direction.")
|
424
381
|
@environment.objects.each do |creature|
|
425
382
|
flee = Behavior.new
|
426
|
-
flee.actions << FleeAction.new(
|
383
|
+
flee.actions << FleeAction.new(300)
|
427
384
|
flee.conditions << TagCondition.new("predator")
|
428
385
|
creature.behaviors << flee
|
429
386
|
end
|
@@ -442,13 +399,13 @@ class Demo < Wx::App
|
|
442
399
|
#Demonstrates keeping a reference to an Environment so a Creature can alter it.
|
443
400
|
def test_eat
|
444
401
|
|
445
|
-
|
402
|
+
@environment.objects = generate_creatures
|
446
403
|
|
447
404
|
say("Most games are all about destruction, but there hasn't been much so far.")
|
448
405
|
say("Let's create a creature that causes some havoc.")
|
449
406
|
predator = Creature.new(
|
450
407
|
:location => Location.new(0, 150),
|
451
|
-
:color => Color.
|
408
|
+
:color => Color.green,
|
452
409
|
:vector => Vector.new(200, 0),
|
453
410
|
:size => DEFAULT_OBJECT_SIZE * 5
|
454
411
|
)
|
@@ -473,6 +430,116 @@ class Demo < Wx::App
|
|
473
430
|
say("And - chomp!")
|
474
431
|
|
475
432
|
end
|
433
|
+
|
434
|
+
|
435
|
+
#Demonstrates ElapsedTimeCondition.
|
436
|
+
def test_explode
|
437
|
+
|
438
|
+
say("Let's have some fireworks.")
|
439
|
+
say("First we'll create 'stars' to load into the rocket.")
|
440
|
+
star = Creature.new(:color => Color.red)
|
441
|
+
say("A BlendAction will make them fade to black over time.")
|
442
|
+
star.behaviors << Behavior.new(:actions => [BlendAction.new(0.5, Color.black)])
|
443
|
+
say("An ExplodeAction copies prototype objects into the environment.")
|
444
|
+
action = ExplodeAction.new(@environment)
|
445
|
+
say("We'll make copies of our star with random vectors.")
|
446
|
+
say("We'll load these copies into our ExplodeAction.")
|
447
|
+
25.times do |i|
|
448
|
+
copy = star.copy
|
449
|
+
copy.vector = Vector.new(rand(50), rand(360))
|
450
|
+
action.prototypes << copy
|
451
|
+
end
|
452
|
+
|
453
|
+
say("It's just not smart to build fireworks without a fuse.")
|
454
|
+
say("An ElapsedTimeCondition should do nicely.")
|
455
|
+
condition = ElapsedTimeCondition.new
|
456
|
+
say("This will be a short fuse, though, say 2 seconds.")
|
457
|
+
condition.interval = 2
|
458
|
+
|
459
|
+
say("We set up a Behavior with the Action and Condition...")
|
460
|
+
explode = Behavior.new(:actions => [action], :conditions => [condition])
|
461
|
+
say("Add the behavior to rockets aimed at the sky...")
|
462
|
+
rocket = Creature.new(
|
463
|
+
:behaviors => [explode],
|
464
|
+
:vector => Vector.new(100, 260),
|
465
|
+
:location => Location.new(WIDTH / 2, HEIGHT),
|
466
|
+
:size => 50
|
467
|
+
)
|
468
|
+
rocket2 = rocket.copy
|
469
|
+
rocket2.vector = Vector.new(130, 275)
|
470
|
+
say("And light those suckers.")
|
471
|
+
@environment.objects << rocket << rocket2
|
472
|
+
@environment << Gravity.new(30)
|
473
|
+
|
474
|
+
end
|
475
|
+
|
476
|
+
|
477
|
+
#Demonstrates ShootAction.
|
478
|
+
def test_shoot
|
479
|
+
|
480
|
+
say("I'm a big fan of shoot-em-up games.")
|
481
|
+
say("The ability to make them easily is a major goal of Zyps.")
|
482
|
+
|
483
|
+
say("Every shooter needs someone to play it, so let's make a player.")
|
484
|
+
say("We give him a 'player' tag so enemies can target him.")
|
485
|
+
player = Creature.new(
|
486
|
+
:location => Location.new(WIDTH / 2, HEIGHT / 2),
|
487
|
+
:behaviors => [
|
488
|
+
Behavior.new(
|
489
|
+
:actions => [FleeAction.new(100)],
|
490
|
+
:conditions => [ProximityCondition.new(30)]
|
491
|
+
)
|
492
|
+
],
|
493
|
+
:size => DEFAULT_OBJECT_SIZE,
|
494
|
+
:vector => Vector.new(10, 0),
|
495
|
+
:tags => ['player']
|
496
|
+
)
|
497
|
+
|
498
|
+
say("Shooters need lots of bullets, of course.")
|
499
|
+
say("A bullet doesn't need to be smart, but it should destroy the player when he gets too close.")
|
500
|
+
bullet = Creature.new(
|
501
|
+
:behaviors => [
|
502
|
+
Behavior.new(
|
503
|
+
:actions => [DestroyAction.new(@environment)],
|
504
|
+
:conditions => [
|
505
|
+
ProximityCondition.new(7),
|
506
|
+
TagCondition.new('player')
|
507
|
+
]
|
508
|
+
)
|
509
|
+
],
|
510
|
+
:vector => Vector.new(100, 0)
|
511
|
+
)
|
512
|
+
|
513
|
+
say("We're going to fire groups of 3 bullets at once.")
|
514
|
+
bullets = [bullet, bullet.copy, bullet.copy]
|
515
|
+
say("There's no point firing all 3 at the same spot...")
|
516
|
+
say("We'll vary their angles a bit.")
|
517
|
+
bullets.first.vector.pitch -= 10
|
518
|
+
bullets.last.vector.pitch += 10
|
519
|
+
|
520
|
+
say("And lastly, we need an enemy to fire the bullets at the player.")
|
521
|
+
say("We'll give him a ShootAction, and assign it our group of bullets.")
|
522
|
+
say("The action copies the bullets into the Environment and aims them at its target.")
|
523
|
+
say("An ElapsedTimeCondition makes it fire every 0.5 seconds.")
|
524
|
+
enemy = Creature.new(
|
525
|
+
:vector => Vector.new(30, 45),
|
526
|
+
:behaviors => [
|
527
|
+
Behavior.new(
|
528
|
+
:actions => [ShootAction.new(@environment, [bullets])],
|
529
|
+
:conditions => [
|
530
|
+
ElapsedTimeCondition.new(0.5),
|
531
|
+
TagCondition.new('player'),
|
532
|
+
]
|
533
|
+
)
|
534
|
+
],
|
535
|
+
:color => Color.green,
|
536
|
+
:size => DEFAULT_OBJECT_SIZE
|
537
|
+
)
|
538
|
+
|
539
|
+
say("Game on!")
|
540
|
+
@environment.objects << player << enemy
|
541
|
+
|
542
|
+
end
|
476
543
|
|
477
544
|
|
478
545
|
#End the demos.
|
data/lib/zyps.rb
CHANGED
@@ -111,6 +111,19 @@ class Environment
|
|
111
111
|
|
112
112
|
end
|
113
113
|
|
114
|
+
#Overloads the << operator to put the new item into the correct list.
|
115
|
+
#This allows one to simply call env << <valid_object> instead of
|
116
|
+
#having to choose a specific list, such as objects or environmental factors.
|
117
|
+
def <<(item)
|
118
|
+
if(item.kind_of? Zyps::GameObject)
|
119
|
+
self.objects << item
|
120
|
+
elsif(item.kind_of? Zyps::EnvironmentalFactor)
|
121
|
+
self.environmental_factors << item
|
122
|
+
else
|
123
|
+
raise "Invalid item: #{item.class}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
114
127
|
end
|
115
128
|
|
116
129
|
|
@@ -164,7 +177,7 @@ class GameObject
|
|
164
177
|
copy.location = @location.copy
|
165
178
|
copy.tags = @tags.clone
|
166
179
|
copy.identifier = generate_identifier
|
167
|
-
copy.name = @name ? "Copy of " + @name : nil
|
180
|
+
copy.name = @name ? "Copy of " + @name.to_s : nil
|
168
181
|
copy
|
169
182
|
end
|
170
183
|
|
@@ -187,6 +200,21 @@ class GameObject
|
|
187
200
|
@identifier = value
|
188
201
|
end
|
189
202
|
|
203
|
+
#Overloads the << operator to put the new item into the correct
|
204
|
+
#list or assign it to the correct attribute.
|
205
|
+
#Assignment is done based on item's class or a parent class of item.
|
206
|
+
def <<(item)
|
207
|
+
if item.kind_of? Zyps::Location:
|
208
|
+
self.location = item
|
209
|
+
elsif item.kind_of? Zyps::Color:
|
210
|
+
self.color = item
|
211
|
+
elsif item.kind_of? Zyps::Vector:
|
212
|
+
self.vector = item
|
213
|
+
else
|
214
|
+
raise "Invalid item: #{item.class}"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
190
218
|
private
|
191
219
|
|
192
220
|
#Make a unique GameObject identifier.
|
@@ -236,6 +264,20 @@ class Creature < GameObject
|
|
236
264
|
behaviors.each {|behavior| behavior.perform(self, targets)}
|
237
265
|
end
|
238
266
|
|
267
|
+
#See GameObject#<<.
|
268
|
+
#Adds ability to stream in behaviors as well.
|
269
|
+
def <<(item)
|
270
|
+
begin
|
271
|
+
super
|
272
|
+
rescue
|
273
|
+
if(item.kind_of? Zyps::Behavior)
|
274
|
+
self.behaviors << item
|
275
|
+
else
|
276
|
+
raise "invalid item: #{item.class}"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
239
281
|
end
|
240
282
|
|
241
283
|
|
@@ -434,6 +476,19 @@ class Color
|
|
434
476
|
)
|
435
477
|
end
|
436
478
|
|
479
|
+
#Pre-defined color value.
|
480
|
+
def self.red; Color.new(1, 0, 0); end
|
481
|
+
def self.orange; Color.new(1, 0.63, 0); end
|
482
|
+
def self.yellow; Color.new(1, 1, 0); end
|
483
|
+
def self.green; Color.new(0, 1, 0); end
|
484
|
+
def self.blue; Color.new(0, 0, 1); end
|
485
|
+
def self.indigo; Color.new(0.4, 0, 1); end
|
486
|
+
def self.violet; Color.new(0.9, 0.5, 0.9); end
|
487
|
+
def self.white; Color.new(1, 1, 1); end
|
488
|
+
def self.black; Color.new(0, 0, 0); end
|
489
|
+
def self.grey; Color.new(0.5, 0.5, 0.5); end
|
490
|
+
|
491
|
+
|
437
492
|
end
|
438
493
|
|
439
494
|
|
@@ -451,6 +506,9 @@ class Location
|
|
451
506
|
#Make a deep copy.
|
452
507
|
def copy; self.clone; end
|
453
508
|
|
509
|
+
#True if x and y coordinates are the same.
|
510
|
+
def ==(other); self.x == other.x and self.y == other.y; end
|
511
|
+
|
454
512
|
end
|
455
513
|
|
456
514
|
|
@@ -478,7 +536,7 @@ class Vector
|
|
478
536
|
#Store as radians internally.
|
479
537
|
@pitch = Utility.to_radians(value)
|
480
538
|
end
|
481
|
-
|
539
|
+
|
482
540
|
#The X component.
|
483
541
|
def x; @speed.to_f * Math.cos(@pitch); end
|
484
542
|
def x=(value)
|
@@ -503,6 +561,9 @@ class Vector
|
|
503
561
|
Vector.new(new_length, new_angle)
|
504
562
|
end
|
505
563
|
|
564
|
+
#True if x and y coordinates are the same.
|
565
|
+
def ==(other); self.speed == other.speed and self.pitch == other.pitch; end
|
566
|
+
|
506
567
|
end
|
507
568
|
|
508
569
|
|
@@ -522,13 +583,20 @@ class Clock
|
|
522
583
|
time = Time.new.to_f
|
523
584
|
elapsed_time = time - @last_check_time
|
524
585
|
@last_check_time = time
|
525
|
-
elapsed_time
|
586
|
+
elapsed_time * @@speed
|
526
587
|
end
|
527
588
|
|
528
589
|
def reset_elapsed_time
|
529
590
|
@last_check_time = Time.new.to_f
|
530
591
|
end
|
531
592
|
|
593
|
+
#Speed at which all Clocks are operating.
|
594
|
+
@@speed = 1.0
|
595
|
+
def Clock.speed; @@speed; end
|
596
|
+
#Set speed at which all Clocks will operate.
|
597
|
+
#1 is real-time, 2 is double speed, 0 is paused.
|
598
|
+
def Clock.speed=(value); @@speed = value; end
|
599
|
+
|
532
600
|
end
|
533
601
|
|
534
602
|
|