【问题标题】:Pygame ball movement flickeringPygame球运动闪烁
【发布时间】:2021-12-29 15:16:37
【问题描述】:

我一直在尝试制作一个基本的 Pygame 代码,让球在屏幕上弹跳并离开你的球拍。桨的运动是平稳的,但球会闪烁并且非常波涛汹涌。这是我的完整代码:

import pygame, sys
from pygame.locals import *
import random, time

pygame.init()

window = (800, 600)

background = (0, 0, 0)
back = pygame.Surface(window)
entity_color = (255, 255, 255)
x = 362.5
y = 550
ball_x = 387.5
ball_y = 50
width = 75
height = 25
clockobject = pygame.time.Clock()


screen = pygame.display.set_mode((window))

pygame.display.set_caption("Test Game")

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super(Ball, self).__init__()
        self.surf = pygame.Surface((25, 25))
        self.surf.fill((255, 255, 255))
        self.rect = self.surf.get_rect()
        self.dir_x = 1
        self.dir_y = 1
        self.speed = 2

    def update(self):
        global ball_x
        global ball_y
        if ball_x > 775:
            ball_x = 775
            ball.dir_x = -1
        elif ball_x < 0:
            ball_x = 0
            ball.dir_x = 1
        if ball_y < 0:
            ball_y = 0
            ball.dir_y = 1
        elif ball_y > 600:
            ball_y = 50
            ball_x = 387.5
        if ball_x <= x + 75 and ball_x >= x and ball_y <= y and ball_y >= y - 25:
            ball.dir_y = -1
        ball_x = ball_x + ball.speed * ball.dir_x
        ball_y = ball_y + ball.speed * ball.dir_y


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super(Player, self).__init__()
        self.image_s = pygame.image.load("paddle.png")
        self.image_b = self.image_s.get_rect()
        self.surf = pygame.Surface((75, 25))

        self.surf.fill((255, 255, 255))
        self.rect = self.surf.get_rect()

    def update(self):
        global x
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            x = x - 5
        elif keys[pygame.K_RIGHT]:
            x = x + 5

    def checkboundaries(self):
        global x
        if x > 725:
            x = 725
        if x < 0:
            x = 0

ball = Ball()
player = Player()
waiting = True
while waiting:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
            elif event.key == pygame.K_SPACE:
                running = True
                waiting = False
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
    player.update()
    ball.update()
    player.checkboundaries()
    screen.blit(back, (0,0))
    screen.blit(player.surf, (x, y))
    screen.blit(ball.surf, (ball_x, ball_y))
    pygame.display.flip()
    clockobject.tick(360)

pygame.quit()
sys.exit()

这是因为我的代码有问题,运行缓慢,还是我遗漏了什么?

【问题讨论】:

  • ball.speed? self.speed 怎么了?还可以在pygame.sprite.Sprite 中使用draw 函数,在这种情况下是ball.draw,并使用正确的表面名称self.image 而不是self.surf,移动使用self.rect.center 移动,这样你可以在Sprite Class中使用draw
  • @CunningBard 你是说用 .draw 代替 .blit 吗?
  • @EpicEfeathers 了解pygame.sprite.Group.draw。但是,您只能在对象的属性名称为 imagerect 时使用它。此外ball_xball_y 应该是属性而不是全局变量。在方法中你应该使用self 而不是ball
  • @EpicEfeathers 无论如何,“闪烁”只是一种视觉错觉,因为您的帧速率如此之高。您对此无能为力。
  • @Rabbid76 但是如果我降低帧速率,球的移动速度会变慢,如果我更快地改变运动,它就会跳跃。那我有什么办法吗?

标签: python python-3.x pygame


【解决方案1】:

如果你使用pygame.sprite.Sprite,你也应该使用pygame.sprite.Group

pygame.sprite.Group.draw()pygame.sprite.Group.update()pygame.sprite.Group提供的方法。

后者委托给包含的pygame.sprite.Spritesupdate 方法——您必须实现该方法。见pygame.sprite.Group.update()

对组中的所有 Sprite 调用 update() 方法。 [...]

前者使用包含的pygame.sprite.Sprites 的imagerect 属性来绘制对象——您必须确保pygame.sprite.Sprites 具有所需的属性。见pygame.sprite.Group.draw()

将包含的 Sprite 绘制到 Surface 参数。这将Sprite.image 属性用于源表面,并使用Sprite.rect。 [...]

例如:

import pygame, sys
from pygame.locals import *

pygame.init()
clockobject = pygame.time.Clock()
screen = pygame.display.set_mode((800, 600))
back = pygame.Surface(screen.get_size())
pygame.display.set_caption("Test Game")

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super(Ball, self).__init__()
        self.image = pygame.Surface((25, 25))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect(topleft = (387, 50))
        self.dir_x = 1
        self.dir_y = 1
        self.speed = 2

    def update(self):
        if self.rect.x > 775:
            self.rect.x = 775
            self.dir_x = -1
        elif self.rect.x < 0:
            self.rect.x = 0
            self.dir_x = 1
        if self.rect.y < 0:
            self.rect.y = 0
            self.dir_y = 1
        elif self.rect.y > 600:
            self.rect.topleft = (387, 50)
        if self.rect.colliderect(player.rect):
            ball.dir_y = -1
        self.rect.x += ball.speed * ball.dir_x
        self.rect.y += ball.speed * ball.dir_y

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super(Player, self).__init__()
        self.image = pygame.Surface((75, 25))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect(topleft = (363, 550))

    def update(self):
        keys = pygame.key.get_pressed()
        self.rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 5
        self.rect.clamp_ip(screen.get_rect())

ball = Ball()
player = Player()
all_sprites = pygame.sprite.Group([ball, player])

started = False
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
            elif event.key == pygame.K_SPACE:
                started = True
    
    
    screen.blit(back, (0,0))
    if started:
        all_sprites.update()
        all_sprites.draw(screen)
    pygame.display.flip()
    clockobject.tick(100)

pygame.quit()
sys.exit()

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    相关资源
    最近更新 更多