Пример #1
0
 def create_blocks(self):
     """
     description:
         - Create the bricks for the player's current level using the LevelGenerator-Class.
     :return: nothing
     """
     self.bricks, self.number_unbreakable_bricks = LevelGenerator().create_level(self.player.current_level) 
Пример #2
0
    def __init__(self, screenWidth, screenHeight, board1X, board1Y, board1Z,
                 board2X, board2Y, board2Z, countersX, countersY, countersZ,
                 timerX, timerY, timerZ, arcadeLevels, gameLevels):

        self.currentScene = "menu"
        self.arcadeLevels = arcadeLevels
        self.currentLevel = 0
        self.gameLevels = gameLevels

        self.BackButton = Button(430, 40, 50, 110, "Back", "menu", 30)
        self.playerBoard = Board(board1X, board1Y, board1Z)
        self.refBoard = Board(board2X, board2Y, board2Z)
        self.MoveCounter = MoveCounter(countersX, countersY, countersZ)
        self.Timer = Timer(timerX, timerY, timerZ)
        # TODO: After updating the MoveCounter, add a second counter for the MAX moves (or target moves)
        self.LevelGenerator = LevelGenerator(board2X, board2Y, board2Z)

        self.mainMenu = MainMenu(screenWidth / 2, screenHeight / 2, 50, 50)
        self.levelSelectMenu = LevelSelect(screenWidth / 2, screenHeight / 2,
                                           50, 50, self.gameLevels)
        self.levelCompleteMenu = LevelComplete(screenWidth / 2,
                                               screenHeight / 2, 50, 50)
        self.arcadeOverMenu = ArcadeOver(screenWidth / 2, screenHeight / 2, 50,
                                         50)

        self.resetList = [
            self.playerBoard, self.refBoard, self.MoveCounter,
            self.LevelGenerator
        ]
Пример #3
0
 def __init__(self,main):
     self.main = main
     self.sounds = Sounds()
     self.loadBackground()
     self.levelGen = LevelGenerator()
     print "initializing levelnode"
     self.LevelNr = 0
Пример #4
0
class Brickbreaker:
    def __init__(self):
        """
        description:
            - Create a new instance of the Brickbreaker class.
            - Initialize all attributes.
        """
        self.clock_speed = DEFAULT_CLOCK_SPEED
        self.screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
        self.bricks = []
        self.number_unbreakable_bricks = 0
        self.paddle = Paddle()
        self.ball = Ball()
        self.present_specials = []
        self.active_special = None
        self.spcl_text = None

        pygame.font.init()
        self.font = pygame.font.SysFont("Arial", 25)
        self.player = Player(current_level=1)

    def start_game(self):
        """
        description:
            - Create new level.
            - Position the paddle to the middle of the screen.
            - Call method to choose starting angle.
        :return: nothing
        """
        self.create_blocks()
        self.paddle.reset_position()
        self.reset_ball()

    def reset_ball(self):
        """
        description:
            - Center the ball over paddle and give the player the opportunity to choose inital angle.
            - Loop:
                - Switch angles using custom set left and right keys. Selected angles is displayed.
                - Shoot ball using custom set key.
        :return: nothing
        """
        if not (self.active_special is None):
            self.remove_special()

        dbi = DatabaseInteract()
        sets = dbi.get_settings()
        key_left = int(sets[2])
        key_right = int(sets[4])
        key_shoot = int(sets[9])

        self.ball.center_over_paddle(self.paddle.get_center())

        vector_indicator_start = (self.ball.form.centerx, self.ball.form.centery - 5)
        current_index = int(len(BOUNCE_OFF_VECTORS)/2) - 1
        clock = pygame.time.Clock()
        vector_selected = False
        while not vector_selected:
            clock.tick(60)
            self.draw_all()
            self.draw_start_text()
            currently_selected_vector = BOUNCE_OFF_VECTORS[current_index]
            events = pygame.event.get()
            for event in events:
                if event.type == QUIT:
                    os._exit(1)
                if event.type == pygame.KEYDOWN:
                    if event.key == key_left:
                        if current_index > 0:
                            current_index -= 1
                    elif event.key == key_right:
                        if current_index < len(BOUNCE_OFF_VECTORS) - 1:
                            current_index += 1
                    elif event.key == key_shoot:
                        self.ball.vector = currently_selected_vector
                        vector_selected = True
                        break
                    elif event.key == pygame.K_ESCAPE:
                        return GameState.TITLE

            vector_indicator_end = (vector_indicator_start[0] + 10 * currently_selected_vector[0],
                                    vector_indicator_start[1] + 10 * currently_selected_vector[1])
            pygame.draw.line(self.screen, WHITE, vector_indicator_start, vector_indicator_end, 3)

            pygame.display.flip()

    def create_blocks(self):
        """
        description:
            - Create the bricks for the player's current level using the LevelGenerator-Class.
        :return: nothing
        """
        self.bricks, self.number_unbreakable_bricks = LevelGenerator().create_level(self.player.current_level) 

    def check_ball_collisions(self):
        """
        description:
            - Checks all possible collisions that can occur for the ball.
            - Bounce off at left, right and top edge.
            - Bounce off from paddle using paddle.hitzones' vectors.
            - Check for brick collision and delegate handling.
            - Check if player dropped the ball.
                - if decremented to 0 --> game over --> save score --> restart
        :return:
        """
        # collision left or right edge
        if self.ball.form.x <= 0 or self.ball.form.x >= DISPLAY_WIDTH:
            self.ball.collide_vertical()
            if self.ball.form.x <= 0:
                self.ball.form.x = 1
            else:
                self.ball.form.x = DISPLAY_WIDTH - 1
        # collision top edge
        if self.ball.form.y <= 0:
            self.ball.form.y = 1
            self.ball.collide_horizontal()

        # collission paddle
        for paddle_part in self.paddle.hitzones:
            if paddle_part[0].colliderect(self.ball.form):
                self.ball.vector = paddle_part[1]
                break
        # brick collisions
        collision_bricks = []
        for brick in self.bricks:
            if brick.rect.colliderect(self.ball.form):
                collision_bricks.append(brick)
        if len(collision_bricks) > 0:
            self.handle_brick_collisions(collision_bricks)

        # collision bottom edge --> lost
        if self.ball.form.y > DISPLAY_HEIGHT:
            self.player.lives -= 1
            if self.player.lives == 0:
                highscore(self.screen, self.player.score)
                self.player.set_lives()
                self.player.score = 0
                self.player.current_level = 1
                self.start_game()
            else:
                self.reset_ball()

    def check_previously_horizontally_outside(self, brick_rect, horizontal_movement):
        """
        description:
            - Check whether the ball did not horizontally overlap with the currently brick hit in the previous frame.
            - Aligned edges do not count as overlap.
        :param brick_rect: pygame.Rect-Object representing the hit brick's position.
        :param horizontal_movement: Movement-Enum value indicating left or right movement
        :return: true if no overlap, false otherwise
        """
        ball_pos_previous = self.ball.get_previous_position()
        ball_rect_previous = pygame.Rect(ball_pos_previous[0], ball_pos_previous[1], self.ball.form.width,
                                         self.ball.form.height)
        if horizontal_movement == Movement.RIGHT:
            return ball_rect_previous.right <= brick_rect.left
        else:
            return ball_rect_previous.left >= brick_rect.right

    def check_previously_vertically_outside(self, brick_rect, vertical_movement):
        """
        description:
            - Check whether the ball did not vertically overlap with the currently brick hit in the previous frame.
            - Aligned edges do not count as overlap.
        :param brick_rect: pygame.Rect-Object representing the hit brick's position.
        :param vertical_movement: Movement-Enum value indicating up or down movement
        :return: true if no overlap, false otherwise
        """
        ball_pos_previous = self.ball.get_previous_position()
        ball_rect_previous = pygame.Rect(ball_pos_previous[0], ball_pos_previous[1], self.ball.form.width,
                                         self.ball.form.height)
        if vertical_movement == Movement.DOWN:
            return ball_rect_previous.bottom <= brick_rect.top
        else:
            return ball_rect_previous.top >= brick_rect.bottom

    def handle_brick_collisions(self, collision_bricks):
        """
        description:
            - Handle the brick-collision based on the number of bricks hit.
            - If only one brick was hit: Call function to perform brick collision with determined collision type
            - More than one (basically working with the first 2,
              edge-case of more than 2 ignored due to unlikelihood and complexity):
                - Determine expected collision type based on the relative position of the 2 bricks.
                - Determine calculated collision type for 2 bricks.
                - Perform brick collision with the brick matching the expected collision type.
                - If none matches: chose one (irrelevant for user experience) to perform the brick collision with using
                  expected collision type.
        :param collision_bricks: list of Brick-objects hit by the ball
        :return: nothing
        """
        if len(collision_bricks) == 1:
            self.perform_brick_collision(collision_bricks[0], self.determine_collision_type(collision_bricks[0]))
        else:
            if collision_bricks[0].rect.x == collision_bricks[1].rect.x:            # above each other
                collision_required = CollisionType.VERTICAL
            else:                                                                   # next to each other
                collision_required = CollisionType.HORIZONTAL
            brick1_collision = self.determine_collision_type(collision_bricks[0])
            brick2_collision = self.determine_collision_type(collision_bricks[1])
            if brick1_collision == collision_required:
                self.perform_brick_collision(collision_bricks[0], brick1_collision)
            elif brick2_collision == collision_required:
                self.perform_brick_collision(collision_bricks[1], brick2_collision)
            else:
                self.perform_brick_collision(collision_bricks[0], collision_required)

    def determine_collision_type(self, brick_hit):
        """
        description:
            - Determine the collision type based on the movement and overlap in the previous frame.
        :param brick_hit: Brick-object determine the theoretical collision type for.
        :return: CollisionType-enum value
        """
        horizontal_movement = self.ball.get_horizontal_movement()
        vertical_movement = self.ball.get_vertical_movement()
        previously_horizontally_outside = self.check_previously_horizontally_outside(brick_hit.rect,
                                                                                     horizontal_movement)
        previously_vertically_outside = self.check_previously_vertically_outside(brick_hit.rect, vertical_movement)

        # neither horizontal nor vertical overlap in the previous frame
        # --> compare ratio of horizontal and vertical overlap in the current frame
        if previously_horizontally_outside and previously_vertically_outside:
            horizontal_delta = (self.ball.form.right - brick_hit.rect.left) if horizontal_movement == Movement.RIGHT \
                else (brick_hit.rect.right - self.ball.form.left)
            vertical_delta = (self.ball.form.bottom - brick_hit.rect.top) if vertical_movement == Movement.DOWN \
                else (brick_hit.rect.bottom - self.ball.form.top)
            if horizontal_delta > vertical_delta:
                return CollisionType.HORIZONTAL
            else:
                return CollisionType.VERTICAL
        # horizontal overlap but no vertical overlap in the previous frame --> vertical collision
        elif previously_horizontally_outside and not previously_vertically_outside:
            return CollisionType.VERTICAL
        # no horizontal overlap but vertical overlap in the previous frame --> horizontal collision
        elif not previously_horizontally_outside and previously_vertically_outside:
            return CollisionType.HORIZONTAL
        # horizontal overlap and vertical overlap in the previous frame
        # --> irrelevant here because collision would have already happended and been handled in the previous frame.

    def perform_brick_collision(self, brick_hit, collision_type):
        """
        description:
            - Call function to change ball's movement direction based on the collision_type.
            - Call Brick's get_hit() function.
            - Destroy brick, increase score if brick was destroyed and create a special with a certain probability.
        :param brick_hit: Brick-object to perform the collision with
        :param collision_type: CollisionType-Enum
        :return: nothing
        """
        if collision_type == CollisionType.HORIZONTAL:
            self.ball.collide_horizontal()
        else:
            self.ball.collide_vertical()

        if brick_hit.get_hit():
            self.bricks.remove(brick_hit)
            self.player.score += 1
            if to_drop_special():
                spcl = choose_random_special()
                txt = spcl.get_german_name()
                self.spcl_text = SpecialText(txt, self.clock_speed)
                self.present_specials.append(Special(brick_hit.rect.topleft, spcl))

    def check_special_collisions(self):
        """
        description:
            - Check if any specials, i.e. special.rect, currently present on the screen is caught with the paddle.
            - To be caught the special has to be completely within the paddle's horizontal width and the paddle's
              height.
                - Remove active special if new special is caught.
                - Activate special on self or paddle based on its type.
                - Remove the special from the currently present specials and set self.active special.
            - If special is off screen, remove it.
        :return: nothing
        """
        if len(self.present_specials) > 0:
            for special in self.present_specials:
                if (self.paddle.get_top_edge() < special.rect.bottom <= self.paddle.get_bottom_edge()) \
                        and self.paddle.get_left_edge() <= special.rect.left \
                        and self.paddle.get_right_edge() >= special.rect.right:
                    if not (self.active_special is None):
                        self.remove_special()
                    if special.is_paddle_special():
                        self.paddle.activate_special(special)
                    else:
                        self.activate_special(special)
                    self.present_specials.remove(special)
                    self.active_special = special
                    self.active_special.activate(self.clock_speed)
                elif special.rect.top > DISPLAY_HEIGHT:
                    self.present_specials.remove(special)

    def activate_special(self, special):
        """
        description:
            - Activate a caught non-paddle special.
            - Either add a bonus life or adjust clock speed based on special.type
        :param special: the caught special
        :return: nothing
        """
        if special.special_type == SpecialType.BONUS_LIFE:
            self.player.lives += 1
        elif special.special_type == SpecialType.FASTER:
            self.clock_speed = DEFAULT_CLOCK_SPEED * CLOCK_SPEED_CHANGE_FACTOR
        elif special.special_type == SpecialType.SLOWER:
            self.clock_speed = DEFAULT_CLOCK_SPEED / CLOCK_SPEED_CHANGE_FACTOR

    def remove_special(self):
        """
        description:
            - Remove the currently active special and negate its effect.
            - If is_paddle_special: remove special from pedal
            - else: reset self.clock_speed
        :return: nothing
        """
        if self.active_special.is_paddle_special():
            self.paddle.remove_special()
        else:
            self.clock_speed = DEFAULT_CLOCK_SPEED
        self.active_special = None

    def draw_all(self):
        """
        description:
            - Called every tick
            - draws screen with every element
        :return:
        """
        self.screen.fill(BLUE)
        for brick in self.bricks:
            brick.show_brick(self.screen)
        for paddle_part in self.paddle.hitzones:
            pygame.draw.rect(self.screen, WHITE, paddle_part[0])
        for triangle in self.paddle.triangle_views:
            pygame.draw.polygon(self.screen, WHITE, triangle)
        for special in self.present_specials:
            special.fall()
            special.show_special(self.screen)
        self.player.draw_lives(self.screen)
        pygame.draw.rect(self.screen, WHITE, self.ball.form)
        self.screen.blit(self.font.render(str(self.player.score), -1, WHITE), (400, 550))

        self.draw_spcl_txt()

    def draw_spcl_txt(self):
        """
        description:
            - Write the type of the special that just dropped to the top of the screen.
        :return: nothing
        """
        if self.spcl_text is not None:
            info = TextElement(
                center_position=(590, 10),
                font_size=16,
                bg_rgb=BLUE,
                text_rgb=WHITE,
                text=f"Spezial: {self.spcl_text.text} aufgetaucht",
                )
            elems = RenderUpdates(info)
            elems.draw(self.screen)
            if self.spcl_text.tick():
                self.spcl_text = None

    def level_completed(self):
        """
        description:
            - Called when the player completes a level.
            - If level 10 was completed: show Highscore Page
            - Else: increase level, add bonus life
        :return:
        """
        if self.player.current_level == 10:
            highscore(self.screen, self.player.score)
            return GameState.TITLE
        else:
            self.player.current_level += 1
            self.player.lives += 1
            self.start_game()

    def pause_elems(self):
        """
        description:
            - Creates the Text object when being in pause mode
        :return: elements to be drawn during pause mode
        """
        dbi = DatabaseInteract()
        sets = dbi.get_settings()
        heading = TextElement(
            center_position=(400, 400),
            font_size=18,
            bg_rgb=BLUE,
            text_rgb=WHITE,
            text=f"Spiel Pausiert, zum Fortsetzen '{sets[5]}' drücken, zum Beenden 'ESC' drücken ",
            )
        elems = RenderUpdates(heading)
        return elems
        
    def draw_start_text(self):
        """
        description:
            - Creates and draws the Text object when being in pause mode
        :return: nothing
        """
        dbi = DatabaseInteract()
        sets = dbi.get_settings()

        key_left = sets[1]
        key_right = sets[3]
        key_shoot = sets[8]

        heading1 = TextElement(
            center_position=(400, 400),
            font_size=18,
            bg_rgb=BLUE,
            text_rgb=WHITE,
            text=f"Startwinkel mit '{key_left}' und '{key_right}' auswählen",
            )
        heading2 = TextElement(
            center_position=(400, 450),
            font_size=18,
            bg_rgb=BLUE,
            text_rgb=WHITE,
            text=f"Mit '{key_shoot}' Ball abschiessen, zum Beenden 'ESC' drücken ",
            )
        elems = RenderUpdates(heading1,heading2)
        elems.draw(self.screen)

    def main(self):
        """
        description:
            - Contains game logic.
            - Process game events by calling corresponding functions.
            - Update the UI.
            - Check whether level was completed.
        :return: nothing
        """
        clock = pygame.time.Clock()
        self.start_game()
        
        dbi = DatabaseInteract()
        sets = dbi.get_settings()

        key_left = sets[2]
        key_right = sets[4]

        pause_key = sets[6]
        
        while True:
            clock.tick(self.clock_speed)

            for event in pygame.event.get():
                if event.type == QUIT:
                    os._exit(1)
                if event.type == pygame.KEYDOWN:

                    if event.key == int(pause_key):
                        elems = self.pause_elems()
                        game_paused = True

                        while game_paused:
                            elems.draw(self.screen)

                            events = pygame.event.get()
                            for event in events:
                                if event.type == QUIT:
                                    os._exit(1)
                                if event.type == pygame.KEYDOWN:
                                    if event.key == int(pause_key):
                                        game_paused = False
                                        break
                                    elif event.key == pygame.K_ESCAPE:
                                        return GameState.TITLE
                            pygame.display.update()

            keys = pygame.key.get_pressed()
            if keys[int(key_left)]:
                self.paddle.move(-1)
            if keys[int(key_right)]:
                self.paddle.move(1)
            if keys[pygame.K_ESCAPE]:
                return GameState.TITLE

            # update ball
            self.ball.move()
            self.check_ball_collisions()
            # update specials
            if not (self.active_special is None):
                if self.active_special.tick():
                    self.remove_special()
            self.check_special_collisions()

            # Update screen
            self.draw_all()
            pygame.display.flip()

            if len(self.bricks) == self.number_unbreakable_bricks:
                if self.level_completed() == GameState.TITLE:
                    return GameState.TITLE
Пример #5
0
class GameManager():
    def __init__(self, screenWidth, screenHeight, board1X, board1Y, board1Z,
                 board2X, board2Y, board2Z, countersX, countersY, countersZ,
                 timerX, timerY, timerZ, arcadeLevels, gameLevels):

        self.currentScene = "menu"
        self.arcadeLevels = arcadeLevels
        self.currentLevel = 0
        self.gameLevels = gameLevels

        self.BackButton = Button(430, 40, 50, 110, "Back", "menu", 30)
        self.playerBoard = Board(board1X, board1Y, board1Z)
        self.refBoard = Board(board2X, board2Y, board2Z)
        self.MoveCounter = MoveCounter(countersX, countersY, countersZ)
        self.Timer = Timer(timerX, timerY, timerZ)
        # TODO: After updating the MoveCounter, add a second counter for the MAX moves (or target moves)
        self.LevelGenerator = LevelGenerator(board2X, board2Y, board2Z)

        self.mainMenu = MainMenu(screenWidth / 2, screenHeight / 2, 50, 50)
        self.levelSelectMenu = LevelSelect(screenWidth / 2, screenHeight / 2,
                                           50, 50, self.gameLevels)
        self.levelCompleteMenu = LevelComplete(screenWidth / 2,
                                               screenHeight / 2, 50, 50)
        self.arcadeOverMenu = ArcadeOver(screenWidth / 2, screenHeight / 2, 50,
                                         50)

        self.resetList = [
            self.playerBoard, self.refBoard, self.MoveCounter,
            self.LevelGenerator
        ]

    def Click(self, x, y):
        if "level" in self.currentScene:

            clicked = self.BackButton.IsIn(x, y)
            if clicked:
                self.ChangeScene(self.BackButton.Value)
                return

            squareX, squareY = self.playerBoard.GetSquare(x, y)

            if squareX != -1:
                self.playerBoard.Click(squareX, squareY)
                self.MoveCounter.Add()

                if self.CheckWin():

                    if "arcade" in self.currentScene:
                        self.currentLevel += 1
                        self.ChangeScene("level arcade")
                    else:
                        self.ChangeScene("complete")

        elif self.currentScene == "menu":
            button = self.mainMenu.GetButton(x, y)
            if button is not None:
                self.ChangeScene(button.Value)

        elif self.currentScene == "select menu":
            button = self.levelSelectMenu.GetButton(x, y)
            if button is not None:
                self.ChangeScene(button.Value)

        elif self.currentScene == "complete":
            button = self.levelCompleteMenu.GetButton(x, y)
            if button is not None:
                if button.Value == "next level":
                    self.currentLevel += 1
                    self.ChangeScene(
                        str(self.arcadeLevels[self.currentLevel]) + " level")

                else:
                    self.ChangeScene(button.Value)

        elif self.currentScene == "arcade complete":
            button = self.arcadeOverMenu.GetButton(x, y)
            if button is not None:
                self.currentLevel = 0
                self.ChangeScene(button.Value)

        #I need to add a value to the button which makes it go to next level
        # IF we clicked on "next level" then:
        #     Check what the current level is (self.currentLevel), and increase it by 1.
        #     Change level to that -> self.ChangeScene("2.2 level")
        elif self.currentScene == "settings":
            pass

        else:
            self.currentScene = "menu"

    def ChangeScene(self, newScene):
        if "complete" not in newScene:
            for object in self.resetList:
                object.Reset()

        else:
            self.Timer.Pause()
        if "level" in newScene:

            if "arcade" in newScene:
                self.GenerateLevel(int(self.arcadeLevels[self.currentLevel]))
            else:
                if newScene is "next level":
                    self.currentLevel += 1
                self.GenerateLevel(int(gameLevels[self.currentLevel][0]))
            #change generate level to my code inside generate level + make an actual input

        self.currentScene = newScene

    def CheckWin(self):
        if self.playerBoard.Equals(
                self.refBoard):  #Impliment Equals check in board
            return True
        else:
            return False

    def Reset(self):
        self.MoveCounter.Reset()
        self.playerBoard.Reset()
        self.Timer.Increment(self.arcadeLevels[self.currentLevel] * 5)

    def GenerateLevel(self, moves):
        self.Reset()
        self.refBoard = self.LevelGenerator.GenerateLevel(moves)

    def Display(self):
        if "level" in self.currentScene:
            self.playerBoard.Display()
            self.refBoard.Display()
            self.MoveCounter.Display()
            self.Timer.Display()
            self.BackButton.Display()
            if self.Timer.OutofTime():
                self.ChangeScene("arcade complete")

        elif self.currentScene == "arcade complete":
            self.playerBoard.Display()
            self.refBoard.Display()
            self.MoveCounter.Display()
            self.Timer.Display()
            self.arcadeOverMenu.Display()

        elif self.currentScene == "menu":
            self.mainMenu.Display()

        elif self.currentScene == "select menu":
            self.levelSelectMenu.Display()

        elif self.currentScene == "complete":
            self.playerBoard.Display()
            self.refBoard.Display()
            self.MoveCounter.Display()
            self.Timer.Display()
            # Task 3: Gray out what is behind it Look at processing docs,
            self.levelCompleteMenu.Display()

        elif self.currentScene == "settings":
            pass

        else:
            self.currentScene = "menu"
Пример #6
0
    def __init__(self):

        # self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT),FULLSCREEN)
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT),
                                              DOUBLEBUF)
        self.width = SCREEN_WIDTH
        self.height = SCREEN_HEIGHT
        self.dimensions = (SCREEN_WIDTH, SCREEN_HEIGHT)
        self.playing = True
        self.paused = True
        self.audio = GameAudio()
        self.total_game_time = 0

        self.pointFont = pygame.font.Font(POINT_FONT, 96)

        self.game_objects = []

        self.level = 1
        self.score = 0

        self.needs_sorting = True

        self.cursor_image = pygame.image.load(CURSOR_SPRITE).convert_alpha()
        self.cursor_dimensions = (50, 50)
        self.cursor_image = pygame.transform.scale(self.cursor_image,
                                                   self.cursor_dimensions)
        pygame.mouse.set_visible(False)

        # Camera
        self.world_x = 0
        self.world_y = 0

        # Background
        self.backdrop = Backdrop(self)

        # Particle system
        self.particle_system = ParticleSystem(self)

        # Player
        self.player = None  # gotta pass it a reference to the Game class
        self.player_gender = 1

        self.bear = None

        # self.game_objects.append(self.player)
        self.weapon = Weapon(self)

        # Level
        self.level_generator = LevelGenerator(self)
        self.bomb_generator = BombGenerator(self)

        floating_text = FloatingText.New(self, (255, 255, 255),
                                         "Use WASD or Arrow keys",
                                         SCREEN_WIDTH * 0.6,
                                         SCREEN_HEIGHT * 0.2,
                                         line2="to run around",
                                         life=6)
        # floating_text = FloatingText.FloatingText(self)
        floating_text.x = -20
        floating_text.y = -200
        self.AddObject(floating_text)

        for i in range(15):
            tree = Tree(self)
            tree.x = SCREEN_WIDTH * random.random()
            tree.y = SCREEN_HEIGHT * random.random()
            self.game_objects.append(tree)

        # Enemies
        self.enemy_generator = EnemyGenerator(self)

        # Coin Generator
        self.coin_generator = CoinGenerator(self)

        self.again_button_style = ButtonStyle('sprites/blue_button00.png',
                                              (100, 100, 100),
                                              'sprites/blue_button01.png',
                                              (150, 150, 150),
                                              POINT_FONT,
                                              vert_align=ALIGN_CENTER,
                                              hor_align=ALIGN_CENTER,
                                              border_perc=0.25,
                                              font_up_color=WHITE,
                                              font_down_color=BLACK,
                                              font_disabled_color=DARK_GREY)

        self.again_button = Button(self.screen, 'again', self.width * 0.7,
                                   self.height * 0.7, self.width * 0.2,
                                   self.height * 0.15, self.again_button_style)

        self.title_image = pygame.image.load(TITLE_SPRITE).convert_alpha()
        tit_width, tit_height = self.title_image.get_size()
        new_tit_width = int(self.width * 0.9)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_image = pygame.transform.scale(
            self.title_image, (new_tit_width, new_tit_height))

        self.boy_button = Button(self.screen, '', self.width * 0.05,
                                 self.height * 0.25, self.width * 0.4,
                                 self.height * 0.7, self.again_button_style)

        self.girl_button = Button(self.screen, '',
                                  self.width * 0.5 + self.width * 0.05,
                                  self.height * 0.25, self.width * 0.4,
                                  self.height * 0.7, self.again_button_style)

        self.title_cowboy = pygame.image.load(TITLE_COWBOY).convert_alpha()
        tit_width, tit_height = self.title_cowboy.get_size()
        new_tit_width = int(self.width * 0.3)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_cowboy = pygame.transform.scale(
            self.title_cowboy, (new_tit_width, new_tit_height))

        self.title_cowgirl = pygame.image.load(TITLE_COWGIRL).convert_alpha()
        tit_width, tit_height = self.title_cowgirl.get_size()
        new_tit_width = int(self.width * 0.3)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_cowgirl = pygame.transform.scale(
            self.title_cowgirl, (new_tit_width, new_tit_height))

        # Running measurements
        self.last_time = time.time()
        self.delta_time = 0
        self.mouse_x = 0
        self.mouse_y = 0
        self.score = 0

        # layers for collision detection
        self.collision_layers = {}
Пример #7
0
class Game(object):
    def __init__(self):

        # self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT),FULLSCREEN)
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT),
                                              DOUBLEBUF)
        self.width = SCREEN_WIDTH
        self.height = SCREEN_HEIGHT
        self.dimensions = (SCREEN_WIDTH, SCREEN_HEIGHT)
        self.playing = True
        self.paused = True
        self.audio = GameAudio()
        self.total_game_time = 0

        self.pointFont = pygame.font.Font(POINT_FONT, 96)

        self.game_objects = []

        self.level = 1
        self.score = 0

        self.needs_sorting = True

        self.cursor_image = pygame.image.load(CURSOR_SPRITE).convert_alpha()
        self.cursor_dimensions = (50, 50)
        self.cursor_image = pygame.transform.scale(self.cursor_image,
                                                   self.cursor_dimensions)
        pygame.mouse.set_visible(False)

        # Camera
        self.world_x = 0
        self.world_y = 0

        # Background
        self.backdrop = Backdrop(self)

        # Particle system
        self.particle_system = ParticleSystem(self)

        # Player
        self.player = None  # gotta pass it a reference to the Game class
        self.player_gender = 1

        self.bear = None

        # self.game_objects.append(self.player)
        self.weapon = Weapon(self)

        # Level
        self.level_generator = LevelGenerator(self)
        self.bomb_generator = BombGenerator(self)

        floating_text = FloatingText.New(self, (255, 255, 255),
                                         "Use WASD or Arrow keys",
                                         SCREEN_WIDTH * 0.6,
                                         SCREEN_HEIGHT * 0.2,
                                         line2="to run around",
                                         life=6)
        # floating_text = FloatingText.FloatingText(self)
        floating_text.x = -20
        floating_text.y = -200
        self.AddObject(floating_text)

        for i in range(15):
            tree = Tree(self)
            tree.x = SCREEN_WIDTH * random.random()
            tree.y = SCREEN_HEIGHT * random.random()
            self.game_objects.append(tree)

        # Enemies
        self.enemy_generator = EnemyGenerator(self)

        # Coin Generator
        self.coin_generator = CoinGenerator(self)

        self.again_button_style = ButtonStyle('sprites/blue_button00.png',
                                              (100, 100, 100),
                                              'sprites/blue_button01.png',
                                              (150, 150, 150),
                                              POINT_FONT,
                                              vert_align=ALIGN_CENTER,
                                              hor_align=ALIGN_CENTER,
                                              border_perc=0.25,
                                              font_up_color=WHITE,
                                              font_down_color=BLACK,
                                              font_disabled_color=DARK_GREY)

        self.again_button = Button(self.screen, 'again', self.width * 0.7,
                                   self.height * 0.7, self.width * 0.2,
                                   self.height * 0.15, self.again_button_style)

        self.title_image = pygame.image.load(TITLE_SPRITE).convert_alpha()
        tit_width, tit_height = self.title_image.get_size()
        new_tit_width = int(self.width * 0.9)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_image = pygame.transform.scale(
            self.title_image, (new_tit_width, new_tit_height))

        self.boy_button = Button(self.screen, '', self.width * 0.05,
                                 self.height * 0.25, self.width * 0.4,
                                 self.height * 0.7, self.again_button_style)

        self.girl_button = Button(self.screen, '',
                                  self.width * 0.5 + self.width * 0.05,
                                  self.height * 0.25, self.width * 0.4,
                                  self.height * 0.7, self.again_button_style)

        self.title_cowboy = pygame.image.load(TITLE_COWBOY).convert_alpha()
        tit_width, tit_height = self.title_cowboy.get_size()
        new_tit_width = int(self.width * 0.3)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_cowboy = pygame.transform.scale(
            self.title_cowboy, (new_tit_width, new_tit_height))

        self.title_cowgirl = pygame.image.load(TITLE_COWGIRL).convert_alpha()
        tit_width, tit_height = self.title_cowgirl.get_size()
        new_tit_width = int(self.width * 0.3)
        new_tit_height = int(new_tit_width * (tit_height / tit_width))
        self.title_cowgirl = pygame.transform.scale(
            self.title_cowgirl, (new_tit_width, new_tit_height))

        # Running measurements
        self.last_time = time.time()
        self.delta_time = 0
        self.mouse_x = 0
        self.mouse_y = 0
        self.score = 0

        # layers for collision detection
        self.collision_layers = {}

    def StartNewGame(self):
        if self.bear is not None:
            self.ExplodeObject(self.bear)
            self.DestroyObject(self.bear)
            self.bear = None
        self.total_game_time = 0

        self.playing = True
        self.score = 0
        self.level = 1
        self.CreatePlayer()

        self.enemy_generator.Reset()
        self.coin_generator.Reset()
        self.weapon.Reset()
        self.bomb_generator.Reset()

        pygame.mouse.set_visible(False)

    def CreatePlayer(self):
        if self.player is not None and not self.player.dead:
            self.DestroyObject(self.player)
        self.player = Player.Player(self, self.player_gender)
        self.AddObject(self.player)

        # self.player.x = 0
        # self.player.y = 0
        self.player.x = -(self.world_x - SCREEN_WIDTH * 0.5)
        self.player.y = -(self.world_y - SCREEN_HEIGHT * 0.5)

    def AddObject(self, game_object):
        self.game_objects.append(game_object)
        self.needs_sorting = True

    def DestroyObject(self, game_object):
        game_object.dead = True
        try:
            self.game_objects.remove(game_object)
        except ValueError:
            print(self.__class__.__name__,
                  'was trying to destroy itself but failed')
        self.needs_sorting = True

    def DisplayPoints(self):
        pointText = pointFont.render('$' + str(self.score), True, POINTS_COLOR,
                                     None)
        TX, TY = pointText.get_size()
        textWidth = int(POINTS_HEIGHT * (TX / TY))
        pointText = pygame.transform.scale(pointText,
                                           (textWidth, POINTS_HEIGHT))
        x = int(SCREEN_WIDTH * 0.95 - textWidth)
        y = int(SCREEN_HEIGHT * 0.97 - POINTS_HEIGHT)
        self.screen.blit(pointText, (x, y))

    def AddPoints(self, value):
        self.score += value
        if self.score >= self.weapon.next_upgrade:
            self.weapon.UpgradeWeapon()

    def ExplodeObject(self, game_object):

        if game_object.IsEnemy():
            self.particle_system.EnemyExplode(game_object.x, game_object.y,
                                              game_object.radius)
        elif game_object.IsBomb():
            self.particle_system.BombExplode(game_object.x, game_object.y)
        else:
            self.particle_system.TreeExplode(game_object)

    def NextLevel(self):
        self.level += 1
        self.bomb_generator.Reset()

    def Play(self):
        while self.playing:
            # lets keep track of how much time has passed between the last frame and this one
            current_time = time.time()
            self.delta_time = current_time - self.last_time  #should be in seconds
            # if are game is running faster than our target FPS then pause for a tick
            if self.delta_time < 1 / TARGET_FPS:
                continue

            self.total_game_time += self.delta_time

            #########
            # Handle events
            for event in pygame.event.get():
                # if the app is quit then break and close
                if event.type == pygame.QUIT:
                    self.playing = False
                    pygame.quit()
                    sys.exit()

                # if the player is holding the left mouse button then fire some bullets
                if event.type == pygame.MOUSEBUTTONDOWN and event.button is 1:
                    if self.player is not None and not self.player.dead:
                        self.weapon.firing = True
                if event.type == pygame.MOUSEBUTTONUP and event.button is 1:
                    self.weapon.firing = False

                if event.type == pygame.ACTIVEEVENT:
                    print('Active event', event.state, event.gain)
                    if event.state == 6 or event.state == 2:
                        self.paused = True

                if event.type == KEYDOWN and event.key == K_ESCAPE:
                    if not self.paused:
                        self.paused = True
                    elif self.player is not None:
                        self.paused = False

            # pressed = pygame.key.get_pressed()
            # if pressed[pygame.K_ESCAPE]:
            #     if not self.paused:
            #         self.paused = True
            #     elif self.player is not None:
            #         self.paused = False
            #     # self.playing = False
            #     # pygame.quit()
            #     # sys.exit()

            # store the mouse pos for easy getting
            self.mouse_x, self.mouse_y = pygame.mouse.get_pos()

            if not self.paused:

                if self.player is not None and not self.player.dead:
                    if self.mouse_x < 30:
                        self.mouse_x = 30
                    if self.mouse_x > SCREEN_WIDTH - 30:
                        self.mouse_x = SCREEN_WIDTH - 30
                    if self.mouse_y < 30:
                        self.mouse_y = 30
                    if self.mouse_y > SCREEN_HEIGHT - 30:
                        self.mouse_y = SCREEN_HEIGHT - 30
                    pygame.mouse.set_pos(self.mouse_x, self.mouse_y)

                # if pygame.mouse.get_focused() == 0:
                #     print( 'Mouse left the screen' )

                # Check for key presses and update the player's velocity

                ###########
                # Update game objects

                # update the weapon (fire bullets)
                self.weapon.Update()

                # update the level
                self.level_generator.Update()

                # spawn more enemies sometimes
                self.enemy_generator.Update()

                self.coin_generator.Update()

                self.bomb_generator.Update()

                # self.bomb_generator.Update()

                # clear the collision layers
                # (we really only need to do this if objects have been added or removed since the last time)
                if self.needs_sorting:
                    for flag in GameObject.COL_FLAGS:
                        self.collision_layers[flag] = []
                    # iterate through all our game objects and add them to any layers they apply to
                    for game_object in self.game_objects:
                        # go through each (if any) collision flags there are for this item
                        for key, value in game_object.collision_flags.items():
                            # the key will be the collision flag
                            # the value will be a bool for if it applies to this layer
                            if value:
                                # add it to the collision layer
                                self.collision_layers[key].append(game_object)
                    self.needs_sorting = False

                # we'll copy the game object list and iterate through the copy so that
                # we can remove dead elements from the original without getting tripped up
                object_list = self.game_objects.copy()
                for game_object in object_list:
                    # we'll let each game object handle their own update
                    # mostly they'll just check whether or not they're dead but sometimes they'll do collision detection
                    game_object.Update()

            if self.player is not None:
                # since the camera follows the player just set the world origin to the player's position
                dif_x = -self.world_x + (-self.player.x + SCREEN_WIDTH * 0.5)
                dif_y = -self.world_y + (-self.player.y + SCREEN_HEIGHT * 0.5)

                self.world_x += dif_x * 0.4
                self.world_y += dif_y * 0.4

            #########
            # draw
            # clear the screen
            self.screen.fill((220, 220, 200))

            # draw the ground layer
            self.backdrop.Draw()

            # sort the objects
            object_sort_tree = TreeList()
            # just by putting them into the TreeList one by one we'll get them in ascending order
            for game_object in self.game_objects:
                # sorted by they're y position
                # that way when we draw them from highest on the screen to the lowest on the screen
                # the ones below (and in front) will be drawn on top
                object_sort_tree.Put(
                    game_object.y + game_object.radius * 0.5 + game_object.z,
                    game_object)
            # draw the game objects
            for game_object in object_sort_tree.ToList():
                game_object.Draw()

            self.DisplayPoints()

            cx = int(self.mouse_x - self.cursor_dimensions[0] * 0.5)
            cy = int(self.mouse_y - self.cursor_dimensions[1] * 0.5)

            self.screen.blit(self.cursor_image, (cx, cy))

            if self.player is not None and self.player.dead and not self.weapon.firing:
                self.again_button.Draw()
                if self.again_button.pressed:
                    self.StartNewGame()
                    self.again_button.pressed = False

            if self.paused:
                # draw the main menu:

                self.boy_button.Draw()
                self.girl_button.Draw()

                self.screen.blit(
                    self.title_image,
                    (int(self.width * 0.05), int(self.height * 0.03)))

                self.screen.blit(
                    self.title_cowboy,
                    (int(self.width * 0.1), int(self.height * 0.25)))
                self.screen.blit(self.title_cowgirl,
                                 (int(self.width * 0.5 + self.width * 0.1),
                                  int(self.height * 0.25)))

                if self.boy_button.pressed:
                    self.player_gender = 1

                if self.girl_button.pressed:
                    self.player_gender = 2

                if self.girl_button.pressed or self.boy_button.pressed:
                    self.girl_button.pressed = False
                    self.boy_button.pressed = False
                    if self.player is None or self.player.dead:
                        self.StartNewGame()
                    else:
                        self.CreatePlayer()
                    self.paused = False

            # display what we've drawn to the screen
            pygame.display.flip()

            #########
            # finalize
            # save the current time as our last time
            self.last_time = current_time

    def ShowMenu(self):
        pass
Пример #8
0
def main():
    pygame.init()

    width = 1200
    height = 800

    levelLoader = LevelGenerator()  #Loads planet layouts into planet array

    screen = pygame.display.set_mode([width, height])
    screen_center = Vec2d(width / 2, height / 2)
    coords = Coords(screen_center.copy(), 1, True)
    # ^ Center of window is (0,0), scale is 1:1, and +y is up

    coords.zoom_at_coords(Vec2d(0, 0), 1)
    # ^Sets camera center

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    planets = []
    planets = levelLoader.loadLevel(levelLoader.getLevel())
    arrow = Arrow(10, Vec2d(-565, 0), Vec2d(-540, 0), Vec2d(0, 0))

    #textFont = pygame.font.Font(None, 144)

    #Strength of arrow shot. Will be divided by 60, adding roughly 1 to force per second
    powerMeter = 0
    arrowShootingTime = 30  #Time to apply force of shooting arrow in frames
    arrowShootingStart = False
    originalThrustVector = Vec2d(0, 0)

    frame_rate = 60
    playback_speed = 4
    dt = playback_speed / frame_rate
    done = False
    while not done:
        gameMouse = pygame.mouse
        # --- Main event loop
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # If user clicked close
                done = True
            if event.type == pygame.MOUSEBUTTONDOWN:
                if (not arrow.getActive()):
                    #Click and hold for power. Release to shoot
                    arrow.setCharging(True)
            if event.type == pygame.MOUSEBUTTONUP:
                if (not arrow.getActive()):
                    arrow.setActive(True)
                    arrow.setCharging(False)
                    arrowShootingStart = True
                    originalThrustVector = ForceCalculator.calculateThrust(
                        arrow.center, arrow.tip, powerMeter)
                    arrow.update_force(originalThrustVector)

        if (arrow.getActive()):
            if (arrowShootingTime > 0):
                arrowShootingTime -= 1
            #calculate all forces that would apply to arrow here
            forces = []
            for planet in planets:
                forces.append(
                    ForceCalculator.calculateGravity(arrow.center, arrow.mass,
                                                     planet.center,
                                                     planet.mass, -10))
            if (arrowShootingTime > 0):
                forces.append(originalThrustVector)
            else:
                powerMeter = 0
            forceSum = ForceCalculator.sumForces(forces)
            arrow.update_force(forceSum)
            print("Arrow is active")
        else:
            #Aim input here
            mouseTup = gameMouse.get_pos()
            mouseVec = Vec2d(mouseTup[0] - 1200, mouseTup[1])
            coordMouseVec = coords.pos_to_screen(mouseVec).int()
            arrow.rotateByMouse(coordMouseVec)
            if (arrow.getCharging()):
                powerMeter += 2
            print("Arrow is deactive")

        print("Power Meter:", powerMeter)
        # Drawing
        screen.fill(BLACK)  # wipe the screen
        for obj in planets:
            obj.draw(screen, coords)  # draw object to screen
            obj.update(dt)
        arrow.update(dt)
        arrow.draw(screen, coords)

        #mouseTup = gameMouse.get_pos()
        #mouseVec = Vec2d(mouseTup[0] - 1200, mouseTup[1])
        #coordMouseVec = coords.pos_to_screen(mouseVec).int()
        #arrow.rotateByMouse(coordMouseVec)
        #mousePosSurface = textFont.render("x: " + str(coordMouseVec[0]) + " y: " + str(coordMouseVec[1]), 0, WHITE)
        #screen.blit(mousePosSurface, (500,500))
        #print("Arrow is deactive")

        # --- Update the screen with what we've drawn.
        pygame.display.update()

        # This limits the loop to 60 frames per second
        clock.tick(frame_rate)

    pygame.quit()
Пример #9
0
def main():
	# Initialize screen
	pygame.init()
	screen = pygame.display.set_mode((1054, 714))
	pygame.display.set_caption('Labyrinth')

	#initializing constants for drawing maze
	black = (0, 0, 0)
	thickness = 4
	width = 34
	height = 34
	none = 0
	offset = 30
	constant = 34

	# Fill background
	background = pygame.Surface(screen.get_size())
	background = background.convert()
	background.fill((250, 250, 250))

	# Blit everything to the screen
	screen.blit(background, (0, 0))
	pygame.display.flip()

	def drawMaze(maze):
		"""
	  View a maze
	  """
	  # initialize north and west
		for i in range(maze.width):
			if maze.cell[i,0].north:
				drawWall(True,i,0)
		for i in range(maze.height):
			if maze.cell[0,i].west:
				drawWall(False,0,i)
	  # loop through to draw the rest of the walls
		for i in range(maze.width):
			for j in range(maze.height):
				if maze.cell[i,j].south:
					drawWall(True,i,j+1)
				if maze.cell[i,j].east:
					drawWall(False,i+1,j)

	def drawWall(isHorizontal, x, y):
		"""
		Draw wall for a cell
		"""
		if isHorizontal:
			pygame.draw.rect(background, black, (x*constant + offset, y*constant + offset, width, none), thickness)
		else:
			pygame.draw.rect(background, black, (x*constant + offset, y*constant + offset, none, height), thickness)

	l = LevelGenerator()
	m = l.nextLevel()
	drawMaze(m)

	# Event loop
	while 1:
		for event in pygame.event.get():
			if event.type == QUIT:
				return

		screen.blit(background, (0, 0))
		pygame.display.flip()