Ejemplo n.º 1
0
class BreakoutGame:
    def setup(self, startWindow=None, playerName=None):
        self.params = GameParams()  # To be filled by user input

        # Set up scorekeeping
        self.score = 0
        self.scoreKeeper = ScoreKeeper()
        self.scoreKeeper.setFile('breakoutScore.txt')

        # Set up window
        width = 800
        height = 600
        font = sf.Font.from_file("rust.ttf")
        self.params.setFont(font)

        if startWindow is None:
            # startWindow is None unless this is a restart
            startWindow = sf.RenderWindow(sf.VideoMode(width, height),
                                          "Breakout")
            startWindow.framerate_limit = 60
            startWindow.clear(sf.Color.BLACK)

            #Display Welcome
            welcomeText = utils.drawText(startWindow,
                                         string="Breakout",
                                         size=60,
                                         font=font,
                                         position='center')
            startWindow.display()

        # Wait for any input
        while (True):
            setup = False
            for event in startWindow.events:
                if type(event) is sf.CloseEvent:
                    exit()
                elif (type(event) is sf.MouseButtonEvent
                      or type(event) is sf.KeyEvent):
                    setup = True
            if setup:
                break

        # Select Player Name
        if playerName is None:
            playerName = utils.textInput(startWindow,
                                         "Enter Name:",
                                         font,
                                         maxLength=10)
        self.params.setPlayerName(playerName.lower())

        #Choose Difficulty
        #difficulty = utils.selectOptions(startWindow, ["Easy", "Medium", "Hard"], [0, 1, 2], font)
        #self.params.setDifficulty(difficulty)

        # Set up Board
        self.board = Board(title="Breakout", width=1000, height=500)

        # Set up Paddle
        self.paddle = Paddle(boundary=self.board.getBoundary(),
                             width=75,
                             height=15)
        self.paddle.setMoveSpeed(10)

        # Gameplay parameters
        self.maxLayers = 5
        self.level = 1

        startWindow.close()

    def endGame(self):
        gameOverText = utils.drawText(self.board.window,
                                      string="Game Over",
                                      font=self.params.font,
                                      size=60,
                                      position='center',
                                      color=sf.Color.RED)

        oldScore = self.scoreKeeper.checkScore(self.params.playerName,
                                               self.params.getDifficulty())
        scoreTextYPosition = gameOverText.position[
            1] + gameOverText.local_bounds.height + 10

        if self.score > oldScore:
            # display a "New Highscore" screen
            self.scoreKeeper.setScore(self.params.playerName, self.score,
                                      self.params.getDifficulty())

            utils.drawText(self.board.window,
                           string="New High Score! {}".format(self.score),
                           font=self.params.font,
                           size=30,
                           position='center',
                           yposition=scoreTextYPosition,
                           color=sf.Color.GREEN)
        else:
            # Display the old highscore
            utils.drawText(self.board.window,
                           string="High Score: {}".format(oldScore),
                           font=self.params.font,
                           size=30,
                           position='center',
                           yposition=scoreTextYPosition,
                           color=sf.Color.WHITE)

        utils.drawText(self.board.window,
                       string="Press ENTER to Relplay",
                       font=self.params.font,
                       size=15,
                       position='center',
                       yposition=self.board.window.height - 20,
                       color=sf.Color.WHITE)

        self.board.window.display()
        while (True):
            for event in self.board.window.events:
                if (type(event) is sf.CloseEvent
                        or (type(event) is sf.KeyEvent
                            and event.code is sf.Keyboard.ESCAPE)):
                    exit()
                if (type(event) is sf.KeyEvent
                        and event.code is sf.Keyboard.RETURN):
                    # Reset
                    self.board.window.clear(sf.Color.BLACK)
                    self.setup(self.board.window, self.params.getPlayerName())
                    self.playGame()

    def playLevel(self, level):
        self.board.window.clear(sf.Color.BLACK)
        self.paddle.draw(self.board.window)

        self.board.displayBoard()

        play = False
        while not play:
            for event in self.board.window.events:
                if type(event) is sf.CloseEvent:
                    exit()
                elif (type(event) is sf.KeyEvent):
                    play = True

        ballManager = ObjectManager(cleanSize=10)

        screenWidth = self.board.getBoundary()[0]
        screenHeight = self.board.getBoundary()[1]

        # Calculate BrickWall difficulty parameters
        wallDepth = min(self.maxLayers, self.level)
        wallLength = 10 + 2 * (self.level // 5
                               )  # increase by 2 width every 5 levels

        boundary = ((0, 25), (screenWidth,
                              25 + min(20 * wallDepth, screenHeight / 3)))

        brickWall = BrickWall(boundary=boundary)
        brickWall.setWallDepth(wallDepth)
        brickWall.setWallWidth(wallLength)

        if self.level < self.maxLayers:  # Set all bricks health = 1
            brickWall.setAllLayerHealth(1)
        else:
            minHealth = 1 + (self.level // 3)
            maxHealth = self.maxLayers + (self.level // 3)
            brickWall.setLayerHealthGradient(minHealth, maxHealth)

        brickWall.createBricks()

        ballSpeed = 4.5 + 0.2 * self.level

        ball = Ball(position=(100, screenHeight / 2),
                    speed=ballSpeed,
                    direction=45)
        ballManager.addObject(ball)

        while (True):
            self.board.window.clear(sf.Color.BLACK)

            # Input handler
            for event in self.board.window.events:
                if type(event) is sf.CloseEvent:
                    exit()
                if type(event) is sf.KeyEvent and event.pressed and (
                        event.code is sf.Keyboard.RETURN):
                    self.level += 1
                    self.playLevel(self.level)
            if sf.Keyboard.is_key_pressed(sf.Keyboard.RIGHT):
                self.paddle.moveRight()
            if sf.Keyboard.is_key_pressed(sf.Keyboard.LEFT):
                self.paddle.moveLeft()

            # Move and draw balls
            for i in range(ballManager.getLength()):
                ball = ballManager.getItem(i)
                ball.move()
                ball.draw(self.board.window)

            # Draw bricks
            brickWall.drawBricks(self.board.window)

            # Draw Paddle
            self.paddle.draw(self.board.window)

            # Check for Ball-Brick Collisions
            for i in range(ballManager.getLength()):
                ball = ballManager.getItem(i)
                brick = brickWall.checkCollision(ball)
                if brick:
                    ball.rectangleBounce(brick.getShape())
                    if (brick.getHealth() == 0):
                        self.score += 1

            # Check for Ball Collisions
            for i in range(ballManager.getLength()):
                ball = ballManager.getItem(i)
                position = ball.getPosition()
                size = ball.getSize()
                if self.paddle.didCollide(ball):
                    ball.rectangleBounce(self.paddle.getShape())
                # Check for Ball-Wall Collision
                if (position[0] <= 0 or
                        position[0] + size[0] >= self.board.getBoundary()[0]):
                    ball.bounceHorizontal()
                if (position[1] <= 0):
                    ball.bounceVertical()
                # Remove Dead Balls
                deadBalls = []
                if (position[1] >= self.board.getBoundary()[1]):
                    deadBalls.append(i)
                ballManager.removeItems(deadBalls)

                # Check if any balls left
                if ballManager.getLength() == 0:
                    self.endGame()

                # Check if any bricks left
                if brickWall.getNumBricks() == 0:
                    self.level += 1
                    self.playLevel(self.level)

            self._drawScore(self.board.window)
            self.board.window.display()

    def playGame(self):
        self.playLevel(self.level)

    def _drawScore(self, window):
        if hasattr(self, 'scoreText'):
            self.scoreText.string = str(self.score)
        else:
            self.scoreText = utils.drawText(window,
                                            size=25,
                                            font=self.params.font,
                                            string=str(self.score))
        window.draw(self.scoreText)