Pygame逻辑问题

时间:2016-11-27 21:54:50

标签: python pygame

我正在尝试使用pygame开发一个Brick Breaker / Breakout游戏,但是当我用箭头移动时,我正面临一个烦人的问题,它会在桨(玩家)上留下“球”,我正在接受代码供你查看。

Process serverSideProcess = new Process();
serverSideProcess.StartInfo.FileName = @"C:\pathToTheExe";
serverSideProcess.StartInfo.Arguments = "arg1 arg2 ..."; 
serverSideProcess.EnableRaisingEvents = true;
serverSideProcess.StartInfo.UseShellExecute = true;
serverSideProcess.Start();

1 个答案:

答案 0 :(得分:2)

我不确定我是否理解你的问题,但代码的问题在于你每次更新播放器时都会创建一个球。只需删除播放器更新方法中的最后四行,并取消注释球的更新方法中的一行,一切正常。

其他提示

退出屏幕时删除球。这样可以防止游戏运行缓慢或崩溃。可以通过在球更新方法中添加if self.rect.bottom < 0: self.kill()来实现。

在适当的时候使用elif

在播放器更新方法中,您定义了一个仅在该方法中使用的属性self.speedx,因此最好只使用局部变量。此外,不鼓励在__init__方法之外定义属性。

这是您的代码稍作修改。

import pygame
pygame.init()

is_running = True  # Use lowercase_and_underscore for variable names.

WIDTH = 800
HEIGHT = 600
FPS = 60

clock = pygame.time.Clock()
window = pygame.display.set_mode((WIDTH, HEIGHT))


class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((60, 30))
        self.image.fill((200, 255, 200))
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 30

    def update(self):
        speedx = 0  # Don't define attributes outside __init__. Local variable works in this case instead.

        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_a]:
            speedx = -5
        elif keystate[pygame.K_d]:  # Use elif so it doesn't need to check this condition if the above is true.
            speedx = 5

        self.rect.x += speedx

        if self.rect.right + speedx > WIDTH:
            self.rect.right = WIDTH
        elif self.rect.left + speedx < 0:  # Use elif so it doesn't need to check this condition if the above is true.
            self.rect.left = 0

    def shoot(self):
        ball = Ball(self.rect.centerx, self.rect.top)
        all_sprites.add(ball)
        balls.add(ball)


class Ball(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 10))
        self.image.fill((100, 150, 200))
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = -3

    def update(self):
        if self.rect.bottom < 0:  # Chack if the ball has exit above the screen.
            self.kill()  # If it has it should delete itself.
        self.rect.y += self.speedy

all_sprites = pygame.sprite.Group()
balls = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

while is_running:

    clock.tick(FPS)
    print(all_sprites)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player.shoot()

    window.fill((0, 0, 30))
    all_sprites.update()
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
quit()

编辑:保持球在球上并空间发射

首先,你可以在Player类中创建一个属性self.current_ball,它将引用球拍上的球。然后在Player类的更新方法中更新球相对于球拍的位置。

要将球保持在球拍上,您必须将球的self.speedy更改为从0开始,否则它将在创建后直接移动。当您调用player.shoot()方法时,您将设置self.speedy = -3,这将启动球移动。

启动后,您只需在球拍上创建一个新球并重复相同的过程。

import pygame
pygame.init()

is_running = True  # Use lowercase_and_underscore for variable names.

WIDTH = 800
HEIGHT = 600
FPS = 60

clock = pygame.time.Clock()
window = pygame.display.set_mode((WIDTH, HEIGHT))


class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((60, 30))
        self.image.fill((200, 255, 200))
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 30
        self.current_ball = Ball(self.rect.centerx, self.rect.top)
        all_sprites.add(self.current_ball)
        balls.add(self.current_ball)

    def update(self):
        speedx = 0  # Don't define attributes outside __init__. Local variable works in this case instead.

        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_a]:
            speedx = -5
        elif keystate[pygame.K_d]:  # Use elif so it doesn't need to check this condition if the above is true.
            speedx = 5

        self.rect.x += speedx

        if self.rect.right + speedx > WIDTH:
            self.rect.right = WIDTH
        elif self.rect.left + speedx < 0:  # Use elif so it doesn't need to check this condition if the above is true.
            self.rect.left = 0

        self.current_ball.rect.midbottom = self.rect.midtop  # Set the ball position relative to paddle position.

    def shoot(self):
        self.current_ball.speedy = -3  # The ball should start moving.
        self.current_ball = Ball(self.rect.centerx, self.rect.top)  # Create a new ball on the paddle.
        all_sprites.add(self.current_ball)
        balls.add(self.current_ball)


class Ball(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 10))
        self.image.fill((100, 150, 200))
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = 0  # The ball don't move from the beginning.

    def update(self):
        if self.rect.bottom < 0:  # Chack if the ball has exit above the screen.
            self.kill()  # If it has it should delete itself.
        self.rect.y += self.speedy

all_sprites = pygame.sprite.Group()
balls = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

while is_running:

    clock.tick(FPS)
    print(all_sprites)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player.shoot()

    window.fill((0, 0, 30))
    all_sprites.update()
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
quit()