######################################################################################################################## # programmed by Zachary Hunter # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ######################################################################################################################## import pygame, random, sys, time from pygame.locals import * #set up some variables WINDOWWIDTH = 1024 WINDOWHEIGHT = 600 FPS = 6000 ZOMBIESIZE =40 CRAWLERSIZE = 55 ADDNEWZOMBIERATE = 30 ADDNEWCRAWLERRATE = ADDNEWZOMBIERATE NORMALZOMBIESPEED = 10 CRAWLERZOMBIESPEED = NORMALZOMBIESPEED / 2 PLAYERMOVERATE = 20 BULLETSPEED = 50 ADDNEWBULLETRATE = 10 highScore = 0 TEXTCOLOR = (255, 255, 255) RED = (255, 0, 0) def terminate(): pygame.quit() sys.exit() def waitForPlayerToPressKey(): while True: for event in pygame.event.get(): if event.type == QUIT: terminate() if event.type == KEYDOWN: if event.key == K_ESCAPE: # pressing escape quits terminate() if event.key == K_RETURN: return if event.key == ord('q'): return def playerHasHitZombie(playerRect, zombies): for z in zombies: if playerRect.colliderect(z['rect']): return True return False def bulletHasHitZombie(bullets, zombies): for b in bullets: if b['bulletRect'].colliderect(z['rect']): return True return False def bulletHasHitCrawler(bullets, crawlers): for b in bullets: if b['bulletRect'].colliderect(c['rect']): return True return False def drawText(text, font, surface, x, y): textobj = font.render(text, 1, TEXTCOLOR) textrect = textobj.get_rect() textrect.topleft = (x, y) surface.blit(textobj, textrect) def showScore(): drawText('creepers gotten past: %s' % (zombiesGottenPast), font, windowSurface, 10, 0) drawText('score: %s' % (score), font, windowSurface, 10, 30) def closeHighScoreTextFile(): #highScoreText.flush highScoreText.close # set up pygame, the window, and the mouse cursor pygame.init() mainClock = pygame.time.Clock() windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), pygame.FULLSCREEN) pygame.display.set_caption('Creeper Defence') pygame.mouse.set_visible(False) # set up fonts font = pygame.font.SysFont(None, 48) # set up sounds gameOverSound = pygame.mixer.Sound('gameover.mp3') pygame.mixer.music.load('aether2.ogg') # set up images playerImage = pygame.image.load('player.png') playerRect = playerImage.get_rect() bulletImage = pygame.image.load('bullet.png') bulletRect = bulletImage.get_rect() zombieImage = pygame.image.load('Creeper.png') crawlerImage = pygame.image.load('crawler.png') backgroundImage = pygame.image.load('background.png') rescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT)) # show the "Start" screen windowSurface.blit(rescaledBackground, (0, 0)) pygame.draw.line(windowSurface, RED, (WINDOWWIDTH / 2 + 20, WINDOWHEIGHT - 50), (WINDOWWIDTH / 2 + 20, 0), 1) windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)) drawText('Creeper Defence', font, windowSurface, (WINDOWWIDTH / 2) - 105, (WINDOWHEIGHT / 3)) drawText('Press Enter to start', font, windowSurface, (WINDOWWIDTH / 2) - 135, (WINDOWHEIGHT / 3) + 50) pygame.display.update() waitForPlayerToPressKey() while True: # set up the start of the game zombies = [] crawlers = [] bullets = [] zombiesGottenPast = 0 score = 0 playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50) moveLeft = moveRight = False shoot = False zombieAddCounter = 0 crawlerAddCounter = 0 bulletAddCounter = 40 pygame.mixer.music.play(-1, 0.0) while True: # the game loop runs while the game part is playing for event in pygame.event.get(): if event.type == QUIT: terminate() if event.type == KEYDOWN: if event.key == K_LEFT or event.key == ord('a'): moveRight = False moveLeft = True if event.key == K_RIGHT or event.key == ord('d'): moveLeft = False moveRight = True if event.key == K_SPACE: shoot = True if event.type == KEYUP: if event.key == K_ESCAPE: terminate() if event.key == K_LEFT or event.key == ord('a'): moveLeft = False if event.key == K_RIGHT or event.key == ord('d'): moveRight = False if event.key == K_SPACE: shoot = False # Add new zombies at the top of the screen, if needed. zombieAddCounter += 1 if zombieAddCounter == ADDNEWCRAWLERRATE: zombieAddCounter = 0 zombieSize = ZOMBIESIZE newZombie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-zombieSize), 0 - zombieSize, zombieSize, zombieSize), 'surface':pygame.transform.scale(zombieImage, (zombieSize, zombieSize)), } zombies.append(newZombie) # Add new crawlers at the top of the screen, if needed. crawlerAddCounter += 1 if crawlerAddCounter == ADDNEWZOMBIERATE: crawlerAddCounter = 0 crawlerSize = CRAWLERSIZE newCrawler = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-crawlerSize), 0 - crawlerSize, crawlerSize, crawlerSize), 'surface':pygame.transform.scale(crawlerImage, (crawlerSize, crawlerSize * 2)), } crawlers.append(newCrawler) # add new bullet bulletAddCounter += 1 if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True: bulletAddCounter = 100000 bulletSize = (15, 5) newBullet = {'bulletRect': windowSurface.blit(bulletImage, (playerRect.centerx - 2,playerRect.centery))} bullets.append(newBullet) # Move the player around. if moveLeft and playerRect.left > 0: playerRect.move_ip(-1 * PLAYERMOVERATE, 0) if moveRight and playerRect.right < WINDOWWIDTH: playerRect.move_ip(PLAYERMOVERATE, 0) # Move the zombies down. for z in zombies: z['rect'].move_ip(0, NORMALZOMBIESPEED) # Move the crawlers down. for c in crawlers: c['rect'].move_ip(0, CRAWLERZOMBIESPEED) # move the bullet for b in bullets: b['bulletRect'].move_ip(0, -1 * BULLETSPEED) # Delete zombies that have fallen past the bottom. for z in zombies[:]: if z['rect'].top > WINDOWHEIGHT: zombies.remove(z) zombiesGottenPast += 1 # Delete crawlers that have fallen past the bottom. for c in crawlers[:]: if c['rect'].top > WINDOWHEIGHT: crawlers.remove(c) zombiesGottenPast += 1 # check if the bullet has hit the zombie for z in zombies: if bulletHasHitZombie(bullets, zombies): score += 1 zombies.remove(z) bullets.remove(b) for c in crawlers: if bulletHasHitCrawler(bullets, crawlers): score += 1 crawlers.remove(c) bullets.remove(b) # delete bullets going past the top for b in bullets[:]: if b['bulletRect'].top < 0: bullets.remove(b) # Draw the game world on the window. windowSurface.blit(rescaledBackground, (0, 0)) # Draw the player's rectangle, rails pygame.draw.line(windowSurface, RED, (playerRect.centerx - 1, playerRect.centery - 20), (playerRect.centerx - 1, 0), 1) windowSurface.blit(playerImage, playerRect) # Draw each baddie for z in zombies: windowSurface.blit(z['surface'], z['rect']) for c in crawlers: windowSurface.blit(c['surface'], c['rect']) # draw each bullet for b in bullets: windowSurface.blit(bulletImage, b['bulletRect']) # Draw the score and how many zombies got past showScore() # update the display pygame.display.update() # Check if any of the zombies has hit the player. if playerHasHitZombie(playerRect, zombies): break if playerHasHitZombie(playerRect, crawlers): break # check if score is over 5 which means game over if zombiesGottenPast >= 5: break mainClock.tick(FPS) # Stop the game and show the "Game Over" screen. pygame.mixer.music.stop() gameOverSound.play() time.sleep(0.1) if zombiesGottenPast >= 5: windowSurface.blit(rescaledBackground, (0, 0)) pygame.draw.line(windowSurface, RED, (WINDOWWIDTH / 2 + 20, WINDOWHEIGHT - 50), (WINDOWWIDTH / 2 + 20, 0), 1) windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)) showScore() drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 2) - 85, (WINDOWHEIGHT / 3)) drawText('you let to many zombies get past', font, windowSurface, (WINDOWWIDTH / 2)- 115, (WINDOWHEIGHT / 3) + 100) drawText('Press enter to play again or escape to exit', font, windowSurface, (WINDOWWIDTH / 3) - 215, (WINDOWHEIGHT / 3) + 150) pygame.display.update() waitForPlayerToPressKey() if playerHasHitZombie(playerRect, zombies): windowSurface.blit(rescaledBackground, (0, 0)) pygame.draw.line(windowSurface, RED, (WINDOWWIDTH / 2 + 20, WINDOWHEIGHT - 50), (WINDOWWIDTH / 2 + 20, 0), 1) windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)) showScore() drawText('GAME OVER!', font, windowSurface, (WINDOWWIDTH / 2) - 85, (WINDOWHEIGHT / 3)) drawText('a zombie has hit you!', font, windowSurface, (WINDOWWIDTH / 2.1) - 115, (WINDOWHEIGHT / 3) +100) drawText('Press enter to play again or escape to exit.', font, windowSurface, (WINDOWWIDTH / 2.5) - 215, (WINDOWHEIGHT / 3) + 150) pygame.display.update() waitForPlayerToPressKey() gameOverSound.stop()