Complete Game Setup and Main Loop
Now, we'll complete the game setup and create the main game loop, where all the game logic and interactions will take place.
## ... (code from step 4)
def main(winstyle=0):
## ... (previous code)
## decorate the game window
icon = pg.transform.scale(Alien.images[0], (32, 32))
pg.display.set_icon(icon)
pg.display.set_caption("Pygame Aliens")
pg.mouse.set_visible(0)
## create the background, tile the bgd image
bgdtile = load_image("background.gif")
background = pg.Surface(SCREENRECT.size)
for x in range(0, SCREENRECT.width, bgdtile.get_width()):
background.blit(bgdtile, (x, 0))
screen.blit(background, (0, 0))
pg.display.flip()
## load the sound effects
boom_sound = load_sound("boom.wav")
shoot_sound = load_sound("car_door.wav")
if pg.mixer:
music = os.path.join(main_dir, "data", "house_lo.wav")
pg.mixer.music.load(music)
pg.mixer.music.play(-1)
## Initialize Game Groups
aliens = pg.sprite.Group()
shots = pg.sprite.Group()
bombs = pg.sprite.Group()
all = pg.sprite.RenderUpdates()
lastalien = pg.sprite.GroupSingle()
## Create Some Starting Values
alienreload = ALIEN_RELOAD
clock = pg.time.Clock()
## initialize our starting sprites
global SCORE
player = Player(all)
Alien(
aliens, all, lastalien
) ## note, this 'lives' because it goes into a sprite group
if pg.font:
all.add(Score(all))
## Run our main loop whilst the player is alive.
while player.alive():
## get input
for event in pg.event.get():
if event.type == pg.QUIT:
return
if event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
return
if event.type == pg.KEYDOWN:
if event.key == pg.K_f:
if not fullscreen:
print("Changing to FULLSCREEN")
screen_backup = screen.copy()
screen = pg.display.set_mode(
SCREENRECT.size, winstyle | pg.FULLSCREEN, bestdepth
)
screen.blit(screen_backup, (0, 0))
else:
print("Changing to windowed mode")
screen_backup = screen.copy()
screen = pg.display.set_mode(
SCREENRECT.size, winstyle, bestdepth
)
screen.blit(screen_backup, (0, 0))
pg.display.flip()
fullscreen = not fullscreen
keystate = pg.key.get_pressed()
## clear/erase the last drawn sprites
all.clear(screen, background)
## update all the sprites
all.update()
## handle player input
direction = keystate[pg.K_RIGHT] - keystate[pg.K_LEFT]
player.move(direction)
firing = keystate[pg.K_SPACE]
if not player.reloading and firing and len(shots) < MAX_SHOTS:
Shot(player.gunpos(), shots, all)
if pg.mixer and shoot_sound is not None:
shoot_sound.play()
player.reloading = firing
## Create new alien
if alienreload:
alienreload = alienreload - 1
elif not int(random.random() * ALIEN_ODDS):
Alien(aliens, all, lastalien)
alienreload = ALIEN_RELOAD
## Drop bombs
if lastalien and not int(random.random() * BOMB_ODDS):
Bomb(lastalien.sprite, all, bombs, all)
## Detect collisions between aliens and players.
for alien in pg.sprite.spritecollide(player, aliens, 1):
if pg.mixer and boom_sound is not None:
boom_sound.play()
Explosion(alien, all)
Explosion(player, all)
SCORE = SCORE + 1
player.kill()
## See if shots hit the aliens.
for alien in pg.sprite.groupcollide(aliens, shots, 1, 1).keys():
if pg.mixer and boom_sound is not None:
boom_sound.play()
Explosion(alien, all)
SCORE = SCORE + 1
## See if alien bombs hit the player.
for bomb in pg.sprite.spritecollide(player, bombs, 1):
if pg.mixer and boom_sound is not None:
boom_sound.play()
Explosion(player, all)
Explosion(bomb, all)
player.kill()
## draw the scene
dirty = all.draw(screen)
pg.display.update(dirty)
## cap the framerate at 40fps. Also called 40HZ or 40 times per second.
clock.tick(40)
if pg.mixer:
pg.mixer.music.fadeout(1000)
pg.time.wait(1000)
## call the "main" function if running this script
if __name__ == "__main__":
main()
pg.quit()
In the main function, we initialize game groups for various entities, create starting values, and implement the main game loop. The game logic, player input handling, collisions, and drawing of the game scene are performed within this loop.
Running the Game
Now, we can run the game by executing the following command:
cd ~/project
python aliens.py