5
#import basic pygame modules
7
from pygame.locals import *
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"
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)
24
"loads an image, prepares it for play"
25
file = os.path.join('data', file)
27
surface = pygame.image.load(file)
29
raise SystemExit, 'Could not load image "%s" %s'%(file, pygame.get_error())
30
return surface.convert()
32
def load_images(*files):
33
return [load_image(file) for file in files]
40
if not pygame.mixer: return dummysound()
41
file = os.path.join('data', file)
43
sound = pygame.mixer.Sound(file)
46
print 'Warning, unable to load,', file
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
60
class Player(pygame.sprite.Sprite):
66
pygame.sprite.Sprite.__init__(self, self.containers)
67
self.image = self.images[0]
68
self.rect = self.image.get_rect()
70
self.rect.centerx = SCREENRECT.centerx
71
self.rect.bottom = SCREENRECT.bottom - 1
72
self.origtop = self.rect.top
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)
80
self.image = self.images[0]
82
self.image = self.images[1]
83
self.rect.top = self.origtop - (self.rect.left/self.bounce%2)
86
pos = self.facing*self.gun_offset + self.rect.centerx
87
return pos, self.rect.top
90
class Alien(pygame.sprite.Sprite):
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
101
self.rect.right = SCREENRECT.right
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]
113
class Explosion(pygame.sprite.Sprite):
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
125
self.life = self.life - 1
126
self.image = self.images[self.life/self.animcycle%2]
127
if self.life <= 0: self.kill()
130
class Shot(pygame.sprite.Sprite):
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
140
self.rect.move_ip(0, self.speed)
141
if self.rect.top <= 0:
145
class Bomb(pygame.sprite.Sprite):
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
156
self.rect.move_ip(0, self.speed)
157
if self.rect.bottom >= 470:
162
class Score(pygame.sprite.Sprite):
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
170
self.rect = self.image.get_rect().move(10, 450)
173
if SCORE != self.lastscore:
174
self.lastscore = SCORE
175
msg = "Score: %d" % SCORE
176
self.image = self.font.render(msg, 0, self.color)
180
def main(winstyle = 0):
183
if pygame.mixer and not pygame.mixer.get_init():
184
print 'Warning, no sound'
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)
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')]
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)
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()
216
#load the sound effects
217
boom_sound = load_sound('boom.wav')
218
shoot_sound = load_sound('car_door.wav')
220
music = os.path.join('data', 'house_lo.wav')
221
pygame.mixer.music.load(music)
222
pygame.mixer.music.play(-1)
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()
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
239
#Create Some Starting Values
241
alienreload = ALIEN_RELOAD
243
clock = pygame.time.Clock()
245
#initialize our starting sprites
248
Alien() #note, this 'lives' because it goes into a sprite group
253
while player.alive():
256
for event in pygame.event.get():
257
if event.type == QUIT or \
258
(event.type == KEYDOWN and event.key == K_ESCAPE):
260
keystate = pygame.key.get_pressed()
262
# clear/erase the last drawn sprites
263
all.clear(screen, background)
265
#update all the sprites
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())
275
player.reloading = firing
280
elif not int(random.random() * ALIEN_ODDS):
282
alienreload = ALIEN_RELOAD
285
if lastalien and not int(random.random() * BOMB_ODDS):
286
Bomb(lastalien.sprite)
289
for alien in pygame.sprite.spritecollide(player, aliens, 1):
296
for alien in pygame.sprite.groupcollide(shots, aliens, 1, 1).keys():
301
for bomb in pygame.sprite.spritecollide(player, bombs, 1):
308
dirty = all.draw(screen)
309
pygame.display.update(dirty)
315
pygame.mixer.music.fadeout(1000)
316
pygame.time.wait(1000)
320
#call the "main" function if running this script
321
if __name__ == '__main__': main()