【问题标题】:Pong game in python. Score and out-of-screen checkpython中的乒乓球游戏。分数和屏幕外检查
【发布时间】:2020-06-06 02:32:00
【问题描述】:

上周我们进行了乒乓球比赛

代码如下:

import pygame

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

class Ball:
    # свойства
    def __init__(self):
        self.rect = pygame.Rect(0, 0, 20, 20)
        self.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
        self.dx = 5     # скорость по иксу
        self.dy = 5     # скорость по игреку
        self.game_over = False

    # методы
    def draw(self, screen):
        pygame.draw.circle(screen, WHITE, self.rect.center, 10)     # 10 - радиус мяча

    def move(self):
        x, y = self.rect.center
        x += self.dx
        y += self.dy
        self.rect.center = (x, y)
        if y > SCREEN_HEIGHT or y < 0:
            self.dy *= -1
        if x > SCREEN_WIDTH or x < 0:
            #self.dx *= -1
            print('Game Over')
            self.game_over = True          

class Paddle:   # ракетка
    def __init__(self, x, y):
        self.rect = pygame.Rect(x, y, 10, 100)

    def draw(self, screen):
        pygame.draw.rect(screen, WHITE, self.rect)

# ----------------  проверка на столкновение -------------------------- #

def check_collision(ball, paddle):
    if ball.rect.colliderect(paddle.rect):
        ball.dx *= -1

# -------------------- управление ракетками --------------------------- #

def control_human(paddle):
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_UP]:
        paddle.rect.y -= 5
    if keys_pressed[pygame.K_DOWN]:
        paddle.rect.y += 5

def control_computer(paddle, ball):
    # если мяч летит от компьютера, то ничего не делать
    if ball.dx < 0:
        return
    # если мяч выше ракетки, то двигаем ракетку вверх
    if ball.rect.y < paddle.rect.y:
        paddle.rect.y -= 5
        if paddle.rect.y < 0:
            paddle.rect.y = 0
    # если мяч ниже ракетки, то двигаем ракетку вниз
    if ball.rect.y > paddle.rect.y:
        paddle.rect.y += 5
        #if paddle.rect.y + 100 > SCREEN_HEIGHT:
        #    paddle.rect.y = SCREEN_HEIGHT - 100
        if paddle.rect.bottom > SCREEN_HEIGHT:
            paddle.rect.bottom = SCREEN_HEIGHT    

# --------------------------------------------------------------------- #
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

# ----------------  создаем объекты для игры -------------------------- #

ball = Ball()
left_paddle = Paddle(30, SCREEN_HEIGHT // 2 - 50)
right_paddle = Paddle(SCREEN_WIDTH - 40, SCREEN_HEIGHT // 2 - 50)
clock = pygame.time.Clock()
font = pygame.font.SysFont("Lucida Console", 30)
label = font.render("G A M E   O V E R", 1, (255, 0, 0, 255))

# --------------------  главный цикл игры ----------------------------- #
while True:
    screen.fill(BLACK)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    if not ball.game_over:
        ball.move()
        ball.draw(screen)
        control_human(left_paddle)
        control_computer(right_paddle, ball)
        left_paddle.draw(screen)
        right_paddle.draw(screen)
        check_collision(ball, left_paddle)
        check_collision(ball, right_paddle)
    else:
        screen.blit(label, (50, 100) )
    pygame.display.update()
    clock.tick(60)

我们需要对人类球员的球拍进行屏幕外检查为每个球员添加成功踢球的计数,并在屏幕上显示当前得分

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    人体划桨的“屏幕外检查”可以在control_human 中完成。如果向上移动桨叶,则最终桨叶顶部位置是 0 和 paddle.rect.top-5 中的最大值 (max)。如果拨片向下移动,那么最终的拨片底部位置是SCREEN_HEIGHTpaddle.rect.bottom+5 中的最小值(min):

    def control_human(paddle):
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_UP]:
            paddle.rect.top = max(0, paddle.rect.top - 5)
        if keys_pressed[pygame.K_DOWN]:
            paddle.rect.bottom = min(SCREEN_HEIGHT, paddle.rect.bottom + 5)
    

    要计算分数,请将返回值添加到函数check_collision。如果球与桨碰撞,该函数必须返回True。否则函数返回False

    def check_collision(ball, paddle):
        if ball.rect.colliderect(paddle.rect):
            ball.dx *= -1
            return True
        return False
    

    添加一个score 并在left_paddleball 冲突时增加分数。通过str将分数转换为字符串,渲染字符串并blit到显示器:

    score = 0
    while True:
        # [...]
    
        if not ball.game_over:
            ball.move()
            ball.draw(screen)
            control_human(left_paddle)
            control_computer(right_paddle, ball)
            left_paddle.draw(screen)
            right_paddle.draw(screen)
    
            if check_collision(ball, left_paddle):
                score += 1
    
            check_collision(ball, right_paddle)
    
            score_label = font.render(str(score), 1, (255, 0, 0, 255))
            screen.blit(score_label, (10, 10))
    
        else:
            screen.blit(label, (50, 100) )
    
        # [...]
    

    完整示例:

    import pygame
    
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    
    class Ball:
        # свойства
        def __init__(self):
            self.rect = pygame.Rect(0, 0, 20, 20)
            self.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
            self.dx = 5     # скорость по иксу
            self.dy = 5     # скорость по игреку
            self.game_over = False
    
        # методы
        def draw(self, screen):
            pygame.draw.circle(screen, WHITE, self.rect.center, 10)     # 10 - радиус мяча
    
        def move(self):
            x, y = self.rect.center
            x += self.dx
            y += self.dy
            self.rect.center = (x, y)
            if y > SCREEN_HEIGHT or y < 0:
                self.dy *= -1
            if x > SCREEN_WIDTH or x < 0:
                #self.dx *= -1
                print('Game Over')
                self.game_over = True          
    
    class Paddle:   # ракетка
        def __init__(self, x, y):
            self.rect = pygame.Rect(x, y, 10, 100)
    
        def draw(self, screen):
            pygame.draw.rect(screen, WHITE, self.rect)
    
    # ----------------  проверка на столкновение -------------------------- #
    
    def check_collision(ball, paddle):
        if ball.rect.colliderect(paddle.rect):
            ball.dx *= -1
            return True
        return False
    
    # -------------------- управление ракетками --------------------------- #
    
    def control_human(paddle):
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_UP]:
            paddle.rect.top = max(0, paddle.rect.top - 5)
        if keys_pressed[pygame.K_DOWN]:
            paddle.rect.bottom = min(SCREEN_HEIGHT, paddle.rect.bottom + 5)
    
    def control_computer(paddle, ball):
        # если мяч летит от компьютера, то ничего не делать
        if ball.dx < 0:
            return
        # если мяч выше ракетки, то двигаем ракетку вверх
        if ball.rect.y < paddle.rect.y:
            paddle.rect.y -= 5
            if paddle.rect.y < 0:
                paddle.rect.y = 0
        # если мяч ниже ракетки, то двигаем ракетку вниз
        if ball.rect.y > paddle.rect.y:
            paddle.rect.y += 5
            #if paddle.rect.y + 100 > SCREEN_HEIGHT:
            #    paddle.rect.y = SCREEN_HEIGHT - 100
            if paddle.rect.bottom > SCREEN_HEIGHT:
                paddle.rect.bottom = SCREEN_HEIGHT    
    
    # --------------------------------------------------------------------- #
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    # ----------------  создаем объекты для игры -------------------------- #
    
    ball = Ball()
    left_paddle = Paddle(30, SCREEN_HEIGHT // 2 - 50)
    right_paddle = Paddle(SCREEN_WIDTH - 40, SCREEN_HEIGHT // 2 - 50)
    clock = pygame.time.Clock()
    font = pygame.font.SysFont("Lucida Console", 30)
    label = font.render("G A M E   O V E R", 1, (255, 0, 0, 255))
    
    # --------------------  главный цикл игры ----------------------------- #
    score = 0
    while True:
        screen.fill(BLACK)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
    
        if not ball.game_over:
            ball.move()
            ball.draw(screen)
            control_human(left_paddle)
            control_computer(right_paddle, ball)
            left_paddle.draw(screen)
            right_paddle.draw(screen)
            if check_collision(ball, left_paddle):
                score += 1
                print(score)
            check_collision(ball, right_paddle)
            score_label = font.render(str(score), 1, (255, 0, 0, 255))
            screen.blit(score_label, (10, 10))
        else:
            screen.blit(label, (50, 100) )
    
        pygame.display.update()
        clock.tick(60)
    

    【讨论】:

    • 非常感谢!
    【解决方案2】:

    这里是带有屏幕外检查人体桨和计数器的代码:

    import pygame
    
    SCREEN_WIDTH = 800
    SCREEN_HEIGHT = 600
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    
    class Ball:
        # свойства
        def __init__(self):
            self.rect = pygame.Rect(0, 0, 20, 20)
            self.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
            self.dx = 5     # скорость по иксу
            self.dy = 5     # скорость по игреку
            self.game_over = False
    
        # методы
        def draw(self, screen):
            pygame.draw.circle(screen, WHITE, self.rect.center, 10)     # 10 - радиус мяча
    
        def move(self):
            x, y = self.rect.center
            x += self.dx
            y += self.dy
            self.rect.center = (x, y)
            if y > SCREEN_HEIGHT or y < 0:
                self.dy *= -1
            if x > SCREEN_WIDTH or x < 0:
                #self.dx *= -1
                print('Game Over')
                self.game_over = True
    
    class Paddle:   # ракетка
        def __init__(self, x, y):
            self.rect = pygame.Rect(x, y, 10, 100)
    
        def draw(self, screen):
            pygame.draw.rect(screen, WHITE, self.rect)
    
        def on_ball_collision(self, ball):
            pass
    
    # ----------------  проверка на столкновение -------------------------- #
    
    def check_collision(ball, paddle):
        if ball.rect.colliderect(paddle.rect):
            paddle.on_ball_collision(ball)
            ball.dx *= -1
    
    # -------------------- управление ракетками --------------------------- #
    
    def control_human(paddle):
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_UP]:
            paddle.rect.y = max(0, paddle.rect.y - 5)
        if keys_pressed[pygame.K_DOWN]:
            paddle.rect.y = min(SCREEN_HEIGHT - paddle.rect.height, paddle.rect.y + 5)
    
    def control_computer(paddle, ball):
        # если мяч летит от компьютера, то ничего не делать
        if ball.dx < 0:
            return
        # если мяч выше ракетки, то двигаем ракетку вверх
        if ball.rect.y < paddle.rect.y:
            paddle.rect.y -= 5
            if paddle.rect.y < 0:
                paddle.rect.y = 0
        # если мяч ниже ракетки, то двигаем ракетку вниз
        if ball.rect.y > paddle.rect.y:
            paddle.rect.y += 5
            #if paddle.rect.y + 100 > SCREEN_HEIGHT:
            #    paddle.rect.y = SCREEN_HEIGHT - 100
            if paddle.rect.bottom > SCREEN_HEIGHT:
                paddle.rect.bottom = SCREEN_HEIGHT
    
    # --------------------------------------------------------------------- #
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    
    # ----------------  создаем объекты для игры -------------------------- #
    
    class HumanPaddle(Paddle):
        def __init__(self, x, y, font):
            super().__init__(x, y)
            self.font = font
            self.count = 0
            self.label = self.font.render("Count: {}".format(self.count), 1, (255, 0, 255, 255))
    
        def on_ball_collision(self, ball):
            self.count += 1
            self.label = self.font.render("Count: {}".format(self.count), 1, (255, 0, 255, 255))
    
        def draw_count(self, x, y):
            screen.blit(self.label, (x, y) )
    
    
    ball = Ball()
    font = pygame.font.SysFont("Lucida Console", 30)
    left_paddle = HumanPaddle(30, SCREEN_HEIGHT // 2 - 50, font)
    right_paddle = Paddle(SCREEN_WIDTH - 40, SCREEN_HEIGHT // 2 - 50)
    clock = pygame.time.Clock()
    label = font.render("G A M E   O V E R", 1, (255, 0, 0, 255))
    
    # --------------------  главный цикл игры ----------------------------- #
    while True:
        screen.fill(BLACK)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
    
        if not ball.game_over:
            ball.move()
            ball.draw(screen)
            control_human(left_paddle)
            control_computer(right_paddle, ball)
            left_paddle.draw(screen)
            right_paddle.draw(screen)
            check_collision(ball, left_paddle)
            check_collision(ball, right_paddle)
            left_paddle.draw_count(10, 10)
        else:
            screen.blit(label, (50, 100) )
        pygame.display.update()
        clock.tick(60)
    

    屏幕外检查由以下代码完成:

    def control_human(paddle):
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_UP]:
            paddle.rect.y = max(0, paddle.rect.y - 5)
        if keys_pressed[pygame.K_DOWN]:
            paddle.rect.y = min(SCREEN_HEIGHT - paddle.rect.height, paddle.rect.y + 5)
    

    计数器是通过使用def on_ball_collision(self, ball) 事件增强Paddle 来完成的,然后将左侧的Paddle 子类化为已实现此事件的HumanPaddle

    截图:

    【讨论】:

    • 哇!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多