Пример #1
0
def start_game():
    global tk
    tk = Tk()
    tk.title("Bounce !!")
    tk.resizable(0, 0)
    tk.wm_attributes("-topmost", 1)
    canvas = Canvas(tk,
                    width=500,
                    height=500,
                    bg="Black",
                    highlightthickness=0)
    canvas.pack()
    tk.update()

    paddle = Paddle(canvas, "Blue")
    bricks = Bricks(canvas, "Green")
    ball = Ball(canvas, paddle, bricks, "red")
    while True:
        if ball.hit_bottom == False and len(bricks.recs) > 0:
            ball.draw()
            paddle.draw()
        elif len(bricks.recs) == 0:
            flag = 1
            break
        elif ball.hit_bottom:
            flag = 2
            break
        tk.update_idletasks()
        tk.update()
        time.sleep(0.05)

    return flag
Пример #2
0
class Board:
    def __init__(self):
        self.ball = Ball(400, 300, 3, 4, "random", 1)
        #self.ball.launch()
        self.paddle1 = Paddle(10, 250)
        self.paddle2 = Paddle(BOARD_LENGTH - 10 - PADDLE_LENGTH, 250)
        self.scoreboard = ScoreBoard()

    def move_paddle_1(self, speed):
        self.paddle1.move(speed)

    def move_paddle_2(self, speed):
        self.paddle2.move(speed)

    def move_ball(self):
        self.ball.move(self.scoreboard)
        return 1

    def get_paddle_1(self):
        return self.paddle1

    def get_paddle_2(self):
        return self.paddle2

    def get_ball(self):
        return self.ball

    def get_scoreboard(self):
        return self.scoreboard

    def draw(self, display):
        self.paddle1.draw(display)
        self.paddle2.draw(display)
        self.scoreboard.update_board(display)
        self.ball.draw(display)
Пример #3
0
class Client:
    def __init__(self):
        port = int(input('Which port are you going to connect to? '))
        self.name = input('What is your name? ')
        n = Network(port)
        x = n.get_xpos()
        player_count = n.get_player_count()
        self.player = Paddle(self.name, x, player_count)
        self.player2 = n.send_paddle(self.player)
        print('Connected to server.')
        self.main(n)

    def main(self, n):
        window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption('You are ' + self.name + '!')
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    break
            ball = n.get_ball()
            self.player2 = n.send_paddle(self.player)
            self.update_window(window, ball)

    def update_window(self, win, ball):
        win.fill((0, 0, 0))
        score1 = font.render(str(ball.score1), False, (255, 255, 255))
        score2 = font.render(str(ball.score2), False, (255, 255, 255))
        win.blit(score1, (WINDOW_WIDTH / 2 + 220, 20))
        win.blit(score2, (WINDOW_WIDTH / 2 - 220, 20))
        name1 = font.render(self.player.name, False, (255, 255, 255))
        name2 = font.render(self.player2.name, False, (255, 255, 255))
        if self.player.id == 1:
            win.blit(name1,
                     (WINDOW_WIDTH - list(name1.get_rect())[2] - 100, 20))
            win.blit(name2, (100, 20))
        else:
            win.blit(name1, (100, 20))
            win.blit(name2,
                     (WINDOW_WIDTH - list(name2.get_rect())[2] - 100, 20))
        if ball.score1 < 7 and ball.score2 < 7:
            ball.draw(win)
            self.player.move()
            self.player.draw(win)
            self.player2.draw(win)
            pygame.draw.rect(win, (255, 255, 255),
                             (WINDOW_WIDTH / 2 - 5, 0, 10, WINDOW_HEIGHT))
        else:
            if ball.winner.id == self.player.id:
                won = big_font.render('You won!', False, (0, 255, 0))
                pos = (WINDOW_WIDTH / 2 - list(won.get_rect())[2] / 2,
                       WINDOW_HEIGHT / 2 - list(won.get_rect())[3] / 2)
                win.blit(won, pos)
            else:
                lost = big_font.render('You lost!', False, (255, 0, 0))
                pos = (WINDOW_WIDTH / 2 - list(lost.get_rect())[2] / 2,
                       WINDOW_HEIGHT / 2 - list(lost.get_rect())[3] / 2)
                win.blit(lost, pos)
        pygame.display.update()
Пример #4
0
class PaddleTestCase(unittest.TestCase):
    def setUp(self):
        self.paddle = Paddle()
        self.paddle.rect.center = SCREEN_WIDTH // 2, SCREEN_HEIGHT - MARGIN

    def test_init(self):
        msg = "invalid paddle length"
        self.assertIn(self.paddle.len, range(-2, 4), msg=msg)

        msg = "paddle shouldn't start with balls attached"
        self.assertFalse(self.paddle.attached_balls, msg=msg)

        msg = "paddle shoudn't start with bonuses"
        self.assertFalse(self.paddle.is_confused, msg=msg)
        self.assertFalse(self.paddle.is_magnetic, msg=msg)

    def test_len(self):
        msg = "wrong paddle length"
        self.assertEqual(len(self.paddle), self.paddle.rect.width, msg=msg)

    def test_update(self):
        ball = Ball()
        ball.rect.center = self.paddle.rect.center
        self.paddle.attached_balls.add(ball)
        x1, x2 = self.paddle.rect.left, ball.rect.left
        dx = 10
        self.paddle.update(dx=dx)

        msg = "wrong position after moving the paddle"
        self.assertEqual(self.paddle.rect.left, x1 + dx, msg=msg)

        msg = "attached ball didn't move along the paddle"
        self.assertEqual(ball.rect.left, x2 + dx, msg=msg)

        self.paddle.is_confused = True
        x0 = self.paddle.rect.left
        self.paddle.update(dx=dx)
        msg = "directions should be reversed"
        self.assertEqual(self.paddle.rect.left, x0 - dx, msg=msg)

        self.paddle.is_confused = False
        self.paddle.update(dx=SCREEN_WIDTH)

        msg = "paddle should stop moving at margins"
        self.assertEqual(self.paddle.rect.right, SCREEN_WIDTH - MARGIN, msg=msg)
        self.paddle.update(dx=-SCREEN_WIDTH)
        self.assertEqual(self.paddle.rect.left, MARGIN, msg=msg)

    def test_draw(self):
        surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))  # pylint: disable=too-many-function-args
        self.paddle.draw(surface)
        msg = "paddle is not displayed"
        white = (255, 255, 255, 255)
        self.assertEqual(surface.get_at(self.paddle.rect.center), white, msg=msg)
Пример #5
0
class ScenePong(Scene):
    def __init__(self):
        Scene.__init__(self)

    def did_load(self, window, scene_director):
        self.window_width, self.window_height = window.get_size()
        self.scene_director = scene_director
        self.btnGoHome = UIButton()
        self.btnGoHome.fixture(color=(100, 100, 100), position=(20, 20)).foreground(text="HOME")
        # paddles
        self.player = Paddle(position=(20, window.get_rect().centery - 100))
        self.player_ia = Paddle(position=(window.get_width() - 70, window.get_rect().centery - 100))

        #ball
        center = (window.get_rect().centerx, window.get_rect().centery)
        self.ball = Ball(position=center, color=(20, 120, 125))

    def listen_inputs(self, event, pressed_keys):
        # go home
        if pressed_keys[pygame.K_BACKSPACE]:
            self.scene_director.go_scene('home')

        if event.type == pygame.KEYDOWN:
            # step up
            if event.key == pygame.K_UP:
                self.player.step_up()
            # step down
            elif event.key == pygame.K_DOWN:
                self.player.step_down()
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                self.player.stop()
            elif event.key == pygame.K_DOWN:
                self.player.stop()

        if pygame.mouse.get_pressed()[0]:
            mouse_position = pygame.mouse.get_pos()
            if self.btnGoHome.is_over(mouse_position):
                self.scene_director.go_scene('home')
    
    def update(self):
        self.player.update(self.window_height)
        self.ball.update(self.window_width, self.window_height)
    
    def render(self, window):
        Scene.render(self, window)
        window.fill((255, 255, 0))
        self.player.draw(window)
        self.player_ia.draw(window)
        self.ball.draw(window)
        self.btnGoHome.draw(window)
Пример #6
0
def main():
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)

    surface = pygame.Surface(screen.get_size())
    surface = surface.convert()

    paddle = Paddle(0)
    ball = Ball(0)
    enemies = []
    for i in range(NUMBER_OF_ENEMIES):
        enemy = Enemy(i)
        enemies.append(enemy)

    draw_grid(surface)

    myfont = pygame.font.SysFont("monospace", 16)
    score = 0

    while True:
        clock.tick(FRAME_RATE)
        paddle.user_input()
        draw_grid(surface)
        paddle.move()
        ball.move()

        result = collision_detection(paddle, ball, enemies)
        if result == -1:
            score = 0
            ball.reset()
            for enemy in enemies:
                enemy.reset()
        if result == 1:
            score += 1

        paddle.draw(surface)
        ball.draw(surface)
        for enemy in enemies:
            enemy.draw(surface)
        screen.blit(surface, (0, 0))
        text = None
        if score == NUMBER_OF_ENEMIES:
            text = myfont.render("WINNER", 50, WHITE)
            screen.blit(text, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2))
            ball.destroy()
        else:
            text = myfont.render(f"Score: {score}", 1, WHITE)
            screen.blit(text, (5, 10))
        pygame.display.update()
Пример #7
0
class Game:
    def __init__(self):
        pygame.init()
        self._window = pygame.display.set_mode((800, 600))
        pygame.display.set_caption("Pong")
        self.deltaTime = 0.0
        self.player = Paddle()
        self.ball = Ball()

    def run(self):
        while True:
            start = time.time()
            self.handle_events()
            self.update()
            self.render()
            end = time.time()
            self.deltaTime = end - start

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.player.move(-self.deltaTime * 250.0, 0.0)
        elif keys[pygame.K_RIGHT]:
            self.player.move(self.deltaTime * 250.0, 0.0)
        self.ball.update(self.deltaTime, self.player)

    def render(self):
        self._window.fill((0, 0, 0))
        self.player.draw(self._window)
        self.ball.draw(self._window)
        pygame.display.update()

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
Пример #8
0
class PongGame:
    window_width = 650
    window_height = 500

    def __init__(self):
        self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2)
        self.paddle1 = NNPaddle(PongGame.window_width - 50,
                                PongGame.window_height / 2, self.ball, self)
        self.paddle2 = AIPaddle(50, PongGame.window_height / 2, self.ball,
                                self)
        self.temp_paddle = None

        self.winner = None
        self.game_over = False
        self.speed = 1000
        self.scores = [0, 0]
        self.timeout = 0
        self.pause = False

    def start_game(self):
        pygame.init()

        clock = pygame.time.Clock()
        display = pygame.display.set_mode(
            (PongGame.window_width, PongGame.window_height))
        pygame.display.set_caption('Neural Net Pong')

        while not self.game_over:

            delta = clock.tick(60) / self.speed
            display.fill((255, 255, 255))

            # listen for events
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

            self.handle_input(delta)
            self.game_over = self.handle_off_screen()
            if not self.game_over:
                self.handle_collisions()
            # super super advanced AI
            self.paddle1.follow_ball(delta)
            self.paddle2.follow_ball(delta)
            self.ball.move(delta)

            self.draw(display)
            if self.timeout < 100:
                self.timeout += 1
            if self.pause:
                self.reset()
            pygame.display.flip()

    def draw(self, display):
        self.paddle1.draw(display)
        self.paddle2.draw(display)
        self.ball.draw(display)
        font = pygame.font.Font(None, 25)
        score = font.render(
            self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' +
            str(self.scores[0]) + ' | ' + self.paddle1.name, True, (0, 0, 0))
        rect = score.get_rect(center=(325, 60))
        display.blit(score, rect)

    def handle_input(self, delta):
        # listen for key presses
        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP] and self.paddle2.bounds.y > 0:
            self.paddle2.move_up(delta)
        if keys[pygame.
                K_DOWN] and self.paddle2.bounds.y + self.paddle2.bounds.height < PongGame.window_height:
            self.paddle2.move_down(delta)
        if keys[pygame.K_RIGHT] and self.speed > 10:
            self.speed -= 10
        if keys[pygame.K_LEFT] and self.speed < 1000000:
            self.speed += 10
        if keys[pygame.K_r]:
            self.reset()
        if keys[pygame.K_SPACE] and self.timeout == 100:
            self.timeout = 0
            if self.paddle2.name != 'Player':
                self.temp_paddle = self.paddle2
                self.paddle2 = Paddle(50, PongGame.window_height / 2)
                self.paddle2.score = self.scores[0]
            else:
                self.paddle2 = self.temp_paddle
        if keys[pygame.K_p] and self.timeout == 100:
            if not self.pause:
                self.pause = True
            else:
                self.pause = False

    def handle_collisions(self):
        # collision with human paddle
        if self.ball.intersects_paddle(self.paddle2, self.paddle1):
            self.ball.vel_x = -self.ball.vel_x
            self.ball.vel_x *= 1.05
            self.ball.vel_y *= 1.05
        # collision with ceiling
        elif (self.ball.bounds.y <= 0 and self.ball.vel_y < 0) or (
                self.ball.bounds.y + self.ball.bounds.height >=
                PongGame.window_height and self.ball.vel_y > 0):
            self.ball.vel_y = -self.ball.vel_y

    def handle_off_screen(self):
        if self.paddle1.score >= 3:
            self.winner = self.paddle1
            return True
        elif self.paddle2.score >= 3:
            self.winner = self.paddle2
            return True

        if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0:
            if self.ball.bounds.x <= 0:
                self.paddle1.score += 1
                self.paddle1.fitness += 10
                self.scores[0] += 1
            else:
                self.paddle2.score += 1
                self.paddle2.fitness += 10
                self.scores[1] += 1
            self.ball = Ball(PongGame.window_width / 2,
                             PongGame.window_height / 2)
            self.paddle1.reset(PongGame.window_width - 50,
                               PongGame.window_height / 2, self.ball)
            self.paddle2.reset(50, PongGame.window_height / 2, self.ball)
        return False

    def reset(self):
        self.ball.reset()
        self.paddle1.reset(PongGame.window_width - 50,
                           PongGame.window_height / 2, self.ball)
        self.paddle1.fitness = 0
        self.paddle1.contacts_ball = 0
        self.paddle1.score = 0
        self.paddle2.reset(50, PongGame.window_height / 2, self.ball)
        self.paddle2.score = 0
        self.scores = [0, 0]
Пример #9
0
class Board:

    def __init__(self, window, path="."):

        self.window = window
        self.h, self.w = window.getmaxyx()

        self.cells_x = self.w // Block.WIDTH
        self.cells_y = self.h // Block.HEIGHT
        self.field = [[None] * self.cells_x  for i in range(self.cells_y)]

        self._gen_blocks(path)
        self.ball = Ball(self.h-2, self.w//2)

        self.paddle = Paddle(self.h-1, self.w//2)

    def draw(self):
        for row in self.field:
            for cell in row:
                if cell is not None:
                    cell.draw(self.window)

        self.window.attron(curses.color_pair(1))

        self.ball.draw(self.window)
        self.paddle.draw(self.window)

    def move(self, offset):
        self.paddle.move(offset, self.w)

    def animate(self):
        self.ball.animate(self.h, self.w)
        self._collide_endzone()
        self._collide_blocks()
        self._collide_paddle()

    def _collide_blocks(self):
        cell_x = self.ball.x // Block.WIDTH
        cell_y = self.ball.y // Block.HEIGHT

        if (cell_y >= self.cells_y) or (cell_x >= self.cells_x):
            return

        block = self.field[cell_y][cell_x]
        if block is not None:

            self.field[cell_y][cell_x] = None # destroy the block

            # deflect the ball
            if (self.ball.y == block.top()) or \
               (self.ball.y == block.bottom()):
                self.ball.bounce_y()

            if (self.ball.x == block.left()) or \
               (self.ball.x == block.right()):
                self.ball.bounce_x()

            if block.isdir:
                self._gen_blocks(block.f)
            else:
                pass
                #block.destroy()

    def _collide_endzone(self):
        if self.ball.y == self.h - 1:
            exit()

    def _collide_paddle(self):
        if self.paddle.contacts(self.ball):
            self.ball.bounce_y()

    def _add_block(self, f):
        for y, row in enumerate(self.field):
            for x, cell in enumerate(row):
                if cell is None:
                    b = Block(f, y, x)
                    self.field[y][x] = b
                    return

    def _gen_blocks(self, path):
        for f in os.listdir(path):
            self._add_block(os.path.join(path, f))
Пример #10
0
class Level(object):
    """
    Main Level class, handles most of the gameplay
    """
    def __init__(self, screen, draw_offset, control_set, player_color, finish_game):
        """
        Init with... way too many parameters
        :param screen: Main PyGame surface to draw the objects/UI on
        :param draw_offset: Drawing offset used in multiplayer
        :param control_set: Key-set used to control the Paddle
        :param player_color: Color of the player's Paddle
        :param finish_game: Function passed to the constructor, triggered on
        the game end
        :return:
        """
        self.screen = screen
        self.draw_offset = draw_offset
        self.control_set = control_set
        self.prev_input_x = 0
        self.level_number = 1
        self.block_count = 0
        self.player = Player("Derp")
        self.paddle = Paddle(LEVEL_WIDTH/2 - Paddle.WIDTH/2, LEVEL_HEIGHT - 40,
                             player_color, parent=self, owner=self.player)
        self.ball = Ball(self.paddle.rect.x + Paddle.WIDTH/2 - Ball.RADIUS,
                         self.paddle.rect.y - Ball.RADIUS * 2)
        self.items = None
        self.blocks = []
        self.blocks_surface = None
        self.blocks_surface_dirty = True
        self.entities = []
        self.font = Assets.font
        self.score_label = None
        self.lives_label = None
        self.level_label = None
        self.load_level(self.level_number)
        self.finish_game = finish_game

    def handle_input(self, events):
        """
        Handles incoming input events
        :param events: input events from the main app
        :return:
        """
        BONUS_SPAWN_X = 305
        BONUS_SPAWN_Y = 200
        for event in events:
            if event.type == KEYDOWN:
                if event.key == self.control_set[0]:
                    if self.paddle.vx != 0:
                        self.prev_input_x = 1
                    self.paddle.vx = -1

                elif event.key == self.control_set[2]:
                    if self.paddle.vx != 0:
                        self.prev_input_x = -1
                    self.paddle.vx = 1

                # elif event.key == K_SPACE:
                #     self.paddle.change_size(self.paddle.rect.width+10)

                elif event.key == K_1:
                    # self.add_entity(ItemExpand(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 1)

                elif event.key == K_2:
                    # self.add_entity(ItemLaserGun(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 2)

                elif event.key == K_3:
                    # self.add_entity(ItemShrink(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 3)

                elif event.key == K_4:
                    # self.add_entity(ItemPaddleNano(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 4)

                elif event.key == K_5:
                    # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 5)

                elif event.key == K_6:
                    # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 6)

            elif event.type == KEYUP:
                if event.key == self.control_set[0]:
                    if self.prev_input_x < 0:
                        self.prev_input_x = 0
                    elif self.prev_input_x > 0:
                        self.paddle.vx = 1
                        self.prev_input_x = 0
                    else:
                        self.paddle.vx = 0

                elif event.key == self.control_set[2]:
                    if self.prev_input_x > 0:
                        self.prev_input_x = 0
                    elif self.prev_input_x < 0:
                        self.paddle.vx = -1
                        self.prev_input_x = 0
                    else:
                        self.paddle.vx = 0

                elif event.key == self.control_set[1]:
                    if self.ball.docked:
                        self.ball.docked = False
                        self.ball.vx = 1
                        self.ball.vy = -1
                    else:
                        self.paddle.use_attachment()

                elif event.key == K_EQUALS:
                    self.start_level(self.level_number + 1)

    def start_level(self, new_level_num):
        """
        Used to start level, checks the level bounds
        :param new_level_num:
        :return:
        """
        self.ball.docked = True
        self.ball.dead = False

        if new_level_num > get_level_count():
            self.finish_game()
        else:
            if self.level_number < new_level_num:
                self.player.score += self.player.lives * 500
            else:
                self.player.score = 0

            self.load_level(new_level_num)
            self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX])
            self.paddle.attachments = []
            self.paddle.rect.x = LEVEL_WIDTH/2 - self.paddle.rect.width/2
            self.paddle.rect.y = LEVEL_HEIGHT - 40
            self.player.lives = 3
            self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT))
            self.blocks_surface_dirty = True

    def load_level(self, new_level_num):
        """
        Parses level from the Character array that is provided by the LevelLoader class
        :param new_level_num: Number of the level, used to construct the filename,
        compute the next level number, and viewed on the UI
        :return:
        """
        loaded_level = LevelLoader.load(LEVELDIR + str(new_level_num).zfill(2) + ".lvl")
        level = loaded_level[0]
        self.items = loaded_level[1]
        self.level_number = new_level_num
        self.blocks = []
        self.entities = []
        self.block_count = 0
        for y in xrange(0, BLOCK_NUM_HEIGHT):
            self.blocks.append([None, ] * BLOCK_NUM_WIDTH)
            for x in xrange(0, BLOCK_NUM_WIDTH):
                if level[y][x] == 'i':
                    self.blocks[y][x] = BlockIndestructible(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                            PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                elif level[y][x] == 'm':
                    self.blocks[y][x] = BlockMultiHit(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                      PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                    self.block_count += 1
                elif level[y][x] == 'e':
                    self.blocks[y][x] = BlockExplosive(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                       PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                    self.block_count += 1
                elif level[y][x] != '0':
                    self.blocks[y][x] = Block(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                              PLAYFIELD_PADDING[1] + y * Block.HEIGHT,
                                              int(level[y][x]) - 1)
                    self.block_count += 1

    def add_entity(self, entity):
        """
        Utility function to add new entities to the level. Later, might search for dead entities
        to replace them instead of expanding the list indefinitely
        :param entity:
        :return:
        """
        self.entities.append(entity)

    def spawn_item(self, x, y, item):
        """
        Function used to spawn items from blocks
        :param x: x coordinate of the play-field
        :param y: y coordinate of the play-field
        :param item: item to spawn, leave empty to make it randomly selected
        :return:
        """
        if item == 1:
            self.add_entity(ItemLife(x, y))
        elif item == 2:
            self.add_entity(ItemExpand(x, y))
        elif item == 3:
            self.add_entity(ItemShrink(x, y))
        elif item == 4:
            self.add_entity(ItemLaserGun(x, y))
        elif item == 5:
            self.add_entity(ItemPaddleNano(x, y))
        elif item == 6:
            pass
        elif randint(0, 35) == 0:
            item_type = randint(0, 4)
            if item_type == 0:
                dropped_item = ItemLife(x, y)
            elif item_type == 1:
                dropped_item = ItemExpand(x, y)
            elif item_type == 2:
                dropped_item = ItemShrink(x, y)
            elif item_type == 3:
                dropped_item = ItemLaserGun(x, y)
            else:
                dropped_item = ItemPaddleNano(x, y)
            self.add_entity(dropped_item)

    def block_destruction(self, block, item, func):
        """
        Decides what to do with the block, based on the block type (sigh), and performs
        appropriate action
        :param block: Block to operate on
        :param item: If the block has a hard-assigned item in level, it will be spawned
        :param func: Function of the block that returns its points-value
        :return:
        """
        return_v = func()
        if isinstance(block, BlockExplosive):
            rect = block.rect
            self.entities.append(Explosion(rect.x + rect.width/2 - Explosion.WIDTH/2,
                                           rect.y + rect.height/2 - Explosion.HEIGHT/2))

        if block.dead:
            self.player.add_points(return_v)
            self.block_count -= 1
            if not isinstance(block, BlockExplosive):
                self.spawn_item(block.rect.x, block.rect.y, item)
        self.blocks_surface_dirty = True

    def draw(self):
        """
        Method called each frame to (re)draw the objects and UI
        :return:
        """
        self.screen.blit(Assets.background, (self.draw_offset[0], self.draw_offset[1]))

        self.screen.blit(Assets.border, (self.draw_offset[0], self.draw_offset[1]))
        self.screen.blit(Assets.border, (self.draw_offset[0] + LEVEL_WIDTH - PLAYFIELD_PADDING[0],
                                         self.draw_offset[1]))
        if self.blocks_surface_dirty:
            self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT), SRCALPHA, 32)
            self.blocks_surface = self.blocks_surface.convert_alpha()
            self.blocks_surface_dirty = False
            for row in self.blocks:
                for block in row:
                    if block is not None and not block.dead:
                        block.draw(self.blocks_surface)
        self.screen.blit(self.blocks_surface, self.draw_offset)
        self.paddle.draw(self.screen, self.draw_offset)

        if not self.ball.dead:
            self.ball.draw(self.screen, self.draw_offset)

        # draw entities
        for entity in self.entities:
            if not entity.dead:
                entity.draw(self.screen, self.draw_offset)

        # draw upper bar
        draw.rect(self.screen, (0, 0, 0), (self.draw_offset[0] + PLAYFIELD_PADDING[0], self.draw_offset[1],
                                           LEVEL_WIDTH - PLAYFIELD_PADDING[0] * 2, PLAYFIELD_PADDING[1]))

        self.screen.blit(self.score_label,
                         (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 10, self.draw_offset[1]))
        self.screen.blit(self.lives_label,
                         (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 150, self.draw_offset[1]))
        self.screen.blit(self.level_label,
                         (self.draw_offset[0] + LEVEL_WIDTH - 100, self.draw_offset[1]))

    def update(self):
        """
        Method called each frame, to update the state of entities based on input events and
        previous state of the game
        :return:
        """
        if self.block_count <= 0:
            self.start_level(self.level_number + 1)
        elif self.player.lives <= 0:
            self.start_level(self.level_number)

        self.paddle.update()
        if self.ball.docked and not self.ball.dead:
            self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius
            self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2
        elif self.player.lives > 0:
            self.ball.update()
        for entity in self.entities:
            if not entity.dead:
                entity.update()

        self.check_collision()
        self.score_label = self.font.render("SCORE: " + str(self.player.score), 1, (255, 255, 255))
        self.lives_label = self.font.render("LIVES: " + str(self.player.lives), 1, (255, 255, 255))
        self.level_label = self.font.render("LEVEL " + str(self.level_number), 1, (255, 255, 255))

    def check_collision(self):
        """
        Called after input handling and movement of the object, to check and solve collisions
        :return:
        """
        # ball vs paddle
        if self.ball.rect.y < self.paddle.rect.y and \
                sprite.collide_rect(self.paddle, self.ball):
            self.ball.vy = -1  # ball.vy

        # ball vs bottom
        if not self.ball.dead and self.ball.rect.y + self.ball.radius * 2 > LEVEL_HEIGHT:
            self.player.lives -= 1
            if self.player.lives < 1:
                self.ball.dead = True
            else:
                self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius
                self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2
            self.ball.docked = True
            self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX])
            self.paddle.attachments = []

        # ball vs blocks
        coll_num = [0, 0, 0]
        coll_num_val = (4, 2, 1)
        ball_grid_x = (self.ball.rect.x - PLAYFIELD_PADDING[0] + self.ball.radius) / Block.WIDTH
        ball_grid_y = (self.ball.rect.y - PLAYFIELD_PADDING[1] + self.ball.radius) / Block.HEIGHT
        for y in range(ball_grid_y - 1, ball_grid_y + 2):
            for x in range(ball_grid_x - 1, ball_grid_x + 2):
                if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                    if self.blocks[y][x] is not None and not self.blocks[y][x].dead and \
                            sprite.collide_rect(self.blocks[y][x], self.ball):
                        self.block_destruction(self.blocks[y][x],
                                               self.items[y][x], self.blocks[y][x].on_collide)

                        coll_num[y - ball_grid_y + 1] += coll_num_val[x - ball_grid_x + 1]

        self.ball.on_collide(coll_num)

        # entities
        for entity in self.entities:
            if not entity.dead:
                # paddle vs items
                if isinstance(entity, Item) and sprite.collide_rect(self.paddle, entity):
                    entity.on_collect(self.paddle)
                    entity.dead = True
                    # self.player.lives += 1
                # explosion vs blocks
                elif isinstance(entity, Explosion) and entity.state > 0:
                    entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] +
                                      Explosion.WIDTH/2) / Block.WIDTH
                    entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] +
                                      Explosion.HEIGHT/2) / Block.HEIGHT
                    for y in xrange(entity_block_y - 1, entity_block_y + 2):
                        for x in xrange(entity_block_x - 1, entity_block_x + 2):
                            if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                                if self.blocks[y][x] is not None and not self.blocks[y][x].dead:
                                    self.block_destruction(self.blocks[y][x], self.items[y][x],
                                                           self.blocks[y][x].kill)
                elif isinstance(entity, Projectile):
                    entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] +
                                      entity.rect.width/2) / Block.WIDTH
                    entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] +
                                      entity.rect.height/2) / Block.HEIGHT
                    for y in xrange(entity_block_y - 1, entity_block_y + 2):
                        for x in xrange(entity_block_x - 1, entity_block_x + 2):
                            if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                                if self.blocks[y][x] is not None and not self.blocks[y][x].dead \
                                        and sprite.collide_rect(self.blocks[y][x], entity):
                                    self.block_destruction(self.blocks[y][x], self.items[y][x],
                                                           self.blocks[y][x].kill)
                                    entity.on_collide()
Пример #11
0
ball = Ball(canvas, paddle, score, 'red')
balls.append(ball)


def ball_destroyer(canvas, balls_list):
    if isinstance(balls_list, list):
        for ball in balls_list:
            if isinstance(ball, Ball):
                if ball.hit_bottom:
                    balls_list.remove(ball)
                    canvas.delete(ball.id)


while len(balls) > 0:
    if paddle.started:
        ball_destroyer(canvas, balls)
        for ball in balls:
            ball.draw()
            if ball.hit_paddle(canvas.coords(ball.id)):
                balls.append(Ball(canvas, paddle, score, 'red'))
        paddle.draw()
    if len(balls) == 0:
        canvas.create_text(250,
                           120,
                           text='ты хуй',
                           font=('Courier', 110),
                           fill='red')
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)
time.sleep(3)
Пример #12
0
class Scene:
    def __init__(self):
        self.lblScore = pyglet.text.Label('Score: 0',
                                          font_name='Arial',
                                          font_size=12,
                                          x=15,
                                          y=5,
                                          anchor_x='left',
                                          anchor_y='bottom')

        self.lblLevel = pyglet.text.Label('Level: 1',
                                          font_name='Arial',
                                          font_size=12,
                                          x=game.window.width - 15,
                                          y=5,
                                          anchor_x='right',
                                          anchor_y='bottom')

        self.setup()

    def setup(self, score=0, level=1):
        # SETUP GAME OBEJCTS
        self.paddle = Paddle(game.keyboard,
                             game.window.width / 2 - 50,
                             40,
                             width=100,
                             height=20,
                             speed=400)

        self.ball = Ball(game.window.width / 2 - 8,
                         200,
                         width=16,
                         height=16,
                         speed=200,
                         direction=(0, -1))

        self.wall_w = Wall(0, 0, width=10, height=game.window.height)
        self.wall_e = Wall(game.window.width - 10,
                           0,
                           width=10,
                           height=game.window.height)
        self.wall_n = Wall(0,
                           game.window.height - 10,
                           width=game.window.width,
                           height=10)
        self.wall_s = Wall(0, 0, width=game.window.width, height=10)

        self.walls = [self.wall_w, self.wall_n, self.wall_e, self.wall_s]

        self.score = score
        self.lblScore.text = "Score: " + str(self.score)

        self.level = level
        self.lblLevel.text = "Level: " + str(self.level)

        # bricks setup

        BRICK_WIDTH = 60
        BRICK_HEIGHT = 40
        MARGIN = 10

        self.bricks = []

        brickX = MARGIN
        brickY = game.window.height - MARGIN - BRICK_HEIGHT
        while brickY > game.window.height / 2:
            while brickX + BRICK_WIDTH < game.window.width - MARGIN:
                self.bricks.append(
                    Brick(brickX, brickY, BRICK_WIDTH, BRICK_HEIGHT))
                brickX += BRICK_WIDTH + MARGIN
            brickX = MARGIN
            brickY -= MARGIN + BRICK_HEIGHT

        # appear
        #for brick in self.bricks:
        #    brick.appear(0.25 + random.random() * 0.5)

    def draw(self):
        for brick in self.bricks:
            brick.draw()

        self.paddle.draw()
        self.ball.draw()

        self.wall_w.draw()
        self.wall_e.draw()
        self.wall_n.draw()

        self.lblScore.draw()
        self.lblLevel.draw()

    def tick(self, dt):
        # update tweens
        game.tween.tick(dt)

        # update game objects
        self.paddle.tick(dt)
        self.ball.tick(dt)

        # compute collisions and raise collision events
        game.physics.collide_prepare()

        game.physics.collide([self.ball],
                             [self.paddle])  # collides ball against the paddle
        game.physics.collide([self.ball],
                             self.walls)  # collides ball against walls
        game.physics.collide([self.ball],
                             self.bricks)  # collides ball against bricks

        game.physics.collide_finish(
        )  # this raises collision events gathered during "physics.collide(...)"

        # remove dead bricks
        i = 0
        while i < len(self.bricks):
            if not self.bricks[i].alive:
                self.bricks.pop(i)
                self.score += 1
                self.lblScore.text = "Score: " + str(self.score)
            else:
                i += 1

        # check ball off-screen
        if self.ball.x < -self.ball.width or self.ball.x > game.window.width + self.ball.width or self.ball.y > game.window.height + self.ball.height or self.ball.y < -self.ball.height:
            self.restart()

        # check all bricks down
        new_level = True
        for brick in self.bricks:
            if brick.destroyable and brick.alive:
                new_level = False
                break
        if new_level:
            self.next_level()

    def restart(self):
        self.setup()

    def next_level(self):
        self.setup(score=self.score, level=self.level + 1)
Пример #13
0
            # use a try-block incase there are no bounding-boxes in the frame
            try:
                if hand_pos[1]:
                    if hand_pos[1] >= 0 and hand_pos[1] <= SCREEN_WIDTH:
                        #print("Center Y: %d" % hand_pos[1])
                        human_paddle.set_ypos(hand_pos[1])
            except:
                print("Error, no hand in the frame!")

        # Update each game object
        ai_paddle.update(ball)
        human_paddle.update(ball)
        ball.move()

    # Draw each game object
    ai_paddle.draw(frame)
    human_paddle.draw(frame)
    ball.draw(frame)

    # Show the pong game
    cv.imshow('Pong', frame)

    key = cv.waitKey(1) & 0xff

    if key == ord('q'):
        break
    # Calibrate the skin detection module
    elif key == ord('s'):
        handDetect.calibrateSkinDetection(calibrate_frame)
    # Start the game 
    elif key == ord('p'):
Пример #14
0
class Game:
    def __init__(self, paddle1computer=None, paddle2computer=None):
        self.paddle1computer = paddle1computer
        self.paddle2computer = paddle2computer

        self._setup()
        self._game_loop()

    def _setup(self):
        pygame.init()
        pygame.display.set_caption("pypong")

        self.screen = pygame.display.set_mode((800, 600))
        self.clock = pygame.time.Clock()
        self.timer = 0

        self.background = Background()

        self.paddle1 = Paddle()
        self.paddle2 = Paddle(760, 'player2.png')
        self.ball = Ball()

        self.paddle1_gui = PaddleGui(self.paddle1)
        self.paddle2_gui = PaddleGui(self.paddle2, 700)
        self.ball_gui = BallGui(self.ball)

        self.game_over = False
        self.running = True

    def _game_loop(self):
        while self.running:
            self.clock.tick(60)
            self.timer += self.clock.get_time()

            self.screen.fill((0, 0, 0))

            self._handle_input()

            if not self.game_over:
                self._update_state()
                self._draw_objects()

            if self.paddle1.lives == 0:
                self._game_over('Player 2')

            if self.paddle2.lives == 0:
                self._game_over('Player 1')

            # refresh display
            pygame.display.flip()

    def _handle_input(self):
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False

                if event.key == pygame.K_r:
                    self._setup()

        if pygame.key.get_pressed()[pygame.K_w]:
            self.paddle1.move_up()

        if pygame.key.get_pressed()[pygame.K_s]:
            self.paddle1.move_down()

        if pygame.key.get_pressed()[pygame.K_UP]:
            self.paddle2.move_up()

        if pygame.key.get_pressed()[pygame.K_DOWN]:
            self.paddle2.move_down()

        # let computer move the paddles if activated
        if self.paddle1computer is not None:
            self.paddle1computer.move(self.paddle1, self.ball)

        if self.paddle2computer is not None:
            self.paddle2computer.move(self.paddle2, self.ball)

    def _update_state(self):
        if collision_screen_left(self.ball):
            self.paddle1.lives -= 1
            self.ball.reset()
            self.background.flash()

        if collision_screen_right(self.ball):
            self.paddle2.lives -= 1
            self.ball.reset()
            self.background.flash()

        if collision_screen_top(self.ball) or collision_screen_bottom(
                self.ball):
            self.ball.acceleration = np.multiply(self.ball.acceleration,
                                                 np.array([1, -1]))

        self.ball.position += self.ball.acceleration
        self.ball.acceleration_multiply(
            np.array([1 + self.timer / 100000000, 1]))

        if collision(self.paddle1, self.ball):
            self.ball.accelerate(acc_factor(self.paddle1, self.ball))
            self.background.flash((0, 255, 0), 100)

        if collision(self.paddle2, self.ball):
            self.ball.accelerate(acc_factor(self.paddle2, self.ball))
            self.background.flash((0, 255, 0), 100)

        self.background.update()

    def _draw_objects(self):
        self.background.draw(self.screen)

        self.paddle1.draw(self.screen)
        self.paddle2.draw(self.screen)

        self.ball.draw(self.screen)

        self.paddle1_gui.draw(self.screen)
        self.paddle2_gui.draw(self.screen)
        self.ball_gui.draw(self.screen)

    def _game_over(self, winner):
        self.game_over = True

        surface_width = pygame.display.get_surface().get_width()
        surface_height = pygame.display.get_surface().get_height()

        font = pygame.font.Font('freesansbold.ttf', 18)

        text = font.render('GAME OVER', True, (255, 255, 255))
        text_rect = text.get_rect(center=(surface_width / 2,
                                          surface_height / 2 - 40))
        self.screen.blit(text, text_rect)

        text = font.render('WINNER: {}'.format(winner), True, (153, 255, 153))
        text_rect = text.get_rect(center=(surface_width / 2,
                                          surface_height / 2))
        self.screen.blit(text, text_rect)

        text = font.render('Press "r" to restart or "esc" to quit', True,
                           (192, 192, 192))
        text_rect = text.get_rect(center=(surface_width / 2,
                                          surface_height / 2 + 40))
        self.screen.blit(text, text_rect)
Пример #15
0
class Board:
    def __init__(self, window, path="."):

        self.window = window
        self.h, self.w = window.getmaxyx()

        self.cells_x = self.w // Block.WIDTH
        self.cells_y = self.h // Block.HEIGHT
        self.field = [[None] * self.cells_x for i in range(self.cells_y)]

        self._gen_blocks(path)
        self.ball = Ball(self.h - 2, self.w // 2)

        self.paddle = Paddle(self.h - 1, self.w // 2)

    def draw(self):
        for row in self.field:
            for cell in row:
                if cell is not None:
                    cell.draw(self.window)

        self.window.attron(curses.color_pair(1))

        self.ball.draw(self.window)
        self.paddle.draw(self.window)

    def move(self, offset):
        self.paddle.move(offset, self.w)

    def animate(self):
        self.ball.animate(self.h, self.w)
        self._collide_endzone()
        self._collide_blocks()
        self._collide_paddle()

    def _collide_blocks(self):
        cell_x = self.ball.x // Block.WIDTH
        cell_y = self.ball.y // Block.HEIGHT

        if (cell_y >= self.cells_y) or (cell_x >= self.cells_x):
            return

        block = self.field[cell_y][cell_x]
        if block is not None:

            self.field[cell_y][cell_x] = None  # destroy the block

            # deflect the ball
            if (self.ball.y == block.top()) or \
               (self.ball.y == block.bottom()):
                self.ball.bounce_y()

            if (self.ball.x == block.left()) or \
               (self.ball.x == block.right()):
                self.ball.bounce_x()

            if block.isdir:
                self._gen_blocks(block.f)
            else:
                block.destroy()

    def _collide_endzone(self):
        if self.ball.y == self.h - 1:
            exit()

    def _collide_paddle(self):
        if self.paddle.contacts(self.ball):
            self.ball.bounce_y()

    def _add_block(self, f):
        for y, row in enumerate(self.field):
            for x, cell in enumerate(row):
                if cell is None:
                    b = Block(f, y, x)
                    self.field[y][x] = b
                    return

    def _gen_blocks(self, path):
        for f in os.listdir(path):
            self._add_block(os.path.join(path, f))
Пример #16
0
class Game:
    FPS = 60
    WIDTH, HEIGHT = (gb.width, gb.height)
    WIN = pygame.display.set_mode(
        (0, 0), pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.HWSURFACE)
    pygame.display.set_caption("BREAKOUT")

    OFFSET_X = 600
    OFFSET_Y = 200

    def __init__(self):
        self.run = False
        self.menu = True
        self.rows = 3
        self.columns = int((Game.WIDTH - Game.OFFSET_X) / Block.WIDTH)
        self.score = 0
        self.lives = 5
        self.level = 1

        self.the_ball = Ball(Ball.START_POSITION[0], Ball.START_POSITION[1], 0,
                             0, white, Game.WIN)
        self.the_paddle = Paddle(Paddle.START_POSITION[0],
                                 Paddle.START_POSITION[1],
                                 Paddle.START_SIZE[0], Paddle.START_SIZE[1],
                                 white, Game.WIN)
        self.score_text = TextGUI(Game.WIDTH / 100 * 15, Game.HEIGHT // 60,
                                  Game.WIN, "SCORE: " + str(self.score), 50)
        self.lives_text = TextGUI(Game.WIDTH / 100 * 73,
                                  Game.HEIGHT - Game.HEIGHT // 12, Game.WIN,
                                  "LIVES: " + str(self.lives), 20)
        self.level_text = TextGUI(Game.WIDTH / 100 * 60, Game.HEIGHT // 60,
                                  Game.WIN, "LEVEL: " + str(self.level), 50)

        self.left_boundary = Boundary(0, 0 + Game.OFFSET_Y, Game.OFFSET_X // 2,
                                      Game.HEIGHT, gray, Game.WIN)
        self.right_boundary = Boundary(Game.WIDTH - Game.OFFSET_X // 2,
                                       0 + Game.OFFSET_Y, Game.OFFSET_X // 2,
                                       Game.HEIGHT, gray, Game.WIN)
        self.top_boundary = Boundary(0, Game.OFFSET_Y // 2, Game.WIDTH,
                                     Game.OFFSET_Y // 2, gray, Game.WIN)

    def break_block(self, a_block):
        a_block.collide()
        self.the_ball.bounce_y()
        self.increase_score()

    def create_blocks(self):
        for c in range(1, self.columns + 1):
            for r in range(3, self.rows + 3):
                this_x = c * Block.WIDTH - (Block.WIDTH) + Game.OFFSET_X // 2
                this_y = r * Block.HEIGHT + (Game.OFFSET_Y * 1.4)
                Block(this_x, this_y, 0, 0, random.choice(block_colors),
                      Game.WIN)

    def increase_score(self):
        self.score += 10
        self.score_text.create_text("SCORE: " + str(self.score))

    def change_lives(self, amount):
        self.lives += amount
        self.lives_text.create_text("LIVES: " + str(self.lives))

    def change_level(self, amount):
        self.level += amount
        self.level_text.create_text("LEVEL: " + str(self.level))

    def increase_rows(self, amount):
        self.rows += amount

    def lost_level(self):
        pygame.time.delay(666)
        self.change_lives(-1)
        self.reset_level()

    def beat_level(self):
        pygame.time.delay(2000)
        self.change_level(1)
        self.change_lives(1)
        self.increase_rows(2)
        self.create_blocks()
        self.reset_level()

    def play_game(self):
        self.menu = False
        self.run = True
        self.main_game()

    def quit_game(self):
        quit()

    def redraw_window(self):
        Game.WIN.fill(black)
        for b in Block.blocks:
            b.draw()

        self.the_paddle.draw()
        self.the_ball.draw()

        self.left_boundary.draw()
        self.right_boundary.draw()
        self.top_boundary.draw()

        self.score_text.draw()
        self.lives_text.draw()
        self.level_text.draw()

    def reset_level(self):
        self.the_ball.reset_ball()
        self.the_paddle.x = Game.WIDTH / 2 - Game.WIDTH / 10 / 2

    def reset_game(self):
        self.score = 11111
        self.lives = 5
        self.level = 9
        self.level_text.create_text("LEVEL: " + str(self.level))
        self.score_text.create_text("SCORE: " + str(self.score))
        self.lives_text.create_text("LIVES: " + str(self.lives))
        self.rows = 17

    def lose(self):
        Game.WIN.fill(black)
        loser_text = TextGUI(Game.WIDTH // 4, Game.HEIGHT // 2, Game.WIN,
                             random.choice(all_taunts), 50)
        loser_text.draw()
        self.reset_game()
        pygame.display.flip()
        pygame.time.delay(5000)
        self.main_menu()

    def win(self):
        loser_text = TextGUI(Game.WIDTH // 2 - Game.WIDTH // 4,
                             Game.HEIGHT // 2, Game.WIN, "YOU WIN!!!", 100)
        loser_text.draw()
        self.reset_game()
        pygame.display.flip()
        pygame.time.delay(3000)
        self.main_menu()

    def main_game(self):
        self.reset_game()
        self.reset_level()
        self.create_blocks()

        clock = pygame.time.Clock()

        while self.run:

            clock.tick(Game.FPS)

            self.redraw_window()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit()

            keys = pygame.key.get_pressed()
            if keys[pygame.K_a] and self.the_paddle.x > 0 + Game.OFFSET_X // 2:
                self.the_paddle.move_left()
            if keys[pygame.
                    K_d] and self.the_paddle.x < Game.WIDTH - self.the_paddle.w - Game.OFFSET_X // 2:
                self.the_paddle.move_right()
            if keys[pygame.K_SPACE]:
                quit()

            if self.the_ball.y - self.the_ball.radius < 0 + Game.OFFSET_Y:
                self.the_ball.bounce_y()
            if self.the_ball.x + self.the_ball.radius > Game.WIDTH - Game.OFFSET_X / 2 or self.the_ball.x - self.the_ball.radius < 0 + Game.OFFSET_X / 2:
                self.the_ball.bounce_x()

            if self.the_ball.y > Game.HEIGHT:
                self.lost_level()

            for block in Block.blocks:
                if self.the_ball.y + self.the_ball.radius > block.y and self.the_ball.y - self.the_ball.radius < block.y + block.h:
                    if self.the_ball.x + self.the_ball.radius > block.x and self.the_ball.x - self.the_ball.radius < block.x + block.w:
                        self.break_block(block)

            if self.the_ball.y + self.the_ball.radius > self.the_paddle.y and self.the_ball.y - self.the_ball.radius < self.the_paddle.y + self.the_paddle.h:
                if self.the_ball.x + self.the_ball.radius > self.the_paddle.x and self.the_ball.x - self.the_ball.radius < self.the_paddle.x + self.the_paddle.w:

                    if self.the_ball.x < self.the_paddle.x + self.the_paddle.w / 2:
                        normalized_ball_x = (self.the_ball.x -
                                             self.the_paddle.x) * -1
                    elif self.the_ball.x >= self.the_paddle.x + self.the_paddle.w / 2:
                        normalized_ball_x = abs(self.the_ball.x -
                                                self.the_paddle.x -
                                                self.the_paddle.w)
                    else:
                        normalized_ball_x = (self.the_ball.x -
                                             self.the_paddle.x) * -1

                    contact_point_fraction = (normalized_ball_x /
                                              self.the_paddle.w) + .0001
                    regularized_fraction = int(1 / contact_point_fraction /
                                               1.5)
                    self.the_ball.x_velocity += regularized_fraction

                    self.the_ball.bounce_y()

            if Block.blocks == []:
                if self.level == 10:
                    self.run = False
                    self.menu = True
                    self.win()
                else:
                    self.beat_level()

            if self.lives == 0:
                self.run = False
                self.menu = True
                self.lose()

            self.the_ball.move_ball()

            pygame.display.flip()

    def main_menu(self):

        button_width = int(Game.WIDTH / 6)
        button_height = int(Game.HEIGHT / 10)

        title = TextGUI(Game.WIDTH // 2 - Game.WIDTH // 10 * 2,
                        Game.HEIGHT // 3, Game.WIN, "BREAKOUT",
                        Game.WIDTH // 20)
        play_button = Button(int(Game.WIDTH / 6 * 2 - button_width / 2),
                             int(Game.HEIGHT / 3 * 2 - button_height),
                             button_width, button_height,
                             random.choice([purple, orange]), Game.WIN, "PLAY",
                             Game.WIDTH // 60, self.play_game)

        quit_button = Button(int(Game.WIDTH / 6 * 4 - button_width / 2),
                             int(Game.HEIGHT / 3 * 2 - button_height),
                             button_width, button_height, red, Game.WIN,
                             "QUIT", Game.WIDTH // 60, self.quit_game)

        clock = pygame.time.Clock()

        while self.menu:
            clock.tick(Game.FPS)

            Game.WIN.fill(black)

            Mouse_x, Mouse_y = pygame.mouse.get_pos()

            title.draw()

            play_button.draw(Mouse_x, Mouse_y)
            play_button.button_text.draw()

            quit_button.draw(Mouse_x, Mouse_y)
            quit_button.button_text.draw()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit()

            pygame.display.flip()
Пример #17
0
class Pong(arcade.Window):
    """
    This class handles all the game callbacks and interaction
    It assumes the following classes exist:
        Point
        Velocity
        Ball
        Paddle

    This class will then call the appropriate functions of
    each of the above classes.

    You are welcome to modify anything in this class,
    but should not have to if you don't want to.
    """

    def __init__(self, width, height):
        """
        Sets up the initial conditions of the game
        :param width: Screen width
        :param height: Screen height
        """
        super().__init__(width, height)

        self.ball = Ball()
        self.paddle = Paddle()
        self.score = 0

        # These are used to see if the user is
        # holding down the arrow keys
        self.holding_left = False
        self.holding_right = False

        arcade.set_background_color(arcade.color.WHITE)

    def on_draw(self):
        """
        Called automatically by the arcade framework.
        Handles the responsiblity of drawing all elements.
        """

        # clear the screen to begin drawing
        arcade.start_render()

        # draw each object
        self.ball.draw()
        self.paddle.draw()

        self.draw_score()

    def draw_score(self):
        """
        Puts the current score on the screen
        """
        score_text = "Score: {}".format(self.score)
        start_x = 10
        start_y = SCREEN_HEIGHT - 20
        arcade.draw_text(score_text, start_x=start_x, start_y=start_y, font_size=12, color=arcade.color.NAVY_BLUE)

    def update(self, delta_time):
        """
        Update each object in the game.
        :param delta_time: tells us how much time has actually elapsed
        """

        # Move the ball forward one element in time
        self.ball.advance()

        # Check to see if keys are being held, and then
        # take appropriate action
        self.check_keys()

        # check for ball at important places
        self.check_miss()
        self.check_hit()
        self.check_bounce()

    def check_hit(self):
        """
        Checks to see if the ball has hit the paddle
        and if so, calls its bounce method.
        :return:
        """
        too_close_x = (PADDLE_WIDTH / 2) + BALL_RADIUS
        too_close_y = (PADDLE_HEIGHT / 2) + BALL_RADIUS

        if (abs(self.ball.center.x - self.paddle.center.x) < too_close_x and
                    abs(self.ball.center.y - self.paddle.center.y) < too_close_y and
                    self.ball.velocity.dx > 0):
            # we are too close and moving right, this is a hit!
            self.ball.bounce_horizontal()
            self.score += SCORE_HIT

    def check_miss(self):
        """
        Checks to see if the ball went past the paddle
        and if so, restarts it.
        """
        if self.ball.center.x > SCREEN_WIDTH:
            # We missed!
            self.score -= SCORE_MISS
            self.ball.restart()

    def check_bounce(self):
        """
        Checks to see if the ball has hit the borders
        of the screen and if so, calls its bounce methods.
        """
        if self.ball.center.x < 0 and self.ball.velocity.dx < 0:
            self.ball.bounce_horizontal()

        if self.ball.center.y < 0 and self.ball.velocity.dy < 0:
            self.ball.bounce_vertical()

        if self.ball.center.y > SCREEN_HEIGHT and self.ball.velocity.dy > 0:
            self.ball.bounce_vertical()

    def check_keys(self):
        """
        Checks to see if the user is holding down an
        arrow key, and if so, takes appropriate action.
        """
        if self.holding_left:
            self.paddle.move_down()

        if self.holding_right:
            self.paddle.move_up()

    def on_key_press(self, key, key_modifiers):
        """
        Called when a key is pressed. Sets the state of
        holding an arrow key.
        :param key: The key that was pressed
        :param key_modifiers: Things like shift, ctrl, etc
        """
        if key == arcade.key.LEFT or key == arcade.key.DOWN:
            self.holding_left = True

        if key == arcade.key.RIGHT or key == arcade.key.UP:
            self.holding_right = True

    def on_key_release(self, key, key_modifiers):
        """
        Called when a key is released. Sets the state of
        the arrow key as being not held anymore.
        :param key: The key that was pressed
        :param key_modifiers: Things like shift, ctrl, etc
        """
        if key == arcade.key.LEFT or key == arcade.key.DOWN:
            self.holding_left = False

        if key == arcade.key.RIGHT or key == arcade.key.UP:
            self.holding_right = False
Пример #18
0
class Game(object):
    """Main program"""

    def __init__(self):
        #Initialize pygame and window
        pygame.init()
        self.screen_width, self.screen_height = 400, 600
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height), 0, 32)
        self.screen.fill(blue)
        pygame.display.update()

        #Clock
        self.clock = pygame.time.Clock()

        #Bricks
        self.blocks = list()
        for w in range(1,self.screen_width,50):
			for h in range(23, 198, 22):
				self.blocks.append(Block(self.screen_width, self.screen_height, w, h, orange, blue_shadow))

        #Paddle
        self.paddle = Paddle(self.screen_width, self.screen_height, purple, blue_shadow)

        #Ball
        self.ball = Ball(self.screen_width, self.screen_height, green, blue_shadow)

    def update(self):
        self.clock.tick(game_speed)

        self.paddle.update()
        self.ball.update(self.paddle)

    def draw(self):
        #Redraw Background
        self.screen.fill(blue)

        for block in self.blocks:
            block.draw_shadow(self.screen)

        self.ball.draw_shadow(self.screen)
        self.paddle.draw_shadow(self.screen)

        for block in self.blocks:
            block.draw(self.screen)

        self.ball.draw(self.screen)
        self.paddle.draw(self.screen)


    def new_game(self):
        self.game_over = False
        self.round = 0

        self.play()

    def new_round(self):
        pass

    def play(self):
        while not self.game_over:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
						self.ball.serve()
                    if event.key == pygame.K_LEFT:
                        self.paddle.x_vel = -4
                    elif event.key == pygame.K_RIGHT:
                        self.paddle.x_vel = 4
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_LEFT and self.paddle.x_vel < 0:
                        self.paddle.x_vel = 0
                    if event.key == pygame.K_RIGHT and self.paddle.x_vel > 0:
                        self.paddle.x_vel = 0
            self.update()
            self.draw()
            pygame.display.update()
Пример #19
0
class PongGame:
    window_width = 650
    window_height = 500

    def __init__(self, four_player=False):
        self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2)
        self.paddle1 = NNPaddle(PongGame.window_width - 50,
                                PongGame.window_height / 2, self.ball, self)
        self.paddle2 = AIPaddle(50, PongGame.window_height / 2, self.ball,
                                self)
        self.paddle3 = None
        self.paddle4 = None

        self.temp_paddle = None
        self.four_player = four_player

        self.winner = None
        self.game_over = False
        self.speed = 1000
        self.scores = [0, 0]
        self.timeout = 0
        self.pause = False

        if self.four_player:
            PongGame.window_width = 650
            PongGame.window_height = 650

            self.ball = Ball(PongGame.window_width / 2,
                             PongGame.window_height / 2)
            self.scores = [0, 0, 0, 0]
            self.paddle1 = NNPaddle(PongGame.window_width - 50,
                                    PongGame.window_height / 2, self.ball,
                                    self, True)
            self.paddle2 = NNPaddle(50, PongGame.window_height / 2, self.ball,
                                    self, True)
            self.paddle3 = SidewaysNNPaddle(PongGame.window_width / 2,
                                            PongGame.window_height - 50,
                                            self.ball, self)
            self.paddle4 = SidewaysNNPaddle(PongGame.window_width / 2, 50,
                                            self.ball, self)

    def start_game(self):
        pygame.init()

        clock = pygame.time.Clock()
        display = pygame.display.set_mode(
            (PongGame.window_width, PongGame.window_height))

        pygame.display.set_caption('Neural Net Pong')

        while not self.game_over:
            delta = clock.tick(60) / self.speed
            display.fill((255, 255, 255))

            # listen for events
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

            # check for user input
            self.handle_input(delta)

            if not self.four_player:
                self.game_over = self.handle_off_screen()
            else:
                self.game_over = self.handle_off_screen_four_player()

            if not self.game_over:
                self.handle_collisions()

            self.paddle1.follow_ball(delta)
            self.paddle2.follow_ball(delta)
            if self.paddle3 is not None and self.paddle4 is not None:
                self.paddle3.follow_ball(delta)
                self.paddle4.follow_ball(delta)

            self.ball.move(delta)

            self.draw(display)
            if self.timeout < 100:
                self.timeout += 1
            if self.pause:
                self.reset()
            pygame.display.flip()

    def draw(self, display):
        self.paddle1.draw(display)
        self.paddle2.draw(display)
        if self.paddle3 is not None and self.paddle4 is not None:
            self.paddle3.draw(display)
            self.paddle4.draw(display)

        self.ball.draw(display)
        self.draw_scoreboard(display)

    def draw_scoreboard(self, display):
        font = pygame.font.Font(None, 25)
        if not self.four_player:
            score = font.render(
                self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' +
                str(self.scores[0]) + ' | ' + self.paddle1.name, True,
                (0, 0, 0))
            info = font.render('Generation ' + str(self.paddle1.generation),
                               True, (0, 0, 0))
            rect = score.get_rect(center=(325, 60))
            info_rect = info.get_rect(center=(325, 90))
            display.blit(score, rect)
            display.blit(info, info_rect)
        else:
            score1 = font.render(
                self.paddle2.name + ' | ' + str(self.scores[1]) + ' - ' +
                str(self.scores[0]) + ' | ' + self.paddle1.name, True,
                (0, 0, 0))
            score2 = font.render(
                self.paddle4.name + ' | ' + str(self.scores[3]) + ' - ' +
                str(self.scores[2]) + ' | ' + self.paddle3.name, True,
                (0, 0, 0))
            rect1 = score1.get_rect(center=(325, 300))
            rect2 = score2.get_rect(center=(325, 350))
            display.blit(score1, rect1)
            display.blit(score2, rect2)

    def handle_input(self, delta):
        # listen for key presses
        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP] and self.paddle2.bounds.y > 0:
            self.paddle2.move_up(delta)
        if keys[pygame.
                K_DOWN] and self.paddle2.bounds.y + self.paddle2.bounds.height < PongGame.window_height:
            self.paddle2.move_down(delta)
        if keys[pygame.K_RIGHT] and self.speed > 10:
            self.speed -= 10
        if keys[pygame.K_LEFT] and self.speed < 1000000:
            self.speed += 10
        if keys[pygame.K_r]:
            self.reset()
        if keys[pygame.K_SPACE] and self.timeout == 100:
            self.timeout = 0
            if self.paddle2.name != 'Player':
                self.temp_paddle = self.paddle2
                self.paddle2 = Paddle(50, PongGame.window_height / 2)
                self.paddle2.score = self.scores[0]
            else:
                self.paddle2 = self.temp_paddle
        if keys[pygame.K_p] and self.timeout == 100:
            if not self.pause:
                self.pause = True
            else:
                self.pause = False

    def handle_collisions(self):
        # collision with paddle
        if self.ball.intersects_paddle(self.paddle2, self.paddle1):
            self.ball.vel_x = -self.ball.vel_x
            self.ball.vel_x *= 1.05
            self.ball.vel_y *= 1.05
        elif self.four_player and self.ball.intersects_top_paddle(
                self.paddle4, self.paddle3):
            self.ball.vel_y = -self.ball.vel_y
            self.ball.vel_x *= 1.05
            self.ball.vel_y *= 1.05
        # collision with ceiling
        if not self.four_player:
            if (self.ball.bounds.y <= 0 and self.ball.vel_y < 0) or (
                    self.ball.bounds.y + self.ball.bounds.height >=
                    PongGame.window_height and self.ball.vel_y > 0):
                self.ball.vel_y = -self.ball.vel_y

    def handle_off_screen_four_player(self):
        if self.paddle1.score >= 6:
            self.winner = self.paddle1
            return True
        elif self.paddle2.score >= 6:
            self.winner = self.paddle2
            return True
        elif self.paddle3.score >= 6:
            self.winner = self.paddle3
            return True
        elif self.paddle4.score >= 6:
            self.winner = self.paddle4
            return True

        if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0:
            self.point_scored()
        elif self.ball.bounds.y + self.ball.bounds.height > PongGame.window_height or self.ball.bounds.y <= 0:
            self.point_scored()
        return False

    def point_scored(self):
        if self.ball.last_hit is not None:
            if self.ball.last_hit == self.paddle1:
                self.scores[0] += 1
                self.paddle1.score += 1
            elif self.ball.last_hit == self.paddle2:
                self.scores[1] += 1
                self.paddle2.score += 1
            elif self.ball.last_hit == self.paddle3:
                self.scores[2] += 1
                self.paddle2.score += 1
            elif self.ball.last_hit == self.paddle4:
                self.scores[3] += 1
                self.paddle3.score += 1

        self.ball = Ball(PongGame.window_width / 2, PongGame.window_height / 2)
        self.paddle1.reset(PongGame.window_width - 50,
                           PongGame.window_height / 2, self.ball)
        self.paddle2.reset(50, PongGame.window_height / 2, self.ball)
        self.paddle3.reset(PongGame.window_width / 2,
                           PongGame.window_height - 50, self.ball)
        self.paddle4.reset(PongGame.window_width / 2, 50, self.ball)

    def handle_off_screen(self):
        if self.paddle1.score >= 3:
            self.winner = self.paddle1
            return True
        elif self.paddle2.score >= 3:
            self.winner = self.paddle2
            return True

        if self.ball.bounds.x + self.ball.bounds.width > PongGame.window_width or self.ball.bounds.x <= 0:
            if self.ball.bounds.x <= 0:
                self.paddle1.score += 1
                self.paddle1.fitness += 10
                self.scores[0] += 1
            else:
                self.paddle2.score += 1
                self.paddle2.fitness += 10
                self.scores[1] += 1
            self.ball = Ball(PongGame.window_width / 2,
                             PongGame.window_height / 2)
            self.paddle1.reset(PongGame.window_width - 50,
                               PongGame.window_height / 2, self.ball)
            self.paddle2.reset(50, PongGame.window_height / 2, self.ball)
        return False

    def reset(self):
        self.ball.reset()
        self.paddle1.reset(PongGame.window_width - 50,
                           PongGame.window_height / 2, self.ball)
        self.paddle1.fitness = 0
        self.paddle1.contacts_ball = 0
        self.paddle1.score = 0
        self.paddle2.reset(50, PongGame.window_height / 2, self.ball)
        self.paddle2.score = 0
        self.scores = [0, 0]
Пример #20
0
class Game(object):
    def __init__(self):
        self.ended = False
        self.paused = False
        self.keys = keyboard.Listener()

        self.player = Paddle()
        self.scores = Scoreboard((0, 20 * config.sprite_size), 57)

        border_graphics(graphic_group)
        demo_blocks(blocks.group)

    def draw(self, screen):
        screen.fill((0, 0, 0))

        graphic_group.draw(screen)
        blocks.group.draw(screen)
        balls.group.draw(screen)

        self.scores.draw(screen)
        self.player.draw(screen)

    def update(self, time):

        self.keys.update()
        if self.paused:
            if self.keys[keyboard.M.SPC]:
                self.paused = False
        else:
            if self.keys[keyboard.M.SPC]:
                self.paused = True

            x_dir = self.keys[keyboard.M.RGT]
            x_dir -= self.keys[keyboard.M.LFT]
            self.player.update(time, x_dir, self.keys[keyboard.M.UP] - 0)

            balls.group.update(time, blocks.group)
            """
			for key, value in block_collisions.iteritems():
				if value == None:
					continue
				for block in value:
					# determine if ball bounces off vertically or horizontally
					d = vector.Vector2D(key.pos.x, key.pos.y)
					
					d.x -= block.rect.x
					d.y -= block.rect.y

					if d.x ** 2 < d.y ** 2:
						key.bounceX()
					else:
						key.bounceY()
					#	destroy block 
					del block
				config.sounds['beep.wav'].play()
			"""

            # update balls
            # update blocks
            self.scores.update()

        if self.keys[keyboard.M.ESC]:
            self.end()

        return self.ended

    def end(self):
        self.ended = True
Пример #21
0
from paddle import Paddle
from inputs import handle_input

TICK_RATE = 30
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Pygame Pong Game")
clock = pygame.time.Clock()
done = [False]

ball = Ball()
left_paddle = Paddle()
left_paddle.rect.x = left_paddle.rect.x + 20
right_paddle = Paddle()
right_paddle.rect.x = SCREEN_WIDTH - right_paddle.rect.width

while not done[0]:
    clock.tick(TICK_RATE)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    handle_input(left_paddle, right_paddle)
    screen.fill(BLACK)
    ball.draw(screen)
    ball.update(left_paddle, right_paddle, done)
    left_paddle.draw(screen)
    right_paddle.draw(screen)

    pygame.display.flip()

pygame.quit()
Пример #22
0
class PongGame:

    # Class Variables
    WIDTH = 1000
    GAME_HEIGHT = 600
    BORDER = 15
    PADDLE_SPACING = 50  # Space between edge of paddle and end of screen
    FPS = 60
    BOTTOM_HEIGHT = 100
    GAME_TEXT_LOC = (WIDTH // 2 - 100, 25)
    SCORE_LOC = (30, GAME_HEIGHT + BORDER + 20)

    def __init__(self):
        self.screen = pygame.display.set_mode(
            (self.WIDTH, self.GAME_HEIGHT + self.BOTTOM_HEIGHT))

        self.ball = Ball(self.screen, (self.WIDTH // 2, self.GAME_HEIGHT // 2))

        right_paddle_pos = (self.WIDTH - (self.PADDLE_SPACING + Paddle.WIDTH),
                            self.GAME_HEIGHT // 2 - Paddle.HEIGHT // 2)
        left_paddle_pos = (self.PADDLE_SPACING,
                           self.GAME_HEIGHT // 2 - Paddle.HEIGHT // 2)
        self.right_paddle = Paddle(self.screen, right_paddle_pos,
                                   RIGHT_PADDLE_COLOR, RIGHT_PADDLE_SPEED)
        self.left_paddle = AIPaddle(self.screen, left_paddle_pos,
                                    LEFT_PADDLE_COLOR, LEFT_PADDLE_SPEED)

        self.score = 0
        pygame.display.set_caption(f"Pong - Level {self.score + 1}")

    def draw_game(self):
        self.right_paddle.draw()
        self.left_paddle.draw()
        self.ball.draw()
        self.draw_border()
        self.display_score()

    def display_score(self):
        """
        Updates score in bottom section.
        """
        pygame.draw.rect(self.screen, BG_COLOR,
                         (self.SCORE_LOC[0], self.SCORE_LOC[1], 200, 40))

        pygame.font.init()
        font = pygame.font.SysFont('calibri', 30)
        score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR)
        self.screen.blit(score_text_surface, self.SCORE_LOC)

    def draw_border(self):
        pygame.draw.rect(self.screen, BORDER_COLOR,
                         (0, 0, self.WIDTH, self.BORDER))
        pygame.draw.rect(
            self.screen, BORDER_COLOR,
            (0, self.GAME_HEIGHT - self.BORDER, self.WIDTH, self.BORDER))

    def move_player(self, dir: str, dt: int):
        if dir == 'up':
            dir_vec = -1
        elif dir == 'down':
            dir_vec = 1
        else:
            dir_vec = 0

        new_y = self.right_paddle.y + round(
            dir_vec * self.right_paddle.speed * dt)
        if new_y < self.BORDER:
            new_y = self.BORDER

        elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT):
            new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT

        self.right_paddle.update(new_y)

    def move_ai(self, dt: int):
        self.left_paddle.check_fail()

        # If the AI is not failed, paddle moves towards ball
        if self.left_paddle.is_failed == False:

            # Move towards the ball if the ball y coordinate is outside the range of the paddle
            if 0 <= self.ball.x < round(self.WIDTH * (2 / 5)):
                if self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) < (
                        -1 * Paddle.HEIGHT // 2):
                    dir_vec = -1
                elif self.ball.y - (self.left_paddle.y +
                                    Paddle.HEIGHT // 2) > (Paddle.HEIGHT // 2):
                    dir_vec = 1
                else:
                    dir_vec = 0

                new_y = self.left_paddle.y + round(
                    dir_vec * self.left_paddle.speed * dt)
                if new_y < self.BORDER:
                    new_y = self.BORDER

                elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT):
                    new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT

                self.left_paddle.update(new_y)

            # Only move towards the ball if y coordinate is over threshold distance away from paddle center
            elif round(self.WIDTH * (2 / 5)) <= self.ball.x < self.WIDTH:

                threshold = 2 * Paddle.HEIGHT

                if self.ball.y - (self.left_paddle.y + Paddle.HEIGHT // 2) < (
                        -1 * threshold):
                    dir_vec = -1
                elif self.ball.y - (self.left_paddle.y +
                                    Paddle.HEIGHT // 2) > (threshold):
                    dir_vec = 1
                else:
                    dir_vec = 0

                new_y = self.left_paddle.y + round(
                    dir_vec * self.left_paddle.speed * dt)
                if new_y < self.BORDER:
                    new_y = self.BORDER

                elif new_y > (self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT):
                    new_y = self.GAME_HEIGHT - self.BORDER - Paddle.HEIGHT

                self.left_paddle.update(new_y)

    def move_ball(self, dt: int):
        new_x = self.ball.x + round(
            self.ball.direction.value[0] * self.ball.speed * dt)
        new_y = self.ball.y + round(
            self.ball.direction.value[1] * self.ball.speed * dt)

        if new_y <= (self.BORDER + Ball.RADIUS):
            new_y = self.BORDER + Ball.RADIUS
            self.ball_collide('top')

        elif new_y >= (self.GAME_HEIGHT - self.BORDER - Ball.RADIUS):
            new_y = self.GAME_HEIGHT - self.BORDER - Ball.RADIUS
            self.ball_collide('bottom')

        elif (self.right_paddle.x - Ball.RADIUS) <= new_x < (
                self.right_paddle.x + Paddle.WIDTH + Ball.RADIUS):
            if self.right_paddle.y - Ball.RADIUS <= new_y <= self.right_paddle.y + Paddle.HEIGHT + Ball.RADIUS:
                new_x = self.right_paddle.x - Ball.RADIUS
                self.ball_collide('right')

        elif (self.left_paddle.x - Ball.RADIUS) <= new_x < (
                self.left_paddle.x + Paddle.WIDTH + Ball.RADIUS):
            if self.left_paddle.y - Ball.RADIUS <= new_y <= self.left_paddle.y + Paddle.HEIGHT + Ball.RADIUS:
                new_x = self.left_paddle.x + Paddle.WIDTH + Ball.RADIUS
                self.ball_collide('left')

        self.ball.update((new_x, new_y))

    def ball_collide(self, collision_loc: str):
        """

        """
        if collision_loc == 'top':
            if self.ball.direction == Directions.UP_LEFT:
                self.ball.change_direction(Directions.DOWN_LEFT)

            elif self.ball.direction == Directions.UP_RIGHT:
                self.ball.change_direction(Directions.DOWN_RIGHT)

        elif collision_loc == 'bottom':
            if self.ball.direction == Directions.DOWN_LEFT:
                self.ball.change_direction(Directions.UP_LEFT)

            elif self.ball.direction == Directions.DOWN_RIGHT:
                self.ball.change_direction(Directions.UP_RIGHT)

        elif collision_loc == 'right':
            if self.ball.direction == Directions.DOWN_RIGHT:
                self.ball.change_direction(Directions.DOWN_LEFT)

            elif self.ball.direction == Directions.UP_RIGHT:
                self.ball.change_direction(Directions.UP_LEFT)

        elif collision_loc == 'left':
            if self.ball.direction == Directions.DOWN_LEFT:
                self.ball.change_direction(Directions.DOWN_RIGHT)

            elif self.ball.direction == Directions.UP_LEFT:
                self.ball.change_direction(Directions.UP_RIGHT)

        else:
            raise ValueError(f"Invalid direction: {collision_loc}")

    def score_goal(self):
        """
        Updates the score and resets the ball and paddles to the middle.
        """
        self.score += 1
        self.left_paddle.update_prob(self.score)

        # Display Score
        pygame.font.init()
        font = pygame.font.SysFont('calibri', 50)
        score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR)
        self.screen.blit(score_text_surface, self.GAME_TEXT_LOC)

        self.display_score()

        self.ball.update((self.WIDTH // 2, self.GAME_HEIGHT // 2))
        self.ball.change_direction(random.choice(list(Directions)))

        self.left_paddle.update(self.GAME_HEIGHT // 2 -
                                self.left_paddle.HEIGHT // 2)
        self.right_paddle.update(self.GAME_HEIGHT // 2 -
                                 self.right_paddle.HEIGHT // 2)

    def lose(self):
        """
        Displays 'You Lose' and freezes the game.
        """
        paused = True

        # Display "You Lose!"
        pygame.font.init()
        font = pygame.font.SysFont('calibri', 50)
        lose_text_surface = font.render("You Lose!", 1, TEXT_COLOR)
        score_text_surface = font.render(f"Score: {self.score}", 1, TEXT_COLOR)

        self.screen.blit(lose_text_surface, self.GAME_TEXT_LOC)

        x, y = self.GAME_TEXT_LOC
        self.screen.blit(score_text_surface, (x + 15, y + 60))
        pygame.display.update()

        while paused:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    paused = False

            #TODO: ask to start new game
        return False

    def run(self):
        clock = pygame.time.Clock()
        running = True
        frozen = False
        frames_frozen = 0
        freeze_length = self.FPS * 4  # frames in 4 seconds

        while running:
            dt = clock.tick(self.FPS)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

            if not frozen:
                keys = pygame.key.get_pressed()
                if keys[pygame.K_UP]:
                    self.move_player('up', dt)

                elif keys[pygame.K_DOWN]:
                    self.move_player('down', dt)

                self.move_ball(dt)
                self.move_ai(dt)

                if self.ball.x <= 0:
                    frozen = True
                    self.score_goal()

                elif self.ball.x >= self.WIDTH:
                    running = self.lose()

            else:
                frames_frozen += 1

                if frames_frozen == freeze_length:
                    frozen = False
                    frames_frozen = 0
                    pygame.draw.rect(self.screen, BG_COLOR,
                                     (self.GAME_TEXT_LOC[0],
                                      self.GAME_TEXT_LOC[1], 200, 50))

            pygame.display.update()

        pygame.quit()
Пример #23
0
class Level:  # pylint: disable=too-many-instance-attributes
    """ Class representing a level. It keeps track of all sprites:
        balls, the paddle, tiles, explosions and bonuses. """
    sounds = {
        "death": pygame.mixer.Sound(os.path.join("sounds", "death.wav")),
        "next_level":
        pygame.mixer.Sound(os.path.join("sounds", "next_level.wav")),
    }

    def __init__(self, n):
        self.paddle = Paddle()
        self.balls = pygame.sprite.Group()
        ball = Ball()
        self.balls.add(ball)
        self.paddle.attached_balls.add(ball)

        self.tile_matrix = [[None for _ in range(16)] for _ in range(16)]
        self.tiles = pygame.sprite.Group()
        if n != 0:  # case n = 0 is used for testing
            with open(os.path.join("levels", f"{n}.pkl"), "rb") as file:
                file = pickle.load(file)
                for line in file.split("\n"):
                    try:
                        j, i, alias = line.split()
                        if alias not in Tile.types:
                            raise RuntimeError(f"invalid tile type: {alias}")
                        i, j = int(i), int(j)
                        tile = Tile.types[alias](MARGIN + 60 * i,
                                                 3 * MARGIN + 30 * j)
                        self.tile_matrix[i][j] = tile
                        self.tiles.add(tile)
                    except (TypeError, ValueError):
                        pass

        self.bonuses = pygame.sprite.Group()
        self.explosions = pygame.sprite.Group()

        self.n = n
        self.finished = False
        self.paused = False
        Ball.reset_state()

    def draw(self, surface):
        # draw all sprites
        self.explosions.draw(surface)
        self.paddle.draw(surface)
        self.balls.draw(surface)
        self.tiles.draw(surface)
        self.bonuses.draw(surface)

        # conditional text
        if self.finished:
            message = "Level Cleared!"
            text = message_font.render(message, True, pygame.Color("white"))
            w, h = text.get_size()
            x, y = (SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2
            surface.blit(text, (x, y))
        elif self.paused:
            text = message_font.render("Pause", True, pygame.Color("white"))
            w, h = text.get_size()
            x, y = (SCREEN_WIDTH - w) // 2, (SCREEN_HEIGHT - h) // 2
            surface.blit(text, (x, y))

    def update(self):
        """ Updates the postions of all sprites. """
        self.paddle.update(paused=self.finished or self.paused)
        if not (self.finished or self.paused):
            self.balls.update()
            self.bonuses.update()
            if not self.balls:
                pygame.event.post(pygame.event.Event(events.DEATH))
            elif all(isinstance(tile, Brick) for tile in self.tiles):
                self.finished = True
                self.sounds["next_level"].play()
            else:
                self.detect_collisions()
        self.explosions.update()

    def detect_collisions(self):
        """ Detects sprite collisions. """
        # paddle vs. balls
        for ball in pygame.sprite.spritecollide(self.paddle, self.balls,
                                                False):
            ball.on_hit(self.paddle)

        # paddle vs. bonuses
        for bonus in pygame.sprite.spritecollide(self.paddle, self.bonuses,
                                                 True):
            bonus.on_collect()

        # balls vs. tiles
        for ball in self.balls:
            for tile in pygame.sprite.spritecollide(ball, self.tiles, False):
                ball.hit(tile)
                break

    def explosion(self, x, y):
        """ Trigerred when an explosion occurs. Destoys all tiles around
            the explosion center. """
        i, j = (x - MARGIN) // 60, (y - 3 * MARGIN) // 30
        for k in range(-1, 2):
            for l in range(-1, 2):
                try:
                    tile = self.tile_matrix[i + k][j + l]
                    x, y = MARGIN + 60 * (i + k) + 30, 3 * MARGIN + 30 * (
                        j + l) + 15
                    if MARGIN < x <= SCREEN_WIDTH - MARGIN:
                        mute = not (k == 0 and l == 0)
                        self.explosions.add(Explosion(x, y, mute=mute))
                        if tile.alive():
                            tile.kill()
                except (AttributeError, IndexError):
                    pass

    def on_death(self):
        """ Triggered when player loses all balls. """
        if self.n != 0:
            self.sounds["death"].play()
            time.sleep(1)

        Ball.reset_state()

        # refresh paddle, ball, delete bonuses
        self.bonuses.empty()
        self.paddle = Paddle()
        self.balls.empty()
        ball = Ball()
        self.balls.add(ball)
        self.paddle.attached_balls.add(ball)
Пример #24
0
class Breakout(object):
	def __init__(self):
		# Initilaize pygame and the display/window
		pygame.init()
		self.screen_width, self.screen_height = 600, 800
		self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))  # , pygame.FULLSCREEN)
		pygame.display.set_caption('Breakout')
		
		# Create the game objects
		self.paddle = Paddle(self.screen_width, self.screen_height)
		self.ball = Ball(self.screen_width, self.screen_height)
		self.bricks = list()
		for i in range(0,600,60):
			for j in range(42, 211, 42):
				self.bricks.append(Brick(self.screen_width, self.screen_height, i, j))

		# Let's control the frame rate
		self.clock = pygame.time.Clock()

	def new_game(self):
		"""Start a new game of Breakout.

		Resets all game-level parameters, and starts a new round.
		"""
		self.game_over = False
		self.round = 0
		self.paddle.reset()

		self.new_round()

	def new_round(self):
		"""Start a new round in a Breakout game.

		Resets all round-level parameters, increments the round counter, and
		puts the ball on the paddle.
		"""
		self.round += 1
		self.ball.reset(self.paddle)

	def play(self):
		"""Start Breakout program.

		New game is started and game loop is entered.
		The game loop checks for events, updates all objects, and then
		draws all the objects.
		"""
		self.new_game()
		while not self.game_over:           # Game loop
			self.clock.tick(50)             # Frame rate control
			font = pygame.font.SysFont("monospace", 15)
			round_counter = font.render("Round " + str(self.round), 2, (255,255,0))
		
			for event in pygame.event.get():
				if event.type == pygame.QUIT or event.type == pygame.MOUSEBUTTONDOWN:
					self.game_over = True
					break
				if event.type == pygame.KEYDOWN:
					if event.key == pygame.K_SPACE:
						self.ball.serve()
					if event.key == pygame.K_LEFT:
						self.paddle.x_velocity = -4
					elif event.key == pygame.K_RIGHT:
						self.paddle.x_velocity = 4
					if event.key == pygame.K_a:
						self.ball.x_velocity = -3
					elif event.key == pygame.K_d:
						self.ball.x_velocity = 3

					# This starts a new round, it's only here for debugging purposes
					if event.key == pygame.K_r:
						self.new_round()
					# This starts a new game, it's only here for debugging purposes
					if event.key == pygame.K_g:
						self.new_game()
				if event.type == pygame.KEYUP:
					if event.key == pygame.K_LEFT and self.paddle.x_velocity < 0:
						self.paddle.x_velocity = 0
					if event.key == pygame.K_RIGHT and self.paddle.x_velocity > 0:
						self.paddle.x_velocity = 0
			else:
				self.paddle.update()
				contact = self.ball.update(self.paddle, self.bricks)
				for brick in self.bricks:
					if contact == brick:
						self.bricks.remove(brick)
					

				self.screen.fill((0, 0, 0))
				self.screen.blit(round_counter, (0, 0))
				ball_loc = font.render(str(self.ball.x) + "," + str(self.ball.y), 2, (255,255,0))
				self.screen.blit(ball_loc, (0, 14))
				self.paddle.draw(self.screen)
				self.ball.draw(self.screen)
				pygame.display.flip()
		
		
				for brick in self.bricks:
					brick.draw(self.screen)
				
				pygame.display.flip()
					
				if self.ball.y >= self.screen_height - self.ball.radius:
					self.new_round()
				if self.round > 3:
					self.new_game()
		

		pygame.quit()
Пример #25
0
class PlayState(BaseState):
    def __init__(self):
        super().__init__()
        self.serving_player = 1
        self.winner = 1
        self.ball_prev_speed = 0

    def enter(self, enter_params=None):
        # Get needed settings
        self.window_width = Settings.instance().settings['window_width']
        self.window_height = Settings.instance().settings['window_height']
        self.paddle_width = Settings.instance().settings['paddle_width']
        self.paddle_height = Settings.instance().settings['paddle_height']
        self.paddle_tolerance_beginner = Settings.instance(
        ).settings['paddle_tolerance_beginner']
        self.paddle_tolerance_Intermediate = Settings.instance(
        ).settings['paddle_tolerance_Intermediate']
        self.paddle_tolerance_expert = Settings.instance(
        ).settings['paddle_tolerance_expert']
        self.ball_speed_increase_beginner = Settings.instance(
        ).settings['ball_speed_increase_beginner']
        self.ball_speed_increase_intermediate = Settings.instance(
        ).settings['ball_speed_increase_intermediate']
        self.ball_speed_increase_expert = Settings.instance(
        ).settings['ball_speed_increase_expert']
        self.paddle_special_hit_threshold = Settings.instance(
        ).settings['paddle_special_hit_threshold']
        self.paddle_special_hit_increase = Settings.instance(
        ).settings['paddle_special_hit_increase']
        self.net_segments = Settings.instance().settings['net_segments']
        self.net_segments_gap = Settings.instance(
        ).settings['net_segments_gap']
        self.net_segments_height = Settings.instance(
        ).settings['net_segments_height']
        self.net_segment_width = Settings.instance(
        ).settings['net_segment_width']
        self.win_score = Settings.instance().settings['win_score']

        # Save enter parameters
        self.num_players = enter_params.get('num_players')
        self.input_device = enter_params.get('input_device')
        self.difficulty = enter_params.get('difficulty')
        self.is_demo = enter_params.get('is_demo')
        if self.is_demo is None:
            self.is_demo = False

        # Load Fonts
        load_font('fonts\\font.ttf', 'small_medium', self.cached_fonts, 32)
        load_font('fonts\\font.ttf', 'huge', self.cached_fonts, 128)

        # Load Sounds
        load_sound('sounds\\paddle_hit.wav', 'paddle_hit', self.cached_sounds)
        load_sound('sounds\\score.wav', 'score', self.cached_sounds)
        load_sound('sounds\\wall_hit.wav', 'wall_hit', self.cached_sounds)
        load_sound('sounds\\paddle_special_hit.wav', 'paddle_special_hit',
                   self.cached_sounds)

        # Play music
        play_music(1, self.music)

        # Create Entites
        self.ball = Ball(self.window_width // 2, self.window_height // 2,
                         Settings.instance().settings['ball_radius'])
        self.player1 = Paddle(self.paddle_width // 2,
                              self.paddle_height // 2 + 100, self.paddle_width,
                              self.paddle_height)
        self.player2 = Paddle(
            self.window_width - self.paddle_width // 2,
            self.window_height - self.paddle_height // 2 - 100,
            self.paddle_width, self.paddle_height)

        self.ball.set_initial_speed(self.serving_player == 2)

        # Set tolerance according to difficulty
        tolerance = random.randint(self.paddle_tolerance_beginner[0],
                                   self.paddle_tolerance_beginner[1]) / 100
        self.speed_increase = self.ball_speed_increase_beginner
        if self.difficulty == 'intermediate':
            tolerance = random.randint(
                self.paddle_tolerance_Intermediate[0],
                self.paddle_tolerance_Intermediate[1]) / 100
            self.speed_increase = self.ball_speed_increase_intermediate
        if self.difficulty == 'expert':
            tolerance = random.randint(self.paddle_tolerance_expert[0],
                                       self.paddle_tolerance_expert[1]) / 100
            self.speed_increase = self.ball_speed_increase_expert
        self.player2.set_tolerance(tolerance)

        # Load particle system
        self.particle_system = ParticleSystem(
            self.ball.get_position()[0],
            self.ball.get_position()[1], ParticleShape.SQUARE,
            Settings.instance().settings['particle_size'],
            Settings.instance().settings['particle_birth_rate'],
            Settings.instance().settings['particle_speed'],
            Settings.instance().settings['particle_death_age'])
        gradient = Gradient(
            Settings.instance().settings['particle_gradient_color_01'],
            Settings.instance().settings['particle_gradient_last_color'])
        gradient.add_color(
            Settings.instance().settings['particle_gradient_color_02'],
            Settings.instance().settings['particle_gradient_color_02_pos'])
        gradient.add_color(
            Settings.instance().settings['particle_gradient_color_03'],
            Settings.instance().settings['particle_gradient_color_03_pos'])
        gradient.add_color(
            Settings.instance().settings['particle_gradient_color_04'],
            Settings.instance().settings['particle_gradient_color_04_pos'])
        self.particle_system.set_gradient(gradient)
        self.particle_system.set_death_variance(
            Settings.instance().settings['particle_death_variant'])
        self.particle_system.set_speed_variance(
            Settings.instance().settings['particle_speed_variant'])

    def exit(self):
        pass

    def handle_events(self, events):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if not self.is_demo:
                        statemachine.StateMachine.instance().push('game_menu')
                    else:
                        statemachine.StateMachine.instance().set_change(
                            'main_menu')
                if event.key == pygame.K_LCTRL:
                    if self.player1.ball_hits >= self.paddle_special_hit_threshold:
                        self.player1.going_to_hit_special = True
                if event.key == pygame.K_RCTRL:
                    if self.num_players == 2 and self.player2.ball_hits >= self.paddle_special_hit_threshold:
                        self.player2.going_to_hit_special = True

    def update(self, dt):
        if not self.is_demo:
            # Move player/s with keyboard or mouse
            if self.input_device == 'keyboard':
                self.on_keypress(dt)
            else:
                self.on_mouse_move()

            # Update player2 if it is a 1 player game
            if self.num_players == 1:
                self.player2.update(dt, self.ball)
        else:
            self.player1.demo(self.ball)
            self.player2.demo(self.ball)

        # Update ball movement
        self.ball.update(dt)

        # Check collisions with bounds
        self.ball_bounds_collision()

        # Ball collision with player1
        if self.ball.collides(self.player1):
            self.ball_paddle_collision(self.player1)

        # Ball collision with player2
        if self.ball.collides(self.player2):
            self.ball_paddle_collision(self.player2)

        self.particle_system.update(dt)
        self.particle_system.set_position(self.ball.get_position())

        if not self.is_demo:
            # Player 1 scores
            if self.ball.left() > self.window_width:
                self.player_scores(self.player1)

            # Player 2 scores
            if self.ball.right() < 0:
                self.player_scores(self.player2)

    def render(self, render_screen):
        # draw the net
        self.draw_net(render_screen)

        # draw the score
        draw_text(render_screen, self.cached_fonts['huge'], (255, 255, 255),
                  True, str(self.player1.score),
                  (self.window_width // 4, self.window_height // 4))
        draw_text(render_screen, self.cached_fonts['huge'], (255, 255, 255),
                  True, str(self.player2.score),
                  (self.window_width * 3 // 4, self.window_height // 4))

        # Draw special hit prompt
        time = int(pygame.time.get_ticks() / 500)
        if self.player1.ball_hits == self.paddle_special_hit_threshold:
            if not self.player1.going_to_hit_special:
                if time % 2 == 0:
                    draw_text(
                        render_screen, self.cached_fonts['small_medium'],
                        (255, 255, 255), True,
                        'Press Left Ctrl for a special hit!',
                        (self.window_width * 1 // 4, self.window_height // 10))
            else:
                if time % 2 == 0:
                    draw_text(
                        render_screen, self.cached_fonts['small_medium'],
                        (255, 255, 255), True, 'Hitting special!',
                        (self.window_width * 1 // 4, self.window_height // 10))
        if self.num_players == 2 and self.player2.ball_hits == self.paddle_special_hit_threshold:
            if not self.player2.going_to_hit_special:
                if time % 2 == 0:
                    draw_text(
                        render_screen, self.cached_fonts['small_medium'],
                        (255, 255, 255), True,
                        'Press Right Ctrl for a special hit!',
                        (self.window_width * 3 // 4, self.window_height // 10))
            else:
                if time % 2 == 0:
                    draw_text(
                        render_screen, self.cached_fonts['small_medium'],
                        (255, 255, 255), True, 'Hitting special!',
                        (self.window_width * 3 // 4, self.window_height // 10))

        # Draw the ball
        self.ball.draw(render_screen)
        # Draw the paddles
        self.player1.draw(render_screen)
        self.player2.draw(render_screen)

        self.particle_system.render(render_screen)

    def draw_net(self, render_screen):
        start_pos = (self.window_width // 2, 0)
        end_pos = (start_pos[0], start_pos[1] + self.net_segments_height)
        pygame.draw.line(render_screen, (255, 255, 255), start_pos, end_pos,
                         self.net_segment_width)

        for _ in range(1, self.net_segments):
            start_pos = (end_pos[0], end_pos[1] + self.net_segments_gap)
            end_pos = (start_pos[0], start_pos[1] + self.net_segments_height)
            pygame.draw.line(render_screen, (255, 255, 255), start_pos,
                             end_pos, self.net_segment_width)

    def on_keypress(self, dt):
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_w]:
            self.player1.move(True, dt)
        elif pressed[pygame.K_s]:
            self.player1.move(False, dt)

        if self.num_players == 2:
            if pressed[pygame.K_UP]:
                self.player2.move(True, dt)
            elif pressed[pygame.K_DOWN]:
                self.player2.move(False, dt)

    def on_mouse_move(self):
        position = pygame.mouse.get_pos()
        self.player1.set_position(self.player1.get_position()[0], position[1])

    def player_scores(self, player):
        player.score += 1
        self.player1.reset_ball_hits()
        self.player2.reset_ball_hits()

        if player == self.player1:
            self.serving_player = 2
        else:
            self.serving_player = 1
        self.cached_sounds['score'].play()
        if player.score == self.win_score:
            if player == self.player1:
                self.winner = 1
            else:
                self.winner = 2
            statemachine.StateMachine.instance().set_change(
                'win', {
                    'winner': self.winner,
                    'player1_score': self.player1.score,
                    'player2_score': self.player2.score
                })
        else:
            pygame.time.delay(200)
            self.ball.reset()
            self.ball.set_initial_speed(self.serving_player == 2)

    def ball_bounds_collision(self):
        # Ball collision with upper bound
        if self.ball.top() <= 0:
            self.ball.dy = -self.ball.dy
            self.ball.set_position(self.ball.get_position()[0],
                                   self.ball.radius)
            self.cached_sounds['wall_hit'].play()

        # Ball collision with lower bound
        if self.ball.bottom() > self.window_height:
            self.ball.dy = -self.ball.dy
            self.ball.set_position(self.ball.get_position()[0],
                                   self.window_height - self.ball.radius)
            self.cached_sounds['wall_hit'].play()

    def ball_paddle_collision(self, player):
        # Add a hit to player
        if player.ball_hits < self.paddle_special_hit_threshold:
            player.add_ball_hit()

        # Set the ball position
        if player == self.player1:
            self.ball.set_position(player.width + self.ball.radius + 1,
                                   self.ball.get_position()[1])
        else:
            self.ball.set_position(
                self.window_width - player.width - self.ball.radius - 1,
                self.ball.get_position()[1])

        # Calculate the new speed
        speed = math.sqrt(self.ball.dx**2 + self.ball.dy**2)
        if self.difficulty == 'beginner':
            speed *= self.ball_speed_increase_beginner
        if self.difficulty == 'intermediate':
            speed *= self.ball_speed_increase_intermediate
        if self.difficulty == 'expert':
            speed *= self.ball_speed_increase_expert
        if player.going_to_hit_special:
            self.ball_prev_speed = self.ball.speed()
            speed *= self.paddle_special_hit_increase
            player.hit_special = True
            player.going_to_hit_special = False
            player.reset_ball_hits()
            self.cached_sounds['paddle_special_hit'].play()

        opponent = self.player1
        if player == self.player1:
            opponent = self.player2
        if opponent.hit_special:
            speed = self.ball_prev_speed
            opponent.hit_special = False

        # Calculate new direction
        direction_y = min(random.random(), 0.6)
        if self.ball.get_position()[1] < player.get_position()[1]:
            direction_y *= -1.0
        direction_x = math.sqrt(1 - direction_y**2)
        if player == self.player2:
            direction_x *= -1

        # Calculate the new velocity
        self.ball.dx = direction_x * speed
        self.ball.dy = direction_y * speed

        # Play the paddle hit sound
        self.cached_sounds['paddle_hit'].play()
Пример #26
0
class Pong:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.screen_rect = self.screen.get_rect()
        self.settings = Settings()
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Pong")
        self.sound = Sound()
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.play_button = Button(self, "Play")

    def run_game(self):
        while True:
            self._check_events()
            if self.stats.game_active:
                self._check_ball_location()
                self._check_paddle_ball_collision()
                self._check_bullet_ball_collision()
                self.left_paddle.update()
                self.right_paddle.update()
                self.ball.update()
                self._update_bullets()
            self._update_screen()

    def _create_game_elements(self):
        self.settings.initialize_dynamic_settings()
        self.left_paddle = Paddle(self, 'left')
        self.right_paddle = Paddle(self, 'right')
        self.ball = Ball(self)

        self.left_paddle_bullets = pygame.sprite.Group()
        self.right_paddle_bullets = pygame.sprite.Group()

        # Store all game sprites in a managable group.
        self.sprites = pygame.sprite.Group()
        self.sprites.add(self.left_paddle)
        self.sprites.add(self.right_paddle)
        self.sprites.add(self.ball)

    def _check_events(self):
        """"Listen for when user presses buttons"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks Play."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            self.stats.reset_stats()
            self.sb.prep_score()
            self.stats.game_active = True
            self._create_game_elements()
            pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        # left_paddle keydown events
        if event.key == pygame.K_e:
            self.left_paddle.moving_up = True
        elif event.key == pygame.K_d:
            self.left_paddle.moving_down = True
        elif event.key == pygame.K_c:
            self._fire_bullet(self.left_paddle)
        # right_paddle keydown events
        elif event.key == pygame.K_y:
            self.right_paddle.moving_up = True
        elif event.key == pygame.K_h:
            self.right_paddle.moving_down = True
        elif event.key == pygame.K_n:
            self._fire_bullet(self.right_paddle)
        # System keydown events
        elif event.key == pygame.K_ESCAPE:
            sys.exit()

    def _check_keyup_events(self, event):
        # left_paddle keyup events
        if event.key == pygame.K_e:
            self.left_paddle.moving_up = False
        elif event.key == pygame.K_d:
            self.left_paddle.moving_down = False
        # right_paddle keyup events
        elif event.key == pygame.K_y:
            self.right_paddle.moving_up = False
        elif event.key == pygame.K_h:
            self.right_paddle.moving_down = False

    def _check_ball_location(self):
        # Bounces on the top or bottom of the surface
        if self.ball.rect.bottom >= self.screen_rect.bottom:
            self._bounce(1)
        if self.ball.rect.top <= self.screen_rect.top:
            self._bounce(1)
        # Scores a goal on the left or right end of the surface
        if self.ball.rect.x < self.screen_rect.left:
            self._goal(self.right_paddle)
        if self.ball.rect.x >= self.screen_rect.right:
            self._goal(self.left_paddle)

    def _check_paddle_ball_collision(self):
        if (pygame.sprite.collide_rect(self.ball, self.left_paddle)
                or pygame.sprite.collide_rect(self.ball, self.right_paddle)):
            if self._check_rim_shot():
                self._bounce(1)
            else:
                self._normal_shot()

    def _normal_shot(self):
        self._bounce(0)
        self._chaos_generator()
        self.stats.rally_length += 1
        if self.stats.rally_length > 0:
            if self.stats.rally_length % 3 == 0:
                self.settings.increase_speed()

    def _check_rim_shot(self):
        if (self.ball.rect.left < (self.left_paddle.rect.right - 20)
                or self.ball.rect.right > (self.right_paddle.rect.left + 20)):
            return True

    def _bounce(self, axis):
        self.settings.velocity[axis] *= -1

    def _check_bullet_ball_collision(self):
        """ Bullets make the ball change y velocity. X velocity is modified so
        that the ball is moving away from the paddle """
        left_collided = pygame.sprite.spritecollideany(
            self.ball, self.left_paddle_bullets)
        if left_collided:
            self._ricochet()
            self.left_paddle_bullets.remove(left_collided)
            if self.settings.velocity[0] < 0:
                self._reflect_bullet()

        right_collided = pygame.sprite.spritecollideany(
            self.ball, self.right_paddle_bullets)
        if right_collided:
            self._ricochet()
            self.right_paddle_bullets.remove(right_collided)
            if self.settings.velocity[0] > 0:
                self._reflect_bullet()

    def _ricochet(self):
        if abs(self.settings.velocity[1]) > abs(self.settings.velocity[0]):
            self.settings.velocity[0] = self.settings.velocity[0] / (
                self.settings.velocity[0] / self.settings.velocity[1])
            self.settings.velocity[1] = (
                self.settings.velocity[1] *
                (self.settings.velocity[0] / self.settings.velocity[1])) * (
                    (-1)**randint(2, 3))
        else:
            self.settings.velocity[1] *= -1
        self._chaos_generator()
        self.sound.ricochet()

    def _reflect_bullet(self):
        self._bounce(0)

    def _chaos_generator(self):
        """ Adjust velocity of ball slightly after paddle/ball collision
        to make game more interesting
        """
        chaos_index = (randint(-10, 25) / 100) + 1
        # Chaos index will be more likely to make y velocity more accute,
        # otherwise points can go on too long.
        self.settings.velocity[1] *= chaos_index

    def _goal(self, paddle):
        """Respond to the ball getting past a paddle"""
        if self.left_paddle == paddle:
            self.stats.score[0] += 1
        elif self.right_paddle == paddle:
            self.stats.score[1] += 1

        self.sb.prep_score()
        self._update_screen()
        sleep(1)
        self._check_score()
        self.sprites.empty()

    def _fire_bullet(self, paddle):
        """Create a new bullet and add it to the bullets group"""
        if self.left_paddle == paddle:
            if len(self.left_paddle_bullets) < self.settings.bullets_allowed:
                new_bullet = Bullet(self, self.left_paddle)
                self.left_paddle_bullets.add(new_bullet)
                self.sound.fire()

        if self.right_paddle == paddle:
            if len(self.right_paddle_bullets) < self.settings.bullets_allowed:
                new_bullet = Bullet(self, self.right_paddle)
                self.right_paddle_bullets.add(new_bullet)
                self.sound.fire()

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        self.left_paddle_bullets.update()
        self.right_paddle_bullets.update()

        # Delete old bullets when they leave the screen
        # Loop through copy of list because not possible to change list
        # length during a loop
        for bullet in self.left_paddle_bullets.copy():
            if bullet.rect.left >= self.screen_rect.right:
                self.left_paddle_bullets.remove(bullet)

        for bullet in self.right_paddle_bullets.copy():
            if bullet.rect.right <= self.screen_rect.left:
                self.right_paddle_bullets.remove(bullet)

    def _check_score(self):
        if self.stats.score[0] >= self.settings.play_to or self.stats.score[
                1] >= self.settings.play_to:
            sleep(3)
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

        self._reset_game()

    def _reset_game(self):
        self._create_game_elements()

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        if self.stats.game_active:
            self.sb.show_score()
            self.left_paddle.draw()
            self.right_paddle.draw()
            self.ball.draw()
            for bullet in self.left_paddle_bullets.sprites():
                bullet.draw_bullet()
            for bullet in self.right_paddle_bullets.sprites():
                bullet.draw_bullet()
        # Draw play button if game is inactive
        elif not self.stats.game_active:
            self.play_button.draw_button()
        pygame.display.flip()
Пример #27
0
def run_game():

    # Initialize pygame, settings, and screen object.
    pygame.init()
    topbot_settings = Settings(True)
    side_settings = Settings(False)
    paddlegap = 10

    screen = pygame.display.set_mode(
        (side_settings.screen_width, side_settings.screen_height))
    pygame.display.set_caption("Pong AI without walls")

    # Make the ball
    ball = Ball(side_settings, screen)
    balls = pygame.sprite.Group()
    balls.add()

    # Make play button
    play_button = Button(side_settings.screen_width / 2,
                         side_settings.screen_height / 2, side_settings,
                         screen, "Play")

    # Make menu
    menu = Menu(side_settings, screen, play_button)

    # Make player paddles
    playerPaddle = Paddle(paddlegap, ((side_settings.screen_height / 2) -
                                      (side_settings.paddle_length / 2)),
                          side_settings, screen)
    playertoppaddle = Paddle(((side_settings.screen_width / 4) -
                              (topbot_settings.paddle_width / 2)), 10,
                             topbot_settings, screen)
    playerbotpaddle = Paddle(((side_settings.screen_width / 4) -
                              (topbot_settings.paddle_width / 2)),
                             (side_settings.screen_height - paddlegap -
                              topbot_settings.paddle_length), topbot_settings,
                             screen)

    # Make ai/player 2 paddles
    aiPaddle = Paddle(
        (side_settings.screen_width - side_settings.paddle_width - paddlegap),
        ((side_settings.screen_height / 2) -
         (side_settings.paddle_length / 2)), side_settings, screen)
    aitop = Paddle(
        ((side_settings.screen_width - (side_settings.screen_width / 4)) -
         (topbot_settings.paddle_width / 2)), paddlegap, topbot_settings,
        screen)
    aibot = Paddle(
        ((side_settings.screen_width - (side_settings.screen_width / 4)) -
         (topbot_settings.paddle_width / 2)),
        (side_settings.screen_height - paddlegap -
         topbot_settings.paddle_length), topbot_settings, screen)

    # TESTING MENU SCREEN HERE
    menu.makeScreen(side_settings, screen, play_button)

    # Start the main loop for the game.
    while True:
        gf.check_events(side_settings, screen, playerPaddle, playertoppaddle,
                        playerbotpaddle)
        gf.update_screen(side_settings, screen, playerPaddle, playertoppaddle,
                         playerbotpaddle)

        # Watch for keyboard and mouse events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        # Redraw the screen during each pass through the loop.
        screen.fill(side_settings.bg_color)

        # Draw the ball in the middle
        ball.draw(screen)

        # Draws player side paddles
        playerPaddle.draw()
        playertoppaddle.draw()
        playerbotpaddle.draw()

        # Draws ai side paddles
        aiPaddle.draw()
        aitop.draw()
        aibot.draw()

        # Draws the middle line
        pygame.draw.line(
            screen, (250, 250, 250), (side_settings.screen_width / 2, 0),
            (side_settings.screen_width / 2, side_settings.screen_height))

        # Make the most recently drawn screen visible.
        pygame.display.flip()
Пример #28
0
def play_level(level, width, height, sounds, fps, score):
    screen_rect = pygame.Rect(0, 0, width, height)
    balls = []
    balls.append(Ball([0, 0], pi/2, 10, 15))
    bricks = load_level(level, width, height)
    paddle = Paddle(pygame.Rect(100, height-50, 150, 15), width,
                    (255, 255, 255))
    clock = pygame.time.Clock()
    font = pygame.font.Font(None, 48)
    spare_balls = 3

    sticky_paddle = True
    while True:
        # Handle events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        # Limit the loop speed to `fps` frames per second
        clock.tick(fps)
        actual_fps = clock.get_fps()
        dt = (1000.0 / actual_fps) if actual_fps > 0 else 0

        # Destroy any balls that reach the bottom
        balls = [ball for ball in balls
                 if ball.position[1] < height - ball.radius]

        if len(balls) == 0:
                # If we have spare balls, use one and create a new ball
                if spare_balls > 0:
                    spare_balls -= 1
                    sticky_paddle = True
                    balls.append(Ball([0, 0], pi/2, 10, 15))
                else:
                    # Otherwise, we lose :(
                    print("You lose!  Score: {}".format(score))
                    sys.exit(0)

        # If there are no bricks left (except immortal bricks), you cleared
        # this level
        if len([brick for brick in bricks if brick.life > 0]) == 0:
            print("Level {} cleared.".format(level))
            return score

        # Move the paddle
        paddle.move(pygame.mouse.get_pos())

        if sticky_paddle:
            balls[0].position[0] = paddle.x
            balls[0].position[1] = (paddle.y - int(paddle.height/2) -
                                    balls[0].radius - 1)
            balls[0].speed = 0
            balls[0].bearing = -pi/2
            if pygame.mouse.get_pressed()[0]:
                balls[0].speed = 10
                sticky_paddle = False

        # Handle all the ball movement and collision
        for ball in balls:
            ball.collide_rect_internal(screen_rect)
            for brick in bricks:
                if ball.collide_rect_external(brick.rect, invert=brick.invert):
                    brick.hit()
                    sounds['brick'].play()
                    if brick.life != -1:
                        score += 1
            if paddle.collide(ball):
                sounds['paddle'].play()
            ball.move(dt)

        # Handle multiballs:
        for brick in bricks:
            if brick.multiball and brick.life == 0:
                # Multiball release!
                x = brick.rect.left + int(brick.rect.width / 2)
                y = brick.rect.top + int(brick.rect.height / 2)
                balls.append(Ball([x, y], 1.0, 10, 15))

        # Remove dead bricks
        bricks = [brick for brick in bricks if brick.alive()]

        # Blank the screen, draw all the bricks, draw the balls
        screen.fill((0, 0, 50))
        for brick in bricks:
            brick.draw(screen)
        for ball in balls:
            ball.draw(screen)
        paddle.draw(screen)
        score_surf = font.render(str(score), 1, (255, 255, 255))
        screen.blit(score_surf, (20, 20))
        for idx in range(spare_balls):
            balls[0].draw(screen, (width - 50 - 40*idx, 20))

        pygame.display.flip()