0

我有一个球对象,它在移动之前在屏幕中间等待一秒钟。这是update方法:

def update(self, dt):
    now = pygame.time.get_ticks() / 1000
    if now - self._spawn_time >= BALL_WAIT_TIME: 
        self.rect = self.calcnewpos(dt)
        self.handle_collision()
    else:
        step = 255 / FPS
        value = int(self._frame * step)
        rgb = (value, value, value)
        self._draw_ball(rgb)
        self._frame += 1

那一秒发生在else子句之下。我的目标是在那段时间内让球的图像从黑色 (8, 8, 8)变为白色 (255, 255, 255),但实际上它_draw_ball什么也没做。

def _draw_ball(self, rgb):
    pygame.draw.circle(self.image, rgb, self.rect.center, BALL_RADIUS)

有趣的是,它在第​​一次被调用时就起作用了__init__。我尝试从更新中取出行并在另一个模块中自行测试此代码,但无法弄清楚问题所在。为什么pygame.draw.circle不使用更新方法传递的颜色绘制圆圈?

这是整个班级:

#!python3
class Ball(pygame.sprite.Sprite):

    def __init__(self, game, velocity):
        super(Ball, self).__init__()

        self.image = pygame.Surface((BALL_RADIUS*2, BALL_RADIUS*2))
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK, RLEACCEL)
        self.rect = self.image.get_rect()

        screen = pygame.display.get_surface()
        self.area = screen.get_rect().inflate(-GAP*2, 0)

        self.velocity = velocity
        self.game = game
        self.start_to_the = random.choice(['left', 'right'])
        self._draw_ball(BALL_COLOR)
        self.reinit()

    def _draw_ball(self, rgb):
        pygame.draw.circle(self.image, rgb, self.rect.center, BALL_RADIUS)

    def _hit_topbottom(self):
        return self.rect.top < self.area.top or self.rect.bottom > self.area.bottom

    def _hit_leftright(self):
        if self.rect.left < self.area.left: return 'left'
        elif self.rect.right > self.area.right: return 'right'
        else: return 0

    def reinit(self):
        self._spawn_time = pygame.time.get_ticks() / 1000
        self._frame = 1

        if self.start_to_the == 'left':
            self.velocity = Vec2D(-BALL_SPEED, 0)
        else:
            self.velocity = Vec2D(BALL_SPEED, 0)

        self.rect.center = self.area.center

    def update(self, dt):
        now = pygame.time.get_ticks() / 1000
        if now - self._spawn_time >= BALL_WAIT_TIME: 
            self.rect = self.calcnewpos(dt)
            self.handle_collision()
        else:
            step = 255 / FPS
            value = int(self._frame * step)
            rgb = (value, value, value)
            self.image.fill(rgb)
            self._frame += 1

    def calcnewpos(self, dt):
        (dx, dy) = self.velocity.x, self.velocity.y
        return self.rect.move(dx, dy)

    def handle_collision(self):
        (dx, dy) = self.velocity.x, self.velocity.y
        if self._hit_topbottom():
            dy = -dy

        elif self._hit_leftright():
            side = self._hit_leftright()

            self.game.enemy.update_hitpos()
            self.game.increase_score(side)

            if side == 'left': self.start_to_the = 'right'
            elif side == 'right': self.start_to_the = 'left'
            self.reinit()
            return

        else:
            if self.hit_paddle():
                paddle = self.hit_paddle()
                paddle.handle_collision()

                if paddle == self.game.paddles['left']:
                    self.rect.left = GAP + PADDLE_WIDTH
                elif paddle == self.game.paddles['right']: 
                    self.rect.right = SCREEN_WIDTH - (GAP + PADDLE_WIDTH)
                dx = -dx

                dy = (self.rect.centery - paddle.rect.centery)
                dy = (math.copysign(min(abs(dy) // 16 * 16, 32), dy)) / 4

                paddle.handle_collision()
        self.velocity = Vec2D(dx, dy)

    def hit_paddle(self):
        paddles = self.game.paddles.values()
        for paddle in paddles:
            if self.rect.colliderect(paddle.rect): return paddle
4

2 回答 2

0

我没有看到任何对pygame.display.flip. 这是负责使用显示表面的当前状态更新屏幕的功能。它看起来也不像是在显示表面上重新绘制你的球。某处,可能在update_draw_ball应该有如下调用:

self.screen.draw(self.image, self.rect)
pygame.display.flip()

第一行将球的图像绘制到代表屏幕的表面上,第二个调用更新屏幕以反映新的表面。

我的第二个理论是,您正在绘制超出self.image. 这个理论来自于看到根据速度移动球的矩形,但总是self.imageself.rect的中心画一个圆圈。的大小self.image仅为BALL_RADIUS*2,如果self.rect' 的左上角变为非 ' ,则可以很容易地在其外部绘制(0,0)。即使这不是你现在的问题,以后也会有。

于 2013-09-30T05:59:53.440 回答
0

在 pygame 中,draw circle 语句是: pygame.draw.circle (SURFACE, COLOUR, (X, Y), SIZE, 0) 如果你把你的 screen.fill 语句放在 circle 语句之后,那么它将绘制圆并立即覆盖它加上屏幕的颜色,使您的圆圈在绘制后的 10000 秒后消失。

于 2016-08-06T17:18:45.363 回答