def initialize(self): print(f"Initializing the '{self.sceneName}' level...") # Loading resources (images, audio, etc.) before beginning scene Player.image = load_image("player.gif") Player.shootSound = load_sound("laser.ogg") Laser.image = load_image("laser.gif") Enemy.image = load_image("spider.gif") self.background = load_image("background2.gif").convert() # Initialize sprite group self.lasers = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self.all = pygame.sprite.RenderUpdates() # Assign groups to sprites Laser.containers = self.lasers, self.all Enemy.containers = self.aliens, self.all Player.containers = self.all Score.containers = self.all Lives.containers = self.all self.player = Player() self.score = Score() self.lives = Lives(self.player.lives) self.all.add(self.score) self.all.add(self.lives) self.generate_enemies()
class GameCompleteScene(Scene): _STIME = 8.5 def __init__(self, game): self.next = self self.game = game self.font = pygame.font.Font('fonts/ShareTechMono-Regular.ttf', 100) self.sfont = pygame.font.Font('fonts/ShareTechMono-Regular.ttf', 30) self.comptxt = self.font.render("Game Complete", True, WHITE) self.wstxt = self.sfont.render("good job, thanks for playing!", True, WHITE) self.player = Player(None, 30, 400) self.telapsed = 0.0 # stop main music and play victory sound effect self.game.jukebox.stop_music() self.game.jukebox.play_sfx('victory') # get totally num deaths this play through self.ndeath = self.game.get_ndeath() self.deathtxt = self.sfont.render("You died {0} times".format(self.ndeath), True, WHITE) if self.ndeath > 0: # it will be! self.deathtxt2 = self.sfont.render("Try for better next time", True, WHITE) else: self.deathtxt2 = self.sfont.render("Perfect!", True, WHITE) def render(self, screen): screen.blit(self.game.bg, (0, 0)) screen.blit(self.comptxt, (180, 40)) screen.blit(self.wstxt, (180, 180)) screen.blit(self.deathtxt, (180, 220)) screen.blit(self.deathtxt2, (180, 260)) screen.blit(self.player.image, self.player.rect) def process_input(self, events, pressed, dt): # hacky (sorry) pressed = {} for action in ALL_ACTIONS: pressed[action] = False pressed[RIGHT] = True self.player.contact = True self.player.process_input(None, pressed, dt) self.player.rect.x += dt*240 def update(self, dt): self.telapsed += dt if self.telapsed > self._STIME: self.next = TitleScene(self.game)
def __init__(self, game): self.next = self self.game = game self.font = pygame.font.Font('fonts/ShareTechMono-Regular.ttf', 100) self.sfont = pygame.font.Font('fonts/ShareTechMono-Regular.ttf', 30) self.comptxt = self.font.render("Game Complete", True, WHITE) self.wstxt = self.sfont.render("good job, thanks for playing!", True, WHITE) self.player = Player(None, 30, 400) self.telapsed = 0.0 # stop main music and play victory sound effect self.game.jukebox.stop_music() self.game.jukebox.play_sfx('victory') # get totally num deaths this play through self.ndeath = self.game.get_ndeath() self.deathtxt = self.sfont.render("You died {0} times".format(self.ndeath), True, WHITE) if self.ndeath > 0: # it will be! self.deathtxt2 = self.sfont.render("Try for better next time", True, WHITE) else: self.deathtxt2 = self.sfont.render("Perfect!", True, WHITE)
def __init__(self, screen, space, filename, input_handler, game_clock): # Open level file self.screen = screen self.space = space self.name = filename self.input_handler = input_handler self.game_clock = game_clock self.game_clock.reset() # Load level background and the objects in the level # level_width, level_width, background, powerups, platforms self._load(self.name) self.player = Player() self.player.body.position.x = 0 self.player.body.position.y = 100 self.gameobjects = pygame.sprite.Group() # Add objects to space self.player.add_to(self.space) for p in self.platforms: p.add_to(self.space) for p in self.powerups: p.add_to(self.space) # Bind input input_handler.bind_player(self.player) # Remember to unbind on level end
def setupPlayground(self): # libavg setup self.display = avg.DivNode(parent=self._parentNode, size=self._parentNode.size) self.renderer = Renderer() background = avg.ImageNode(parent=self.display) background.setBitmap(self.backgroundpic) self.display.player = None (displayWidth, displayHeight) = self.display.size widthThird = (int)(displayWidth / 3) fieldSize = (widthThird, displayHeight) self.field1 = avg.DivNode(parent=self.display, size=fieldSize) self.field2 = avg.DivNode(parent=self.display, size=fieldSize, pos=(displayWidth - widthThird, 0)) avg.LineNode(parent=self.display, pos1=(0, 1), pos2=(displayWidth, 1)) avg.LineNode(parent=self.display, pos1=(0, displayHeight), pos2=(displayWidth, displayHeight)) self.lines.createImageNode('layer1', dict(parent=self.display, pos=(widthThird, 0)), (2, displayHeight)) self.lines.createImageNode('layer1', dict(parent=self.display, pos=(displayWidth - widthThird, 0)), (2, displayHeight)) # pybox2d setup self.world = b2World(gravity=(0, 0), doSleep=True) self.hitset = set() self.listener = ContactListener(self.hitset) self.world.contactListener = self.listener self.running = True pointsToWin = 999 if self.tutorialMode else config.pointsToWin self.leftPlayer, self.rightPlayer = Player(self, self.field1, pointsToWin), Player(self, self.field2, pointsToWin) self.leftPlayer.other, self.rightPlayer.other = self.rightPlayer, self.leftPlayer # horizontal lines BorderLine(self.world, a2w((0, 1)), a2w((displayWidth, 1)), 1, False, 'redball') BorderLine(self.world, a2w((0, displayHeight)), a2w((displayWidth, displayHeight)), 1, False, 'redball') # vertical ghost lines maxWallHeight = brickSize * brickLines * PPM BorderLine(self.world, a2w((maxWallHeight, 0)), a2w((maxWallHeight, displayHeight)), 1, False, 'redball', 'ball') BorderLine(self.world, a2w((displayWidth - maxWallHeight - 1, 0)), a2w((displayWidth - maxWallHeight - 1, displayHeight)), 1, False, 'redball', 'ball') self.middleX, self.middleY = self.display.size / 2 self.middle = a2w((self.middleX, self.middleY)) BatManager(self.field1, self.world, self.renderer) BatManager(self.field2, self.world, self.renderer) self.bonus = None self.balls = [] self.redballs = [] self.towers = [] self.ghosts = [] self.mainLoop = g_player.setOnFrameHandler(self.step)
def __init__(self, window, space, filename, input_handler, game_clock): self.music = 'elec_Spin.wav' # Open level file self.window = window self.space = space self.name = filename self.input_handler = input_handler self.game_clock = game_clock self.game_clock.reset() #next level default is none self.next_level = "none" # Load level background and the objects in the level # level_width, level_width, background, powerups, platforms self._load(self.name) self.player = Player() self.player.body.position.x = 0 self.player.body.position.y = 100 self.gameobjects = pygame.sprite.Group() # Add objects to space self.player.add_to(self.space) for p in self.platforms: p.add_to(self.space) for p in self.powerups: p.add_to(self.space) # Bind input input_handler.bind_player(self.player) # Remember to unbind on level end # Create camera self.camera = Camera(self.window, self.level_width, self.level_height, self.player) print 'current level: ', self.name print 'next level: ', self.next_level
class GameScene(Scene): def __init__(self): super(GameScene, self).__init__() self.id = 2 self.sceneName = "game" self.spawnFactor = 0 self.speedFactor = 0 self.resetEnemy = False def initialize(self): print(f"Initializing the '{self.sceneName}' level...") # Loading resources (images, audio, etc.) before beginning scene Player.image = load_image("player.gif") Player.shootSound = load_sound("laser.ogg") Laser.image = load_image("laser.gif") Enemy.image = load_image("spider.gif") self.background = load_image("background2.gif").convert() # Initialize sprite group self.lasers = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self.all = pygame.sprite.RenderUpdates() # Assign groups to sprites Laser.containers = self.lasers, self.all Enemy.containers = self.aliens, self.all Player.containers = self.all Score.containers = self.all Lives.containers = self.all self.player = Player() self.score = Score() self.lives = Lives(self.player.lives) self.all.add(self.score) self.all.add(self.lives) self.generate_enemies() def handle_events(self, event): keystate = pygame.key.get_pressed() # Player using LEFT & RIGHT ARROWS to move direction = keystate[pygame.K_RIGHT] - keystate[pygame.K_LEFT] self.player.set_direction(direction) # Player presses SPACE to shoot self.player.firing = keystate[pygame.K_SPACE] def render(self, screen): screen.blit(self.background, (0, 0)) self.all.clear(screen, self.background) self.all.update() self.all.draw(screen) def update(self): if self.player.alive(): self.player.move() # Prevent overfiring/spamming lasers over max limit if not self.player.reloading and self.player.firing and len( self.lasers) < const.MAX_SHOT: Laser(self.player.gunpos()) Player.shootSound.play() self.player.reloading = self.player.firing else: # Player has died (lost all lives) self.go_to_gameover() # Enemy (group) direction change check for e1 in self.aliens: # An enemy reaches the edge of the screen, # then change all enemy's direction if e1.changeDirection: for e2 in self.aliens: e2.go_down() break #===------------------- # Collision detection for alien in pygame.sprite.spritecollide(self.player, self.aliens, 1): self.resetEnemy = True self.player.died() self.lives.set_lives(self.player.lives) if self.player.lives <= 0: self.player.kill() break for alien in pygame.sprite.groupcollide(self.lasers, self.aliens, 1, 1).keys(): self.score.increment() #===------------------- # Reset position of enemies if self.resetEnemy: self.resetEnemy = False for e in self.aliens: e.reset_position() if len(self.aliens) == 0: if self.speedFactor < const.MAX_SPEED_FACTOR: self.speedFactor += 1 self.generate_enemies() pygame.display.update() def generate_enemies(self): rows = random.randrange(2, 5) cols = random.randrange(5, 11) speed = random.randrange(const.MIN_E_SPEED + self.speedFactor, const.MAX_E_SPEED + self.speedFactor) facing = random.choice((-1, 1)) count = 0 offset_x = offset_y = 16 x_pos = y_pos = 0 for row in range(rows): for col in range(cols): count = count + 1 e = Enemy(count, speed, facing) e.set_position(x_pos, y_pos) x_pos = 32 + x_pos + offset_x x_pos = 0 y_pos = 32 + y_pos + offset_y def go_to_gameover(self): ApplicationManager().load_scene(GameOverScene(self.score.get_score()))
class Game(gameapp.GameApp): def init(self): gameobjects.displayWidth, gameobjects.displayHeight = self._parentNode.size gameobjects.bricksPerLine = (int)(self._parentNode.height / (brickSize * PPM)) gameobjects.preRender() self.bonusjob = None self.cleanup = None self.keepPushingBalls = None self.tutorialMode = False self.backgroundpic = None self.lines = None self.preRender() self.machine = statemachine.StateMachine('UPM', 'MainMenu') self.machine.addState('MainMenu', ['Playing', 'Tutorial', 'About'], enterFunc=self.showMenu, leaveFunc=self.hideMenu) self.machine.addState('Tutorial', ['MainMenu', 'Playing', 'Tutorial'], enterFunc=self.startTutorial, leaveFunc=self.hideTutorial) self.machine.addState('Playing', ['MainMenu'], enterFunc=self.startPlaying) self.machine.addState('About', ['MainMenu'], enterFunc=self.showAbout, leaveFunc=self.hideAbout) self.showMenu() def preRender(self): self.backgroundpic = avg.SVG('../data/img/char/background_dark.svg', False).renderElement('layer1', self._parentNode.size + (50, 50)) self.lines = avg.SVG('../data/img/btn/dotted_line.svg', False) def makeButtonInMiddle(self, name, node, yOffset, pyFunc): path = '../data/img/btn/' svg = avg.SVG(path + name + '_up.svg', False) height = node.height / 8 size = (height * 2.4, height) upNode = svg.createImageNode('layer1', {}, size) svg = avg.SVG(path + name + '_dn.svg', False) downNode = svg.createImageNode('layer1', {}, size) position = (node.pivot[0] - upNode.width / 2, node.pivot[1] + yOffset * upNode.height + yOffset * 50) return ui.TouchButton(upNode, downNode, clickHandler=pyFunc, parent=node, pos=position) def showMenu(self): self._createMenuBackground() self.menuScreen = avg.DivNode(parent=self._parentNode, size=self._parentNode.size) self.startButton = self.makeButtonInMiddle('start', self.menuScreen, -1, lambda:self.machine.changeState('Playing')) self.tutorialButton = self.makeButtonInMiddle('help', self.menuScreen, 0, lambda:self.machine.changeState('Tutorial')) self.aboutButton = self.makeButtonInMiddle('about', self.menuScreen, 1, lambda:self.machine.changeState('About')) self.exitButton = self.makeButtonInMiddle('exit', self.menuScreen, 2, lambda:exit(0)) def _createMenuBackground(self): self.nodeList = [] picList = [Ball.pic, Mine.leftPic, Mine.rightPic, RedBall.pic] + Ghost.pics.values() for i in range (1, 500): node = avg.ImageNode(parent=self._parentNode) node.setBitmap(random.choice(picList)) if i <= 250: pos = (random.randint(0, int(self._parentNode.width / 3 - ghostRadius * PPM * 2)), random.randint(0, int(self._parentNode.height - ghostRadius * PPM * 2))) else: pos = (random.randint(2 * int(self._parentNode.width / 3), int(self._parentNode.width)), random.randint(0, int(self._parentNode.height - ghostRadius * PPM * 2))) node.pos = pos self.nodeList.append(node) self.title = avg.WordsNode( parent=self._parentNode, pivot=(0, 0), text="UPM", pos=(self._parentNode.width / 2 - 100, 50), wrapmode="wordchar", font='Impact', color="00FF00", fontsize=100, variant="bold") def _destroyMenuBackground(self): for node in self.nodeList: node.active = False node.unlink(True) node = None if self.title is not None: self.title.active = False self.title.unlink(True) self.title = None def hideMenu(self): self._destroyMenuBackground() self.menuScreen.unlink(True) self.menuScreen = None def startTutorial(self): self.tutorialMode = True self.setupPlayground() g_player.setTimeout(config.startingTutorial, self.startBall) g_player.setTimeout(config.startingTutorial + config.ballTutorial, self.startGhosts) g_player.setTimeout(config.startingTutorial + config.ballTutorial + config.ghostTutorial, self.revealTetris) g_player.setTimeout(config.startingTutorial + config.ballTutorial + config.ghostTutorial + config.tetrisTutorial, self.revealBoni) def startPlaying(self): self.tutorialMode = False self.setupPlayground() TetrisBar(self.display) TetrisBar(self.display, left=False) self.revealTetris() g_player.setTimeout(config.tetrisTutorial, self.startMovement) def startMovement(self): self.startBall() self.createGhosts() self._bonusJob() def hideTutorial(self): self.tutorialMode = False def showAbout(self): self.aboutScreen = avg.DivNode(parent=self._parentNode, size=self._parentNode.size) avg.WordsNode(parent=self.aboutScreen, x=5, text='Unnamed Multipong<br/>as envisioned and implemented by<br/>Benjamin Guttman<br/>Joachim Couturier<br/>Philipp Hermann<br/>Mykola Havrikov<br/><br/>This game uses libavg(www.libavg.de) and PyBox2D(http://code.google.com/p/pybox2d/)') self.menuButton = self.makeButtonInMiddle('menu', self.aboutScreen, 1, lambda:self.machine.changeState('MainMenu')) def hideAbout(self): self.aboutScreen.unlink(True) self.aboutScreen = None def setupPlayground(self): # libavg setup self.display = avg.DivNode(parent=self._parentNode, size=self._parentNode.size) self.renderer = Renderer() background = avg.ImageNode(parent=self.display) background.setBitmap(self.backgroundpic) self.display.player = None (displayWidth, displayHeight) = self.display.size widthThird = (int)(displayWidth / 3) fieldSize = (widthThird, displayHeight) self.field1 = avg.DivNode(parent=self.display, size=fieldSize) self.field2 = avg.DivNode(parent=self.display, size=fieldSize, pos=(displayWidth - widthThird, 0)) avg.LineNode(parent=self.display, pos1=(0, 1), pos2=(displayWidth, 1)) avg.LineNode(parent=self.display, pos1=(0, displayHeight), pos2=(displayWidth, displayHeight)) self.lines.createImageNode('layer1', dict(parent=self.display, pos=(widthThird, 0)), (2, displayHeight)) self.lines.createImageNode('layer1', dict(parent=self.display, pos=(displayWidth - widthThird, 0)), (2, displayHeight)) # pybox2d setup self.world = b2World(gravity=(0, 0), doSleep=True) self.hitset = set() self.listener = ContactListener(self.hitset) self.world.contactListener = self.listener self.running = True pointsToWin = 999 if self.tutorialMode else config.pointsToWin self.leftPlayer, self.rightPlayer = Player(self, self.field1, pointsToWin), Player(self, self.field2, pointsToWin) self.leftPlayer.other, self.rightPlayer.other = self.rightPlayer, self.leftPlayer # horizontal lines BorderLine(self.world, a2w((0, 1)), a2w((displayWidth, 1)), 1, False, 'redball') BorderLine(self.world, a2w((0, displayHeight)), a2w((displayWidth, displayHeight)), 1, False, 'redball') # vertical ghost lines maxWallHeight = brickSize * brickLines * PPM BorderLine(self.world, a2w((maxWallHeight, 0)), a2w((maxWallHeight, displayHeight)), 1, False, 'redball', 'ball') BorderLine(self.world, a2w((displayWidth - maxWallHeight - 1, 0)), a2w((displayWidth - maxWallHeight - 1, displayHeight)), 1, False, 'redball', 'ball') self.middleX, self.middleY = self.display.size / 2 self.middle = a2w((self.middleX, self.middleY)) BatManager(self.field1, self.world, self.renderer) BatManager(self.field2, self.world, self.renderer) self.bonus = None self.balls = [] self.redballs = [] self.towers = [] self.ghosts = [] self.mainLoop = g_player.setOnFrameHandler(self.step) def startBall(self): ball = Ball(self, self.renderer, self.world, self.display, self.middle) self.balls.append(ball) if self.tutorialMode: BallTutorial(self).start() def revealBoni(self): BoniTutorial(self).start() def revealTetris(self): height = (self.display.height / 2) - (brickSize * PPM) width = self.display.width for i in range (-3, 3): form = random.choice(Block.form.values()) offset = form[1] if form == Block.form['SPIECE']: offset += 1 Block(self.display, self.renderer, self.world, (width / 3 - (brickSize * offset * PPM), height - (brickSize * PPM * 3) * i), self.leftPlayer, form, vanishLater=True) Block(self.display, self.renderer, self.world, (2 * width / 3, height - (brickSize * PPM * 3) * i), self.rightPlayer, form, vanishLater=True) if self.tutorialMode: TetrisTutorial(self).start() def startGhosts(self): self.createGhosts() if self.tutorialMode: GhostTutorial(self).start() def createGhosts(self): offset = 2 * ballRadius + 3 * ghostRadius self.ghosts.append(Ghost(self.renderer, self, self.display, self.middle + (offset, offset), "blinky")) self.ghosts.append(Ghost(self.renderer, self, self.display, self.middle + (-offset, offset), "pinky")) self.ghosts.append(Ghost(self.renderer, self, self.display, self.middle - (-offset, offset), "inky")) self.ghosts.append(Ghost(self.renderer, self, self.display, self.middle - (offset, offset), "clyde")) def killGhosts(self): for ghost in self.ghosts: ghost.destroy() del self.ghosts[:] def getBalls(self): return self.balls def getRedBalls(self): return self.redballs def getGhosts(self): return self.ghosts def _windex(self, lst): wtotal = sum([x[1] for x in lst]) n = random.uniform(0, wtotal) for item, weight in lst: if n < weight: break n = n - weight return item def _bonusJob(self): if not self.running: return nextBonus = random.randint(0, 10) if nextBonus <= 5: bonus = self._windex(PersistentBonus.probs) self.bonus = PersistentBonus(self, (bonus, PersistentBonus.boni[bonus])) elif 5 < nextBonus <= 7: bonus = self._windex(InstantBonus.probs) self.bonus = InstantBonus(self, (bonus, InstantBonus.boni[bonus])) else: self.bonus = InstantBonus(self, ('newBlock', InstantBonus.boni['newBlock'])) self.bonusjob = g_player.setTimeout(random.choice([4000, 5000, 6000]), self._bonusJob) def end(self, player): if not self.running: return self.running = False self.killGhosts() self.leftPlayer.killBricks() self.rightPlayer.killBricks() if self.bonusjob is not None and not self.tutorialMode: g_player.clearInterval(self.bonusjob) if self.bonus is not None and not self.tutorialMode: self.bonus.vanish() (displayWidth, displayHeight) = self.display.size BorderLine(self.world, a2w((0, 0)), a2w((0, displayHeight)), 1, False) BorderLine(self.world, a2w((displayWidth, 0)), a2w((displayWidth, displayHeight)), 1, False) if not self.tutorialMode: player.setEndText('You won') player.other.setEndText('You lost') self.createWinBalls() self.cleanup = g_player.setTimeout(40000, self.clearDisplay) self.menuButton = self.makeButtonInMiddle('menu', self.display, 0, self.clearDisplay) def createWinBalls(self): for i in range(1, random.randint(2, 5)): ball = Ball(self, self.renderer, self.world, self.display, self.middle) picList = [Ball.pic, Mine.leftPic, Mine.rightPic, RedBall.pic, Tower.pic] + Ghost.pics.values() + Bonus.pics.values() ball.setPic(random.choice(picList)) self.balls.append(ball) if len(self.balls) <= 60: self.keepPushingBalls = g_player.setTimeout(1000, self.createWinBalls) def clearDisplay(self): for tower in self.towers: tower.destroy() for redball in self.redballs: redball.destroy() g_player.clearInterval(self.mainLoop) if self.cleanup is not None: g_player.clearInterval(self.cleanup) self.cleanup = None if self.keepPushingBalls is not None: g_player.clearInterval(self.keepPushingBalls) self.keepPushingBalls = None for ghost in self.ghosts: if ghost.movement is not None: g_player.clearInterval(ghost.movement) if ghost.changing is not None: g_player.clearInterval(ghost.changing) self.display.active = False self.display.unlink(True) BorderLine.body = None self.machine.changeState('MainMenu') def addBall(self): if len(self.balls) < maxBalls: self.balls.append(Ball(self, self.renderer, self.world, self.display, self.middle)) def removeBall(self, ball): if len(self.balls) > 1: self.balls.remove(ball) ball.destroy() else: ball.reSpawn() def _processBallvsBrick(self, hitset): copy = hitset.copy() for brick in copy: brick.hit() hitset.difference_update(copy) copy.clear() def _processBallvsBall(self): for ball in self.balls: for ce in ball.body.contacts: contact = ce.contact mine = None if contact.fixtureA.userData == 'mine': mine = contact.fixtureA.body.userData elif contact.fixtureB.userData == 'mine': mine = contact.fixtureB.body.userData if mine is not None: if ball.lastPlayer != mine.getOwner() and ball.lastPlayer is not None: ball.lastPlayer.penalize() ball.reSpawn() mine.destroy() return def _processBallvsGhost(self): for ball in self.balls: for ce in ball.body.contacts: contact = ce.contact ghost = None if contact.fixtureA.userData == 'ghost': ghost = contact.fixtureA.body.userData elif contact.fixtureB.userData == 'ghost': ghost = contact.fixtureB.body.userData if ghost is not None: if ghost.mortal: # ball eats ghost ghost.reSpawn() if ball.lastPlayer is not None: ball.lastPlayer.addPoint() self.addBall() break else: # ghost tries to eat ball if ball.lastPlayer is None: break if ghost.getOwner() is not None: if ball.lastPlayer == ghost.getOwner(): break player = ball.zoneOfPlayer() if player is not None: player.penalize() self.removeBall(ball) def _checkBallPosition(self): for ball in self.balls: if ball.body.position[0] > (self.display.width / PPM) + ballRadius: if ball.lastPlayer == self.rightPlayer: self.rightPlayer.penalize() self.leftPlayer.addPoint() ball.reSpawn() elif ball.body.position[0] < -ballRadius: if ball.lastPlayer == self.leftPlayer: self.leftPlayer.penalize() self.rightPlayer.addPoint() ball.reSpawn() def _outside(self, ball): return (ball.body is None or not (-ballRadius <= ball.body.position[0] <= (self.display.width / PPM) + ballRadius)) def _checkRedBallPosition(self): killList = [x for x in self.redballs if self._outside(x)] self.redballs[:] = [x for x in self.redballs if x not in killList] for ball in killList: ball.destroy() def step(self): self.world.Step(TIME_STEP, 10, 10) self.world.ClearForces() if self.running: self._processBallvsGhost() self._checkBallPosition() self._checkRedBallPosition() self._processBallvsBall() self._processBallvsBrick(self.hitset) self.renderer.draw()
class Level(object): def __init__(self, window, space, filename, input_handler, game_clock): self.music = 'elec_Spin.wav' # Open level file self.window = window self.space = space self.name = filename self.input_handler = input_handler self.game_clock = game_clock self.game_clock.reset() #next level default is none self.next_level = "none" # Load level background and the objects in the level # level_width, level_width, background, powerups, platforms self._load(self.name) self.player = Player() self.player.body.position.x = 0 self.player.body.position.y = 100 self.gameobjects = pygame.sprite.Group() # Add objects to space self.player.add_to(self.space) for p in self.platforms: p.add_to(self.space) for p in self.powerups: p.add_to(self.space) # Bind input input_handler.bind_player(self.player) # Remember to unbind on level end # Create camera self.camera = Camera(self.window, self.level_width, self.level_height, self.player) print 'current level: ', self.name print 'next level: ', self.next_level def update(self): self.space.step(1.0/self.window.framerate) self.camera.update() if not self.player.alive: self.reload() self.player.update(self.level_width) # Keep the player within the level self._constrain_to_level(self.player) for p in self.platforms: p.update() for p in self.powerups: p.update collisions.PlayerZiplineCollision.post_collision_callback(self.space, self.player) collisions.PowerupCollision.post_collision_callback() def draw(self, screen): # Display Background screen.fill([0,0,0]) screen.blit(self.background, (0-Camera.offset_x, 600-self.background.get_height()+Camera.offset_y)) #self.background.draw(screen) # Environment for p in self.platforms: p.draw(screen) # Powerups for p in self.powerups: p.draw(screen) # Player self.player.draw(screen) # Draw UI self.game_clock.draw(screen) def delete(self): # Remove all objects contained in this level from the pymunk space, and mark for gc for p in self.platforms: p.delete() # Powerups for p in self.powerups: p.delete() self.player.delete() def reload(self): # Pop current state off the stack and replace with an identical one old_state = self.window.pop_state() state = Level(self.window, old_state.space, old_state.name, old_state.input_handler, old_state.game_clock) self.window.push_state(state) def _constrain_to_level(self, gameobject): # Keep the gameobject within the confines of the level if(gameobject.x - gameobject.get_width()/2) < 0: # Player went off the left side gameobject.x = gameobject.get_width()/2 gameobject.body.force.x = 0 gameobject.body.velocity.x = 0 elif(gameobject.x + gameobject.get_width()/2 > self.level_width): # Player went off the right side gameobject.x = self.level_width - gameobject.get_width()/2 gameobject.body.force.x = 0 gameobject.body.velocity.x = 0 def _load(self, filename): level_file = self._openFile(filename) #get the name of the next level file line = level_file.readline().rstrip('\n') self.next_level = line # Read load the background image line = level_file.readline().rstrip('\n') fullname = os.path.join('levels', line) self.background = pygame.image.load(fullname).convert() #bg_image = pygame.image.load(fullname).convert() #self.background = BackgroundObject.BackgroundObject(fullname,(0,0)) # Set level size from file line = level_file.readline() matches = self._findPatterns(r'\d+', line) self.level_width = int(matches[0]) self.level_height = int(matches[1]) #~ self.screen = pygame.display.set_mode((self.level_width,self.level_height)) # Load platforms, ramps, ziplines, and powerups self.platforms = pygame.sprite.Group() self.powerups = pygame.sprite.Group() line = level_file.readline() section = 0 while line != '': if(line[0] == '#' or line[0] == '\n'): if line[0] == '#': section += 1 line = level_file.readline() elif(section == 1): # Load platforms matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Platform(pos,dimensions) self.platforms.add(platform) line = level_file.readline() elif(section == 2): # Load ramps matches = self._findPatterns(r'\d+.\d+', line) endPoint1 = [float(matches[0]),float(matches[1])] endPoint2 = [float(matches[2]),float(matches[3])] rampWidth = int(float(matches[4])) platform = Ramp(endPoint1,endPoint2,rampWidth) self.platforms.add(platform) line = level_file.readline() elif(section == 3): # Load ziplines matches = self._findPatterns(r'\d+.\d+', line) endPoint1 = [float(matches[0]),float(matches[1])] endPoint2 = [float(matches[2]),float(matches[3])] platform = ZiplineWire(endPoint1,endPoint2) self.platforms.add(platform) line = level_file.readline() elif(section == 4): # Load Exit platform matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Exit(pos,dimensions,self.game_clock) self.platforms.add(platform) line = level_file.readline() elif(section == 5): # Load Jump powerups matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Powerup_Jump_Number(pos,dimensions) self.powerups.add(platform) line = level_file.readline() elif(section == 6): # Load power ziplines matches = self._findPatterns(r'\d+.\d+', line) endPoint1 = [float(matches[0]),float(matches[1])] endPoint2 = [float(matches[2]),float(matches[3])] platform = PowerZipline(endPoint1,endPoint2) self.platforms.add(platform) line = level_file.readline() else: print('Format error in ' + filename + '. Program terminated.') sys.exit() # Regular expression is used to find pattern within text def _findPatterns(self, pat, text): match = re.findall(pat, text) if match: match return match else: print(pat + ' not found') def _openFile(self, filename): fullname = os.path.join('levels', filename) try: file = open(fullname, 'rU') except pygame.error, message: print 'Cannot load file:', fullname raise SystemExit, message return file
class Level(object): def __init__(self, screen, space, filename, input_handler, game_clock): # Open level file self.screen = screen self.space = space self.name = filename self.input_handler = input_handler self.game_clock = game_clock self.game_clock.reset() # Load level background and the objects in the level # level_width, level_width, background, powerups, platforms self._load(self.name) self.player = Player() self.player.body.position.x = 0 self.player.body.position.y = 100 self.gameobjects = pygame.sprite.Group() # Add objects to space self.player.add_to(self.space) for p in self.platforms: p.add_to(self.space) for p in self.powerups: p.add_to(self.space) # Bind input input_handler.bind_player(self.player) # Remember to unbind on level end def update(self): self.player.update(self.level_width) for p in self.platforms: p.update() for p in self.powerups: p.update collisions.PlayerZiplineCollision.post_collision_callback(self.space, self.player) collisions.PowerupCollision.post_collision_callback() def draw(self, screen): # Display Background screen.fill([0,0,0]) screen.blit(self.background, (0, 0)) # Environment for p in self.platforms: p.draw(screen) # Powerups for p in self.powerups: p.draw(screen) # Player self.player.draw(screen) # Draw UI self.game_clock.draw(screen) def delete(self): # Remove all objects contained in this level from the pymunk space, and mark for gc pass def _load(self, filename): level_file = self._openFile(filename) # Read load the background image line = level_file.readline().rstrip('\n') fullname = os.path.join('levels', line) self.background = pygame.image.load(fullname).convert() # Set level size from file line = level_file.readline() matches = self._findPatterns(r'\d+', line) self.level_width = int(matches[0]) self.level_height = int(matches[1]) #~ self.screen = pygame.display.set_mode((self.level_width,self.level_height)) # Load platforms, ramps, ziplines, and powerups self.platforms = pygame.sprite.Group() self.powerups = pygame.sprite.Group() line = level_file.readline() section = 0 while line != '': if(line[0] == '#' or line[0] == '\n'): if line[0] == '#': section += 1 line = level_file.readline() elif(section == 1): # Load platforms matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Platform(pos,dimensions) self.platforms.add(platform) line = level_file.readline() elif(section == 2): # Load ramps matches = self._findPatterns(r'\d+.\d+', line) endPoint1 = [float(matches[0]),float(matches[1])] endPoint2 = [float(matches[2]),float(matches[3])] rampWidth = int(float(matches[4])) platform = Ramp(endPoint1,endPoint2,rampWidth) self.platforms.add(platform) line = level_file.readline() elif(section == 3): # Load ziplines matches = self._findPatterns(r'\d+.\d+', line) endPoint1 = [float(matches[0]),float(matches[1])] endPoint2 = [float(matches[2]),float(matches[3])] platform = ZiplineWire(endPoint1,endPoint2) self.platforms.add(platform) line = level_file.readline() elif(section == 4): # Load Exit platform matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Exit(pos,dimensions,self.game_clock,self.input_handler) self.platforms.add(platform) line = level_file.readline() elif(section == 5): # Load Jump powerups matches = self._findPatterns(r'\d+.\d+', line) pos = [float(matches[0]),float(matches[1])] dimensions = [float(matches[2]),float(matches[3])] platform = Powerup_Jump_Number(pos,dimensions) self.powerups.add(platform) line = level_file.readline() else: print('Format error in ' + filename + '. Program terminated.') sys.exit() # Regular expression is used to find pattern within text def _findPatterns(self, pat, text): match = re.findall(pat, text) if match: match return match else: print(pat + ' not found') def _openFile(self, filename): fullname = os.path.join('levels', filename) try: file = open(fullname, 'rU') except pygame.error, message: print 'Cannot load file:', fullname raise SystemExit, message return file