Optional Pyrex extension for the collision module. More than doubles its speed.
[python-bulletml.git] / bulletml-runner
1 #!/usr/bin/env python
2
3 import os
4 import sys
5 import time
6
7 import pygame
8
9 import bulletml
10 import bulletml.bulletyaml
11 from bulletml.collision import collides_all
12
13 try:
14 import yaml
15 except ImportError:
16 yaml = None
17
18 try:
19 import psycox
20 except ImportError:
21 pass
22 else:
23 psyco.full()
24
25 def main(argv):
26 if not argv:
27 raise SystemExit("Usage: %s filename ..." % sys.argv[0])
28
29 pygame.display.init()
30 screen = pygame.display.set_mode([600, 600], pygame.DOUBLEBUF)
31 bullet = pygame.Surface([3, 3])
32 bullet.fill([255, 0, 0])
33 clock = pygame.time.Clock()
34 target = bulletml.Bullet()
35
36 file_idx = 0
37
38 while True:
39 filename = argv[file_idx % len(argv)]
40 doc = bulletml.BulletML.FromDocument(open(filename, "rU"))
41 source = bulletml.Bullet.FromDocument(
42 doc, x=150, y=150, target=target, rank=0.5)
43
44 active = set([source])
45 source.vanished = True
46 print filename
47 print " Loaded %d top-level actions." % len(source._actions)
48 frames = 0
49 total = 0
50 paused = False
51 newfile = False
52
53 pygame.display.set_caption(os.path.basename(filename))
54
55 while active and not newfile:
56 go = False
57
58 for event in pygame.event.get():
59 if event.type == pygame.QUIT:
60 raise SystemExit
61 elif event.type == pygame.KEYDOWN:
62 if event.key == pygame.K_SPACE:
63 paused ^= True
64 elif event.key == pygame.K_RIGHT:
65 go = True
66 elif event.key == pygame.K_PAGEUP:
67 file_idx -= 1
68 newfile = True
69 elif event.key == pygame.K_PAGEDOWN:
70 file_idx += 1
71 newfile = True
72 elif event.key == pygame.K_RETURN:
73 newfile = True
74 elif event.key == pygame.K_s:
75 actions = [act([], 0.5) for act in doc.actions]
76 source = bulletml.Bullet(
77 x=150, y=150, target=target,
78 actions=actions, rank=0.5)
79 source.vanished = True
80 active.add(source)
81 target.x, target.y = pygame.mouse.get_pos()
82 target.x /= 2
83 target.y /= 2
84
85 if not paused or go:
86 lactive = list(active)
87 start = time.time()
88 count = len(active)
89 for obj in lactive:
90 new = obj.step()
91 total += len(new)
92 active.update(new)
93 if (obj.finished
94 or not (-50 < obj.x < 350)
95 or not (-50 < obj.y < 350)):
96 active.remove(obj)
97 if lactive:
98 collides_all(lactive[0], lactive)
99 elapsed = time.time() - start
100
101 frames += 1
102 if frames % 100 == 0:
103 print " Processing: %04d: %d bullets, %d active." % (
104 frames, total, count)
105 if elapsed:
106 seconds_per_bullet = elapsed / count
107 bullets_per_second = count / elapsed
108 print " %g seconds per bullet (60Hz max: %g)." % (
109 seconds_per_bullet, bullets_per_second / 60)
110
111 screen.fill([0, 0, 0])
112 for obj in active:
113 try:
114 x, y = obj.x, obj.y
115 except AttributeError:
116 pass
117 else:
118 if not obj.vanished:
119 x *= 2
120 y *= 2
121 x -= 1
122 y -= 1
123 screen.blit(bullet, [x, y])
124 clock.tick(60)
125 pygame.display.flip()
126
127 print " Finished: %04d: %d bullets." % (frames, total)
128
129 if __name__ == "__main__":
130 main(sys.argv[1:])