python - python pygame 中的分数没有变化

标签 python pygame

我正在尝试制作乒乓球游戏,但当球离开屏幕时得分不会改变。另一件不太正确的事情是,有时,球会在桨上滑动,然后离开屏幕,而不是从桨上弹开。我可以就这些问题获得一些帮助吗? (主要是第一个)这是我的代码:

import pygame as pg
import random
from os import path

img_dir = path.join(path.dirname(__file__), 'img')
snd_dir = path.join(path.dirname(__file__), 'snd')
WIDTH = 1280
HEIGHT = 690
FPS = 60
# define colors 
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (0, 255, 255)
OPPONENT_SPEED = 2.4
# initialize PyGame and create window 
pg.init()
pg.mixer.init()
screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption('PONG!')
clock = pg.time.Clock()
pong_ball_x = [-3, 3]
pong_ball_y = [-3, 3]
font_name = pg.font.match_font('arial')


def draw_text(surf, text, size, x, y):
    font = pg.font.Font(font_name, size)
    text_surface = font.render(text, True, WHITE)
    text_rect = text_surface.get_rect()
    text_rect.midtop = (x, y)
    surf.blit(text_surface, text_rect)


class Player(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((5, 100))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.x = 10
        self.rect.y = HEIGHT / 2
        self.speedy = 0

    def update(self):
        self.speedy = 0
        keys = pg.key.get_pressed()
        if keys[pg.K_s]:
            self.speedy = 5
        if keys[pg.K_w]:
            self.speedy = -5
        self.rect.y += self.speedy
        if self.rect.bottom >= HEIGHT:
            self.rect.bottom = HEIGHT
        if self.rect.top <= 0:
            self.rect.top = 0


class Player2(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((5, 100))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH - 15
        self.rect.y = HEIGHT / 2
        self.speedy = 0

    def update(self):
        self.speedy = 0
        keys = pg.key.get_pressed()
        if keys[pg.K_DOWN]:
            self.speedy = 5
        if keys[pg.K_UP]:
            self.speedy = -5
        self.rect.y += self.speedy
        if self.rect.bottom >= HEIGHT:
            self.rect.bottom = HEIGHT
        if self.rect.top <= 0:
            self.rect.top = 0


class Opponent(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((5, 100))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH - 10
        self.rect.y = HEIGHT / 2
        self.speedy = 0

    def update(self):
        if self.rect.bottom >= HEIGHT:
            self.rect.bottom = HEIGHT
        if self.rect.top <= 0:
            self.rect.top = 0

    def opponent_ai(self):
        if self.rect.top < pong_ball.rect.y:
            self.rect.top += OPPONENT_SPEED
        if self.rect.bottom > pong_ball.rect.y:
            self.rect.bottom -= OPPONENT_SPEED


class PongBall(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((30, 30))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH / 2 - 12.5
        self.rect.y = HEIGHT / 2 - 12.5
        self.speedx = random.choice(pong_ball_x)
        self.speedy = random.choice(pong_ball_y)

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.top <= 0:
            self.speedy = -self.speedy
        if self.rect.bottom >= HEIGHT:
            self.speedy = -self.speedy
        if self.rect.right <= 0:
            self.rect.x = WIDTH / 2 - 15
            self.rect.y = HEIGHT / 2 - 15
        if self.rect.left >= WIDTH:
            self.rect.x = WIDTH / 2 - 15
            self.rect.y = HEIGHT / 2 - 15

    def bounce(self):
        self.speedx = -self.speedx
    # load all game graphics 


# ball_img = pg.image.load(path.join(img_dir, "white_circle2.png")).convert() 
all_sprites = pg.sprite.Group()
pong_ball_group = pg.sprite.Group()
player = Player()
player2 = Player2()
opponent = Opponent()
pong_ball = PongBall()
all_sprites.add(player)
all_sprites.add(player2)
pong_ball_group.add(pong_ball)
score = 0
score2 = 0
# Game loop 
running = True
while running:
    # process input (events) 
    for event in pg.event.get():
        # check for closing window 
        if event.type == pg.QUIT:
            running = False
    if pong_ball.rect.left == WIDTH - 12.5:
        score = score + 1
    if pong_ball.rect.right == 12.5:
        score2 = score2 + 1
        # update 
    all_sprites.update()
    pong_ball_group.update()
    # check to see if pong ball hit one of the pads 
    hits = pg.sprite.spritecollide(pong_ball, all_sprites, False, False)
    for hit in hits:
        pong_ball.bounce()
        # draw and render 
    screen.fill(BLACK)
    all_sprites.draw(screen)
pong_ball_group.draw(screen)
draw_text(screen, str(score), 50, WIDTH / 2 - 30, 10)
draw_text(screen, str(score2), 50, WIDTH / 2 + 30, 10)
draw_text(screen, "-", 50, WIDTH / 2, 10)
# *after* drawing everything, flip the display 
pg.display.flip()
pg.quit()

最佳答案

问题在于如何检查球是否已离开屏幕。您当前的检查条件永远不会触发为 pong_ball.rect.left永远不会等于 WIDTH - 12.5因为它是一个整数。

一个简单的调试方法就是打印您正在检查的值,因此添加

print(pong_ball.rect.left, WIDTH - 12.5)

将输出:

1264 1267.5
1267 1267.5
1270 1267.5
1273 1267.5
1276 1267.5
1279 1267.5
625 1267.5
628 1267.5

当球移向屏幕右侧时,其位置就会重置。

因此,您会看到球的位置超出了您的极限,而没有触发您的条件。

如果将比较更改为 ><分别,分数将更新。

但是这会导致另一个问题,从上面的调试打印中也可能很明显。有四个帧的评分条件为 true,因为重置位置检查在 PongBall.update() 中。没有12.5像素的余地。这就是存在余地的原因吗? future 的你可能会欣赏您的评论。

但是,如果您更改比较以删除 12.5 像素缓冲区,则分数不会更新。这是因为pong_ball位置已更新并在其 update() 中重置。方法。

如果我们遵循您的退回方法,我们可以添加单独的 reset方法PongBall当我们满足评分标准时称之为。

所以你的PongBall现在上课:

class PongBall(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((30, 30))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.speedx = random.choice(pong_ball_x)
        self.speedy = random.choice(pong_ball_y)
        self.reset()

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.top <= 0:
            self.speedy = -self.speedy
        if self.rect.bottom >= HEIGHT:
            self.speedy = -self.speedy

    def reset(self):
        self.rect.x = WIDTH / 2 - 15
        self.rect.y = HEIGHT / 2 - 15

    def bounce(self):
        self.speedx = -self.speedx

您的主循环发生更改以执行重置:

while running:
    # process input (events)
    for event in pg.event.get():
        # check for closing window
        if event.type == pg.QUIT:
            running = False
    # check for score
    if pong_ball.rect.left > WIDTH - 12.5:
        score = score + 1
        pong_ball.reset()
    if pong_ball.rect.right < 12.5:
        score2 = score2 + 1
        pong_ball.reset()
    # update
    ....

那么您的分数应该表现正确。

关于python - python pygame 中的分数没有变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60767506/

相关文章:

python - 列表理解和循环之间的区别

python - django:如何在 ManyToManyField(通过)相关模型中的字段上对查询集进行排序

python - PyGame 安装 Mac OS X

python - 如何访问特定键具有特定值的字典中的所有字典

python - 寻找多个重叠矩形的并集 - OpenCV python

python - 如何配置 sublimerope 自动完成 python 代码?

python - 使用 cx_Freeze 构建 msi : ValueError: FCI error 1

python - pygame中的 Sprite 掩码碰撞问题

python - 错误 pygame : Argument must be a sequence of rectstyle objects

pygame - Travis CI、pip 和 pygame