~ubuntu-branches/ubuntu/gutsy/pygame/gutsy

« back to all changes in this revision

Viewing changes to examples/aliens.py

  • Committer: Bazaar Package Importer
  • Author(s): Ed Boraas
  • Date: 2002-02-20 06:39:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020220063924-amlzj7tqkeods4eq
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
 
 
3
import random, os.path
 
4
 
 
5
#import basic pygame modules
 
6
import pygame
 
7
from pygame.locals import *
 
8
 
 
9
#see if we can load more than standard BMP
 
10
if not pygame.image.get_extended():
 
11
    raise SystemExit, "Sorry, extended image module required"
 
12
 
 
13
 
 
14
#game constants
 
15
MAX_SHOTS      = 2      #most player bullets onscreen
 
16
ALIEN_ODDS     = 22     #chances a new alien appears
 
17
BOMB_ODDS      = 60    #chances a new bomb will drop
 
18
ALIEN_RELOAD   = 12     #frames between new aliens
 
19
SCREENRECT     = Rect(0, 0, 640, 480)
 
20
SCORE          = 0
 
21
 
 
22
    
 
23
def load_image(file):
 
24
    "loads an image, prepares it for play"
 
25
    file = os.path.join('data', file)
 
26
    try:
 
27
        surface = pygame.image.load(file)
 
28
    except pygame.error:
 
29
        raise SystemExit, 'Could not load image "%s" %s'%(file, pygame.get_error())
 
30
    return surface.convert()
 
31
 
 
32
def load_images(*files):
 
33
    return [load_image(file) for file in files]
 
34
 
 
35
 
 
36
class dummysound:
 
37
    def play(self): pass
 
38
    
 
39
def load_sound(file):
 
40
    if not pygame.mixer: return dummysound()
 
41
    file = os.path.join('data', file)
 
42
    try:
 
43
        sound = pygame.mixer.Sound(file)
 
44
        return sound
 
45
    except pygame.error:
 
46
        print 'Warning, unable to load,', file
 
47
    return dummysound()
 
48
 
 
49
 
 
50
 
 
51
# each type of game object gets an init and an
 
52
# update function. the update function is called
 
53
# once per frame, and it is when each object should
 
54
# change it's current position and state. the Player
 
55
# object actually gets a "move" function instead of
 
56
# update, since it is passed extra information about
 
57
# the keyboard
 
58
 
 
59
 
 
60
class Player(pygame.sprite.Sprite):
 
61
    speed = 10
 
62
    bounce = 24
 
63
    gun_offset = -11
 
64
    images = []
 
65
    def __init__(self):
 
66
        pygame.sprite.Sprite.__init__(self, self.containers)
 
67
        self.image = self.images[0]
 
68
        self.rect = self.image.get_rect()
 
69
        self.reloading = 0
 
70
        self.rect.centerx = SCREENRECT.centerx
 
71
        self.rect.bottom = SCREENRECT.bottom - 1
 
72
        self.origtop = self.rect.top
 
73
        self.facing = -1
 
74
 
 
75
    def move(self, direction):
 
76
        if direction: self.facing = direction
 
77
        self.rect.move_ip(direction*self.speed, 0)
 
78
        self.rect = self.rect.clamp(SCREENRECT)
 
79
        if direction < 0:
 
80
            self.image = self.images[0]
 
81
        elif direction > 0:
 
82
            self.image = self.images[1]
 
83
        self.rect.top = self.origtop - (self.rect.left/self.bounce%2)
 
84
 
 
85
    def gunpos(self):
 
86
        pos = self.facing*self.gun_offset + self.rect.centerx
 
87
        return pos, self.rect.top
 
88
 
 
89
 
 
90
class Alien(pygame.sprite.Sprite):
 
91
    speed = 13 
 
92
    animcycle = 12
 
93
    images = []
 
94
    def __init__(self):
 
95
        pygame.sprite.Sprite.__init__(self, self.containers)
 
96
        self.image = self.images[0]
 
97
        self.rect = self.image.get_rect()
 
98
        self.facing = random.choice((-1,1)) * Alien.speed
 
99
        self.frame = 0
 
100
        if self.facing < 0:
 
101
            self.rect.right = SCREENRECT.right
 
102
            
 
103
    def update(self):
 
104
        self.rect.move_ip(self.facing, 0)
 
105
        if not SCREENRECT.contains(self.rect):
 
106
            self.facing = -self.facing;
 
107
            self.rect.top = self.rect.bottom + 1
 
108
            self.rect = self.rect.clamp(SCREENRECT)
 
109
        self.frame = self.frame + 1
 
110
        self.image = self.images[self.frame/self.animcycle%3]
 
111
 
 
112
 
 
113
class Explosion(pygame.sprite.Sprite):
 
114
    defaultlife = 12
 
115
    animcycle = 3
 
116
    images = []
 
117
    def __init__(self, actor):
 
118
        pygame.sprite.Sprite.__init__(self, self.containers)
 
119
        self.image = self.images[0]
 
120
        self.rect = self.image.get_rect()
 
121
        self.life = self.defaultlife
 
122
        self.rect.center = actor.rect.center
 
123
        
 
124
    def update(self):
 
125
        self.life = self.life - 1
 
126
        self.image = self.images[self.life/self.animcycle%2]
 
127
        if self.life <= 0: self.kill()
 
128
 
 
129
 
 
130
class Shot(pygame.sprite.Sprite):
 
131
    speed = -11
 
132
    images = []
 
133
    def __init__(self, pos):
 
134
        pygame.sprite.Sprite.__init__(self, self.containers)
 
135
        self.image = self.images[0]
 
136
        self.rect = self.image.get_rect()
 
137
        self.rect.midbottom = pos
 
138
 
 
139
    def update(self):
 
140
        self.rect.move_ip(0, self.speed)
 
141
        if self.rect.top <= 0:
 
142
            self.kill()
 
143
 
 
144
 
 
145
class Bomb(pygame.sprite.Sprite):
 
146
    speed = 9
 
147
    images = []
 
148
    def __init__(self, alien):
 
149
        pygame.sprite.Sprite.__init__(self, self.containers)
 
150
        self.image = self.images[0]
 
151
        self.rect = self.image.get_rect()
 
152
        self.rect.centerx = alien.rect.centerx
 
153
        self.rect.bottom = alien.rect.bottom + 5
 
154
 
 
155
    def update(self):
 
156
        self.rect.move_ip(0, self.speed)
 
157
        if self.rect.bottom >= 470:
 
158
            Explosion(self)
 
159
            self.kill()
 
160
 
 
161
 
 
162
class Score(pygame.sprite.Sprite):
 
163
    def __init__(self):
 
164
        pygame.sprite.Sprite.__init__(self)
 
165
        self.font = pygame.font.Font(None, 20)
 
166
        self.font.set_italic(1)
 
167
        self.color = 255, 255, 255
 
168
        self.lastscore = -1
 
169
        self.update()
 
170
        self.rect = self.image.get_rect().move(10, 450)
 
171
        
 
172
    def update(self):
 
173
        if SCORE != self.lastscore:
 
174
            self.lastscore = SCORE
 
175
            msg = "Score: %d" % SCORE
 
176
            self.image = self.font.render(msg, 0, self.color)
 
177
            
 
178
 
 
179
 
 
180
def main(winstyle = 0):
 
181
    # Initialize pygame
 
182
    pygame.init()
 
183
    if pygame.mixer and not pygame.mixer.get_init():
 
184
        print 'Warning, no sound'
 
185
        pygame.mixer = None
 
186
 
 
187
    # Set the display mode
 
188
    winstyle = 0  # |FULLSCREEN
 
189
    bestdepth = pygame.display.mode_ok(SCREENRECT.size, winstyle, 32)
 
190
    screen = pygame.display.set_mode(SCREENRECT.size, winstyle, bestdepth)
 
191
 
 
192
    #Load images, assign to sprite classes
 
193
    #(do this before the classes are used, after screen setup)
 
194
    img = load_image('player1.gif')
 
195
    Player.images = [img, pygame.transform.flip(img, 1, 0)]
 
196
    img = load_image('explosion1.gif')
 
197
    Explosion.images = [img, pygame.transform.flip(img, 1, 1)]
 
198
    Alien.images = load_images('alien1.gif', 'alien2.gif', 'alien3.gif')
 
199
    Bomb.images = [load_image('bomb.gif')]
 
200
    Shot.images = [load_image('shot.gif')]
 
201
 
 
202
    #decorate the game window
 
203
    icon = pygame.transform.scale(Alien.images[0], (32, 32))
 
204
    pygame.display.set_icon(icon)
 
205
    pygame.display.set_caption('Pygame Aliens')
 
206
    pygame.mouse.set_visible(0)
 
207
 
 
208
    #create the background, tile the bgd image
 
209
    bgdtile = load_image('background.gif')
 
210
    background = pygame.Surface(SCREENRECT.size)
 
211
    for x in range(0, SCREENRECT.width, bgdtile.get_width()):
 
212
        background.blit(bgdtile, (x, 0))
 
213
    screen.blit(background, (0,0))
 
214
    pygame.display.flip()
 
215
 
 
216
    #load the sound effects
 
217
    boom_sound = load_sound('boom.wav')
 
218
    shoot_sound = load_sound('car_door.wav')
 
219
    if pygame.mixer:
 
220
        music = os.path.join('data', 'house_lo.wav')
 
221
        pygame.mixer.music.load(music)
 
222
        pygame.mixer.music.play(-1)
 
223
 
 
224
    # Initialize Game Groups
 
225
    aliens = pygame.sprite.Group()
 
226
    shots = pygame.sprite.Group()
 
227
    bombs = pygame.sprite.Group()
 
228
    all = pygame.sprite.RenderUpdates()
 
229
    lastalien = pygame.sprite.GroupSingle()
 
230
 
 
231
    #assign default groups to each sprite class
 
232
    Player.containers = all
 
233
    Alien.containers = aliens, all, lastalien
 
234
    Shot.containers = shots, all
 
235
    Bomb.containers = bombs, all
 
236
    Explosion.containers = all
 
237
    Score.containers = all
 
238
 
 
239
    #Create Some Starting Values
 
240
    global score
 
241
    alienreload = ALIEN_RELOAD
 
242
    kills = 0
 
243
    clock = pygame.time.Clock()
 
244
 
 
245
    #initialize our starting sprites
 
246
    global SCORE
 
247
    player = Player()
 
248
    Alien() #note, this 'lives' because it goes into a sprite group
 
249
    if pygame.font:
 
250
        all.add(Score())
 
251
 
 
252
 
 
253
    while player.alive():
 
254
 
 
255
        #get input
 
256
        for event in pygame.event.get():
 
257
            if event.type == QUIT or \
 
258
                (event.type == KEYDOWN and event.key == K_ESCAPE):
 
259
                    return
 
260
        keystate = pygame.key.get_pressed()
 
261
 
 
262
        # clear/erase the last drawn sprites
 
263
        all.clear(screen, background)
 
264
        
 
265
        #update all the sprites
 
266
        all.update()
 
267
 
 
268
        #handle player input
 
269
        direction = keystate[K_RIGHT] - keystate[K_LEFT]
 
270
        player.move(direction)
 
271
        firing = keystate[K_SPACE]
 
272
        if not player.reloading and firing and len(shots) < MAX_SHOTS:
 
273
            Shot(player.gunpos())
 
274
            shoot_sound.play()
 
275
        player.reloading = firing
 
276
 
 
277
        # Create new alien
 
278
        if alienreload:
 
279
            alienreload -= 1
 
280
        elif not int(random.random() * ALIEN_ODDS):
 
281
            Alien()
 
282
            alienreload = ALIEN_RELOAD
 
283
 
 
284
        # Drop bombs
 
285
        if lastalien and not int(random.random() * BOMB_ODDS):
 
286
            Bomb(lastalien.sprite)
 
287
 
 
288
        # Detect collisions
 
289
        for alien in pygame.sprite.spritecollide(player, aliens, 1):
 
290
            boom_sound.play()
 
291
            Explosion(alien)
 
292
            Explosion(player)
 
293
            SCORE = SCORE + 1
 
294
            player.kill()
 
295
 
 
296
        for alien in pygame.sprite.groupcollide(shots, aliens, 1, 1).keys():
 
297
            boom_sound.play()
 
298
            Explosion(alien)
 
299
            SCORE = SCORE + 1
 
300
                    
 
301
        for bomb in pygame.sprite.spritecollide(player, bombs, 1):         
 
302
            boom_sound.play()
 
303
            Explosion(player)
 
304
            Explosion(bomb)
 
305
            player.kill()
 
306
 
 
307
        #draw the scene
 
308
        dirty = all.draw(screen)
 
309
        pygame.display.update(dirty)
 
310
 
 
311
        #cap the framerate
 
312
        clock.tick(40)
 
313
 
 
314
    if pygame.mixer:
 
315
        pygame.mixer.music.fadeout(1000)
 
316
    pygame.time.wait(1000)
 
317
   
 
318
 
 
319
 
 
320
#call the "main" function if running this script
 
321
if __name__ == '__main__': main()
 
322