1#!/usr/bin/env python
2""" pg.examples.testsprite
3
4Like the testsprite.c that comes with libsdl, this pygame version shows
5lots of sprites moving around.
6
7It is an abomination of ugly code, and mostly used for testing.
8
9
10See pg.examples.aliens for some prettyier code.
11"""
12import sys
13import os
14
15from random import randint
16from time import time
17
18import pygame as pg
19from pygame.compat import xrange_
20
21
22if "-psyco" in sys.argv:
23    try:
24        import psyco
25
26        psyco.full()
27    except Exception:
28        print("No psyco for you!  psyco failed to import and run.")
29
30main_dir = os.path.split(os.path.abspath(__file__))[0]
31data_dir = os.path.join(main_dir, "data")
32
33
34# use this to use update rects or not.
35#  If the screen is mostly full, then update rects are not useful.
36update_rects = True
37if "-update_rects" in sys.argv:
38    update_rects = True
39if "-noupdate_rects" in sys.argv:
40    update_rects = False
41
42use_static = False
43if "-static" in sys.argv:
44    use_static = True
45
46
47use_layered_dirty = False
48if "-layered_dirty" in sys.argv:
49    update_rects = True
50    use_layered_dirty = True
51
52
53flags = 0
54if "-flip" in sys.argv:
55    flags ^= pg.DOUBLEBUF
56
57if "-fullscreen" in sys.argv:
58    flags ^= pg.FULLSCREEN
59
60if "-sw" in sys.argv:
61    flags ^= pg.SWSURFACE
62
63use_rle = True
64
65if "-hw" in sys.argv:
66    flags ^= pg.HWSURFACE
67    use_rle = False
68
69if "-scaled" in sys.argv:
70    flags ^= pg.SCALED
71
72screen_dims = [640, 480]
73
74if "-height" in sys.argv:
75    i = sys.argv.index("-height")
76    screen_dims[1] = int(sys.argv[i + 1])
77
78if "-width" in sys.argv:
79    i = sys.argv.index("-width")
80    screen_dims[0] = int(sys.argv[i + 1])
81
82if "-alpha" in sys.argv:
83    use_alpha = True
84else:
85    use_alpha = False
86
87print(screen_dims)
88
89
90##class Thingy(pg.sprite.Sprite):
91##    images = None
92##    def __init__(self):
93##        pg.sprite.Sprite.__init__(self)
94##        self.image = Thingy.images[0]
95##        self.rect = self.image.get_rect()
96##        self.rect.x = randint(0, screen_dims[0])
97##        self.rect.y = randint(0, screen_dims[1])
98##        #self.vel = [randint(-10, 10), randint(-10, 10)]
99##        self.vel = [randint(-1, 1), randint(-1, 1)]
100##
101##    def move(self):
102##        for i in [0, 1]:
103##            nv = self.rect[i] + self.vel[i]
104##            if nv >= screen_dims[i] or nv < 0:
105##                self.vel[i] = -self.vel[i]
106##                nv = self.rect[i] + self.vel[i]
107##            self.rect[i] = nv
108
109
110class Thingy(pg.sprite.DirtySprite):
111    images = None
112
113    def __init__(self):
114        ##        pg.sprite.Sprite.__init__(self)
115        pg.sprite.DirtySprite.__init__(self)
116        self.image = Thingy.images[0]
117        self.rect = self.image.get_rect()
118        self.rect.x = randint(0, screen_dims[0])
119        self.rect.y = randint(0, screen_dims[1])
120        # self.vel = [randint(-10, 10), randint(-10, 10)]
121        self.vel = [randint(-1, 1), randint(-1, 1)]
122        self.dirty = 2
123
124    def update(self):
125        for i in [0, 1]:
126            nv = self.rect[i] + self.vel[i]
127            if nv >= screen_dims[i] or nv < 0:
128                self.vel[i] = -self.vel[i]
129                nv = self.rect[i] + self.vel[i]
130            self.rect[i] = nv
131
132
133class Static(pg.sprite.DirtySprite):
134    images = None
135
136    def __init__(self):
137        pg.sprite.DirtySprite.__init__(self)
138        self.image = Static.images[0]
139        self.rect = self.image.get_rect()
140        self.rect.x = randint(0, 3 * screen_dims[0] / 4)
141        self.rect.y = randint(0, 3 * screen_dims[1] / 4)
142
143
144def main(
145    update_rects=True,
146    use_static=False,
147    use_layered_dirty=False,
148    screen_dims=[640, 480],
149    use_alpha=False,
150    flags=0,
151):
152    """Show lots of sprites moving around
153
154    Optional keyword arguments:
155    update_rects - use the RenderUpdate sprite group class (default True)
156    use_static - include non-moving images (default False)
157    use_layered_dirty - Use the FastRenderGroup sprite group (default False)
158    screen_dims - Pygame window dimensions (default [640, 480])
159    use_alpha - use alpha blending (default False)
160    flags - additional display mode flags (default no additional flags)
161
162    """
163
164    if use_layered_dirty:
165        update_rects = True
166
167    pg.init()  # needed to initialise time module for get_ticks()
168    pg.display.init()
169
170    # if "-fast" in sys.argv:
171
172    screen = pg.display.set_mode(screen_dims, flags, vsync="-vsync" in sys.argv)
173
174    # this is mainly for GP2X, so it can quit.
175    pg.joystick.init()
176    num_joysticks = pg.joystick.get_count()
177    if num_joysticks > 0:
178        stick = pg.joystick.Joystick(0)
179        stick.init()  # now we will receive events for the joystick
180
181    screen.fill([0, 0, 0])
182    pg.display.flip()
183    sprite_surface = pg.image.load(os.path.join(data_dir, "asprite.bmp"))
184    sprite_surface2 = pg.image.load(os.path.join(data_dir, "static.png"))
185
186    if use_rle:
187        sprite_surface.set_colorkey([0xFF, 0xFF, 0xFF], pg.SRCCOLORKEY | pg.RLEACCEL)
188        sprite_surface2.set_colorkey([0xFF, 0xFF, 0xFF], pg.SRCCOLORKEY | pg.RLEACCEL)
189    else:
190        sprite_surface.set_colorkey([0xFF, 0xFF, 0xFF], pg.SRCCOLORKEY)
191        sprite_surface2.set_colorkey([0xFF, 0xFF, 0xFF], pg.SRCCOLORKEY)
192
193    if use_alpha:
194        sprite_surface = sprite_surface.convert_alpha()
195        sprite_surface2 = sprite_surface2.convert_alpha()
196    else:
197        sprite_surface = sprite_surface.convert()
198        sprite_surface2 = sprite_surface2.convert()
199
200    Thingy.images = [sprite_surface]
201    if use_static:
202        Static.images = [sprite_surface2]
203
204    if len(sys.argv) > 1:
205        try:
206            numsprites = int(sys.argv[-1])
207        except Exception:
208            numsprites = 100
209    else:
210        numsprites = 100
211    sprites = None
212    if use_layered_dirty:
213        ##        sprites = pg.sprite.FastRenderGroup()
214        sprites = pg.sprite.LayeredDirty()
215    else:
216        if update_rects:
217            sprites = pg.sprite.RenderUpdates()
218        else:
219            sprites = pg.sprite.Group()
220
221    for i in xrange_(0, numsprites):
222        if use_static and i % 2 == 0:
223            sprites.add(Static())
224        sprites.add(Thingy())
225
226    frames = 0
227    start = time()
228
229    background = pg.Surface(screen.get_size())
230    background = background.convert()
231    background.fill([0, 0, 0])
232
233    going = True
234    while going:
235        if not update_rects:
236            screen.fill([0, 0, 0])
237
238        ##        for sprite in sprites:
239        ##            sprite.move()
240
241        if update_rects:
242            sprites.clear(screen, background)
243        sprites.update()
244
245        rects = sprites.draw(screen)
246        if update_rects:
247            pg.display.update(rects)
248        else:
249            pg.display.flip()
250
251        for event in pg.event.get():
252            if event.type in [pg.QUIT, pg.KEYDOWN, pg.QUIT, pg.JOYBUTTONDOWN]:
253                going = False
254
255        frames += 1
256    end = time()
257    print("FPS: %f" % (frames / ((end - start))))
258    pg.quit()
259
260
261if __name__ == "__main__":
262    main(update_rects, use_static, use_layered_dirty, screen_dims, use_alpha, flags)
263