小能豆

用 Python 玩乒乓球游戏。得分和屏幕外检查

py

上周我们进行了一场乒乓球游戏

代码如下:

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)

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


阅读 6

收藏
2025-01-13

共1个答案

小能豆

可以在 中对人体桨进行“屏幕外检查” control_human。如果桨向上移动,则最终桨顶部位置是max0 和 中的最大值 ( ) paddle.rect.top-5。如果桨向下移动,则最终桨底部位置是和 中min的最小值 ( ) :SCREEN_HEIGHT``paddle.rect.bottom+5

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并增加分数。将分数转换为字符串,渲染字符串并将其 blit 到显示器上: left_paddle``ballstr

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) )

    # [...]

完整示例:

HAyCa.gif

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)
2025-01-13