Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''
- Game made by @Tititesouris
- Graphics made by @_Inaar
- 28/04/2014 - 29/04/2014
- Ludum Dare - Beneath the surface
- '''
- from math import *
- import pygame, os, time, random, sys, json
- from pygame.locals import *
- from cx_Freeze import setup, Executable
- pygame.mixer.pre_init(44100, -16, 2, 2048) #Initialise the mixer
- pygame.init() #Initialise Pygame
- os.environ["SDL_VIDEO_WINDOW_POS"] = "{0}, {1}".format(50, 50) #Window origin
- windowSize = [800, 600] #Window size
- window = pygame.display.set_mode((windowSize[0], windowSize[1])) #Creating window
- pygame.display.set_caption("Window") #Window title
- font = pygame.font.SysFont("Lucida Console", 18) #Font
- bigFont = pygame.font.SysFont("Lucida Console", 30) #Font
- '''
- Global functions
- '''
- def getTime(): #Returns the current timestamp
- return int(round(time.time()*1000))
- def isTime(time): #Is time a past timestamp
- if getTime() > time:
- return True
- else:
- return False
- def randNb(min=0, max=1): #Returns a random integer between min and max inclusive
- return random.randint(min, max)
- def randItem(list): #Returns a random element from list
- return random.choice(list)
- def write(window, font, text, coords, colour=(0, 0, 0)):
- window.blit(font.render(str(text), 1, colour), coords)
- def drawRect(window, rectangle, colour=(255, 255, 255), thickness=1):
- pygame.draw.rect(window, colour, rectangle, thickness)
- def drawCircle(window, coords, radius, colour=(255, 255, 255), thickness=1):
- pygame.draw.circle(window, colour, coords, radius, thickness)
- def play(sound): #Play sound
- sound.set_volume(0.5)
- sound.play()
- def playMusic(music, loop=-1): #Play music
- music.set_volume(0.5)
- music.play(loop)
- '''
- Images and sounds
- '''
- backgroundImage = pygame.image.load("images/background.png")
- turtleImage = [pygame.image.load("images/turtles.png").subsurface(140*i, 0, 140, 80) for i in range(6)]
- deadTurtleImage = pygame.image.load("images/deadturtle.png")
- barrelRollImage = pygame.image.load("images/barrelroll.png")
- junkImages = {junk.split(".png")[0]: pygame.image.load("images/junks/{0}".format(junk)) for junk in os.listdir("images/junks")}
- music = pygame.mixer.Sound("sounds/music.wav") #Easy Lemon incompetech.com
- sadMusic = pygame.mixer.Sound("sounds/sadmusic.wav") #Virtutes Instrumenti incompetech.com
- deathSound = pygame.mixer.Sound("sounds/death.wav")
- barrelRollSound = pygame.mixer.Sound("sounds/barrelroll.wav")
- '''
- Global variables
- '''
- press = {
- "up": False,
- "right": False,
- "down": False,
- "left": False,
- }
- isGameRunning = True
- '''
- Classes
- '''
- class engine:
- def __init__(self):
- self.startTime = getTime()+3000
- self.moveInterval = 5
- self.nextMove = self.startTime
- self.gravityPullInterval = 50
- self.nextGravityPull = self.startTime
- self.moveJunkInterval = 4
- self.nextMoveJunk = self.startTime
- self.spawnInterval = 2000
- self.nextSpawn = self.startTime+1000
- self.levelInterval = 10000
- self.nextLevel = self.startTime+self.levelInterval
- self.staminaInterval = 300
- self.nextStamina = self.startTime+self.staminaInterval
- self.barrelRollTime = 2000
- self.endBarrelRoll = 0
- self.paused = False
- def tick(self):
- if isTime(self.startTime) and not self.paused:
- if not GAME.gameOver:
- if not pygame.key.get_focused(): #Window loses focus
- self.paused = True
- GAME.pausedTime = getTime()
- if isTime(self.nextMove): #Turtle move
- if press["up"] and not press["down"]:
- TURTLE.move("up")
- elif press["down"] and not press["up"]:
- TURTLE.move("down")
- if press["right"] and not press["left"]:
- TURTLE.move("right")
- elif press["left"] and not press["right"]:
- TURTLE.move("left")
- self.nextMove = getTime()+self.moveInterval
- if isTime(self.nextMoveJunk): #Junk move
- JUNK.move()
- self.nextMoveJunk = getTime()+self.moveJunkInterval
- if isTime(self.nextSpawn): #Junk spawn
- JUNK.spawn()
- JUNK.destroy()
- self.nextSpawn = getTime()+self.spawnInterval
- if isTime(self.nextLevel): #Level up
- GAME.level += 1
- JUNK.speed += 1
- TURTLE.swimming = max(10, TURTLE.swimming-20)
- GAME.waveSpeed = max(1, GAME.waveSpeed-2)
- self.spawnInterval = max(600, self.spawnInterval - 500)
- self.levelInterval += GAME.level*10000
- self.nextLevel = getTime()+self.levelInterval
- if TURTLE.barrelRolling and isTime(self.endBarrelRoll):
- TURTLE.barrelRolling = False
- elif isTime(self.nextStamina) and TURTLE.stamina < 100:
- TURTLE.stamina += 1
- self.nextStamina = getTime()+self.staminaInterval
- TURTLE.contact()
- if isTime(self.nextGravityPull):
- if GAME.gameOver or (not GAME.gameOver and TURTLE.position[1] < windowSize[1]-TURTLE.size[1]):
- TURTLE.position[1] += 1
- self.nextGravityPull = getTime()+self.gravityPullInterval
- ENGINE = engine()
- class turtle:
- def __init__(self):
- self.size = [140, 80]
- self.position = [windowSize[0]//2-self.size[0], windowSize[1]//2]
- self.speed = 6
- self.barrelRolling = False
- self.stamina = 100
- self.swimming = 100
- def move(self, direction):
- if not self.barrelRolling:
- if direction == "up" and self.position[1] > GAME.surface:
- self.position[1] -= self.speed
- elif direction == "right" and self.position[0] < windowSize[0]-self.size[0]:
- self.position[0] += self.speed
- elif direction == "down" and self.position[1] < windowSize[1]-self.size[1]:
- self.position[1] += self.speed
- elif direction == "left" and self.position[0] > 0:
- self.position[0] -= self.speed
- def contact(self):
- if not self.barrelRolling:
- touch = False
- for junk in JUNK.junks:
- if junk["position"][0]+JUNK.size[0] > self.position[0] > junk["position"][0]-self.size[0] and junk["position"][1]+JUNK.size[1] > self.position[1] > junk["position"][1]-self.size[1]:
- touch = True
- break
- if touch:
- GAME.gameOver = True
- GAME.finishTime = getTime()-GAME.time
- pygame.mixer.stop()
- play(deathSound)
- playMusic(sadMusic)
- def barrelRoll(self):
- if not self.barrelRolling and self.stamina == 100 and isTime(ENGINE.startTime) and not ENGINE.paused:
- self.barrelRolling = True
- self.stamina = 0
- ENGINE.endBarrelRoll = getTime()+ENGINE.barrelRollTime
- play(barrelRollSound)
- TURTLE = turtle()
- class junk:
- def __init__(self):
- self.junks = []
- self.size = [55, 55]
- self.speed = 4
- def spawn(self):
- spawnPoints = [i for i in range(((windowSize[1]-self.size[1])-GAME.surface)//TURTLE.size[1]+1)]
- for i in range(randItem([1]*(GAME.level+1)+[randNb(1, max(1, min(6, GAME.level)))])):
- spawnPoint = randItem(spawnPoints)
- spawnPoints.remove(spawnPoint)
- self.junks.append({
- "name": randItem(["Plastic Bag", "Water Bottle", "Coke Bottle", "Can", "Cigarette Pack"]),
- "position": [windowSize[0], GAME.surface+TURTLE.size[1]*spawnPoint],
- })
- def move(self):
- self.junks = [{"name": junk["name"], "position": [junk["position"][0]-self.speed, junk["position"][1]]} for junk in self.junks]
- def destroy(self):
- self.junks = [junk for junk in self.junks if junk["position"][0] >= -self.size[0]]
- JUNK = junk()
- class facts:
- def __init__(self):
- self.facts = [
- "More than 3 billion kilograms (7 billion pounds)\nof non-recyclable plastic is created every year.",
- "Only 7% of the plastic in the U.S.A. is recycled.\nLess than 5% of the plastic worldwide is recycled.",
- "Consider picking up every plastic debris you spot\nin the street, before they end up in the sea.",
- "All the junk in the oceans conglomerates\nto form 'Great Garbage Patches' or 'Trash Vortexes'.",
- "It's impossible to measure the size of a garbage patch\nbut using samples it's estimated that the Great Pacific Garbage Patch\nis twice the size of Texas.",
- "In the Great Pacific Garbage Patch there is\nmore plastic than plankton, the main food for many marine animals.",
- "Even the Mediterranean sea is full of junk\nwith 500 tonnes of trash floating around.",
- "If you played this game with realistic trash proportions\nyou wouldn't last more than 3 seconds.",
- "Hundreds of thousands of marine mammals and more than\n1 million seabirds die each year from ocean pollution.",
- "Sea turtles and other marine creatures mistake\nplastic bags for jellyfish. When ingesting them, it causes\nblockages in their digestive systems, leading to death.",
- "The plastic toxins end up in fish, which end up in our plates.",
- "More than 80% of the oceans' junk is plastic.",
- ]
- self.fact = 0
- def new(self):
- if self.fact < len(self.facts)-1:
- self.fact += 1
- else:
- self.fact = 0
- FACTS = facts()
- class game:
- def __init__(self):
- self.gameOver = False
- self.time = ENGINE.startTime
- self.level = 0
- self.highscore = 0
- self.waveAmplitude = 10 #Amplitude of the wave in pixel
- self.waveSpeed = 10 #Speed of the wave moving left, the lower the greater
- self.waveStrength = 400 #Speed of the wave moving up and down, the lower the greater
- self.wavePeriod = 50 #Spacial period in pixel
- self.surface = 100
- self.pausedTime = 0
- self.finishTime = 0
- def reset(self):
- if self.finishTime > self.highscore:
- json.dump(self.finishTime, open("save.txt", "w"))
- ENGINE.__init__()
- TURTLE.__init__()
- JUNK.__init__()
- GAME.__init__()
- self.highscore = json.load(open("save.txt", "r"))
- pygame.mixer.stop()
- playMusic(music)
- def display(self):
- window.blit(backgroundImage, (0, 0)) #Background
- write(window, font, "Stamina", (windowSize[0]-font.size("Stamina")[0]-35, 26)) #Stamina
- drawRect(window, (windowSize[0]-154, 0, 204, 24), (0, 0, 0), 0) #Stamina gauge border
- drawRect(window, (windowSize[0]-152, 2, TURTLE.stamina*1.5, 20), (0, 150, 50), 0) #Stamina gauge
- if not self.gameOver:
- if not TURTLE.barrelRolling:
- window.blit(turtleImage[floor(getTime()/TURTLE.swimming%6)], (TURTLE.position[0], TURTLE.position[1])) #Turtle
- else:
- middlePoint = ENGINE.endBarrelRoll-ENGINE.barrelRollTime//2
- distanceToMiddle = getTime()-middlePoint
- newSize = [round(TURTLE.size[0]*max(0.75, abs(sin(distanceToMiddle/(ENGINE.barrelRollTime/2))))), round(TURTLE.size[1]*max(0.75, abs(sin(distanceToMiddle/(ENGINE.barrelRollTime/2)))))]
- window.blit(pygame.transform.scale(barrelRollImage, (newSize[0], newSize[1])), (TURTLE.position[0]+(TURTLE.size[0]-newSize[0])//2, TURTLE.position[1]+(TURTLE.size[1]-newSize[1])//2)) #Barrel rolling turtle
- if isTime(ENGINE.startTime):
- for junk in JUNK.junks: #Junks
- window.blit(junkImages[junk["name"]], (junk["position"][0], junk["position"][1]))
- if not ENGINE.paused:
- write(window, bigFont, round((getTime()-self.time)/1000, 2), (0, 0)) #Time
- else:
- write(window, bigFont, round((self.pausedTime-self.time)/1000, 2), (0, 0)) #Time
- write(window, bigFont, "Press escape to unpause the game", (windowSize[0]//2-bigFont.size("Press escape to unpause the game")[0]//2, windowSize[1]//2), (190, 100, 10)) #Instructions
- else:
- write(window, bigFont, "Trash Rolling Turtle", (windowSize[0]//2-bigFont.size("Trash Rolling Turtle")[0]//2, windowSize[1]//2-4*bigFont.size("A")[1]), (190, 100, 10)) #Title
- write(window, bigFont, round((ENGINE.startTime-getTime())/1000), (TURTLE.position[0]+TURTLE.size[0]+50, TURTLE.position[1]+TURTLE.size[1]//2-bigFont.size("A")[1]//2)) #Countdown
- write(window, bigFont, "Press space to do a barrel roll", (windowSize[0]//2-bigFont.size("Press space to do a barrel roll")[0]//2, windowSize[1]//2-2*bigFont.size("A")[1])) #Instructions
- write(window, bigFont, "Survive as long as possible", (windowSize[0]//2-bigFont.size("Survive as long as possible")[0]//2, windowSize[1]//2+4*bigFont.size("A")[1])) #Instructions
- else:
- window.blit(deadTurtleImage, (TURTLE.position[0], TURTLE.position[1])) #Dead turtle
- if self.finishTime > self.highscore:
- write(window, bigFont, "New Record!", (windowSize[0]//2-bigFont.size("New Record!")[0]//2, windowSize[1]//2-4*bigFont.size("A")[1]), (190, 100, 10)) #New record
- write(window, bigFont, "Best: {0} seconds".format(round(self.finishTime/1000, 2)), (windowSize[0]//2-bigFont.size("Best: {0} seconds".format(round(self.finishTime/1000, 2)))[0]//2, windowSize[1]//2-3*bigFont.size("A")[1])) #Highscore
- else:
- write(window, bigFont, "Best: {0} seconds".format(round(self.highscore/1000, 2)), (windowSize[0]//2-bigFont.size("Best: {0} seconds".format(round(self.highscore/1000, 2)))[0]//2, windowSize[1]//2-3*bigFont.size("A")[1])) #Highscore
- write(window, bigFont, "{0} seconds".format(round(self.finishTime/1000, 2)), (windowSize[0]//2-bigFont.size("{0} seconds".format(round(self.finishTime/1000, 2)))[0]//2, windowSize[1]//2-2*bigFont.size("A")[1])) #Time
- fact = FACTS.facts[FACTS.fact].split("\n")
- for i in range(len(fact)):
- write(window, font, fact[i], (windowSize[0]//2-font.size(fact[i])[0]//2, windowSize[1]//2+i*font.size("A")[1])) #Fact
- write(window, bigFont, "Press space to retry", (windowSize[0]//2-bigFont.size("Press space to retry")[0]//2, windowSize[1]//2+(i+2)*font.size("A")[1]), (190, 100, 10)) #Instructions
- write(window, font, "Game made by @Tititesouris", (0, windowSize[1]-2*font.size("A")[1])) #Credits game
- write(window, font, "Graphics made by @_Inaar", (0, windowSize[1]-font.size("A")[1])) #Credits art
- write(window, font, "Music from incompetech.com", (windowSize[0]-font.size("Music from incompetech.com")[0], windowSize[1]-font.size("A")[1])) #Credits music
- for x in range(windowSize[0]+round(2*pi*self.wavePeriod)): #Waves
- drawCircle(window, (round(x-getTime()/self.waveSpeed%(2*pi*self.wavePeriod)), round(self.surface+(abs(sin(getTime()/self.waveStrength%(2*pi*self.wavePeriod)))+1)*self.waveAmplitude*sin(x/self.wavePeriod))), 1, (255, 255, 255), 0)
- GAME = game()
- '''
- Infinite loop
- '''
- GAME.reset()
- while isGameRunning:
- posMouse = pygame.mouse.get_pos() #Cursor position
- ### Events ###
- for event in pygame.event.get():
- if event.type == QUIT: #Closing window
- isGameRunning = False #Terminate programme
- if event.type == KEYDOWN: #Pushing key
- if event.key in [K_UP, K_w]:
- press["up"] = True
- if event.key in [K_RIGHT, K_d]:
- press["right"] = True
- if event.key in [K_DOWN, K_s]:
- press["down"] = True
- if event.key in [K_LEFT, K_a]:
- press["left"] = True
- if event.key == K_SPACE:
- if not GAME.gameOver:
- TURTLE.barrelRoll()
- else:
- GAME.reset()
- FACTS.new()
- if event.key == K_ESCAPE and isTime(ENGINE.startTime):
- if ENGINE.paused:
- ENGINE.paused = False
- GAME.time += getTime()-GAME.pausedTime
- ENGINE.nextSpawn += getTime()-GAME.pausedTime
- else:
- ENGINE.paused = True
- GAME.pausedTime = getTime()
- if event.type == KEYUP: #Releasing key
- if event.key in [K_UP, K_w]:
- press["up"] = False
- if event.key in [K_RIGHT, K_d]:
- press["right"] = False
- if event.key in [K_DOWN, K_s]:
- press["down"] = False
- if event.key in [K_LEFT, K_a]:
- press["left"] = False
- ENGINE.tick()
- GAME.display()
- pygame.display.update() #Display everything!
Add Comment
Please, Sign In to add comment