在pygame中是否有Repeat-Until?

时间:2013-06-26 14:18:48

标签: python pygame

我想让我的角色在pygame中拍摄。我无法让子弹从他的位置移开,如果它碰到屏幕的边缘就停止。我想要的是它继续移动,直到它与屏幕边缘碰撞。每当我运行以下代码时,它都会崩溃:

class BULLET(pygame.sprite.Sprite):
def __init__(self, speed, location):
    self.pos = [0,0]
    pygame.sprite.Sprite.__init__(self)
    self.image = SHOWBULLET
    self.rect = self.image.get_rect()
    self.rect.left, self.rect.top = location
    self.rect.center = location
    self.speed = speed
def move(self):
    if AMMO > 0:
        if event.type == pygame.MOUSEBUTTONDOWN and Gun.image == NOGUN:
            held_down = True
            if held_down == True:
                self.rect.centerx = Player.rect.centerx
                self.rect.centery = Player.rect.centery
                if Player.direction == 0:
                    self.direction = 0
                    while self.rect.top >= screen.get_rect().top:
                        self.rect.top = self.rect.top + 20
                        if self.rect.top <=   screen.get_rect().top:
                            break

2 个答案:

答案 0 :(得分:1)

我想你想以这种方式构建你的游戏。这是一个缩写版本,包含我认为相关的内容,并且存在一些问题,但实质上是

  • 你的子弹在被解雇后根本不应该关心玩家。
  • 子弹应该从玩家在HoldMouseButton事件时站立的位置开始。在那之后,它应该继续在它的路径上不间断。
  • 我认为如果长时间按住鼠标,你会希望玩家射出许多子弹。我不认为你当前的代码那样做。实际上,除了帮助它在屏幕上移动的TickEvents之外,子弹应该关心任何事件。另一方面,玩家应该关心按下鼠标按钮,只要按下鼠标按钮就应该发射子弹。
  • 此外,了解一下MVC架构可能会有所帮助。看看这个basic tutorial

希望这有帮助。

class Bullet:
    def __init__(self, velocity, start_position):
        self.pos = start_position
        self.velocity = velocity
        self.visible = True

    def notify(self, event):
        if isinstance(event, TickEvent):
            self.move(event.time_passed)

    def move(self, time):
        self.pos += velocity * time

class Charactor:
    def __init__(self, position, event_manager, sprite_manager, etc.):
        self.state = 'MOVING'
        self.pos = position
        self.direction = direction

    def notify(self, event):
        if isinstance(event, HoldMouseButtonEvent()):
            self.state = 'SHOOTING'
        elif isinstance(event, ReleaseMouseButtonEvent()):
            self.state = 'MOVING'
        elif isinstance(event, TickEvent()):
            if self.state == 'SHOOTING':
                self.shoot()
            elif self.state == 'MOVING':
                self.move()

    def shoot(self):
        sprite_manager.add(Bullet(BULLET_VELOCITY * self.direction, self.pos))

答案 1 :(得分:0)

你的移动功能应该忽略与播放器有关的一切。从头开始吧。它应该每次滴答时更新它的位置(可能通过每个滴答调用move())并且它应该沿着自己的方向并检查它自己与墙/边缘的碰撞

修正了你的init方法

def __init__(self, speed, location, direction):
    self.pos = location
    pygame.sprite.Sprite.__init__(self)
    self.image = SHOWBULLET
    self.rect = self.image.get_rect()
    self.rect.left, self.rect.top = location
    self.rect.center = location
    self.speed = speed
    self.direction = direction

您的移动方法可能需要从头开始重做

移动方法应该有两个部分:

1)将子弹沿你想要的方向移动一个增量

if (direction == 0) {
    self.pos = newPosition; // replace new position with a calculation for up
} else if (direction == 1) {
    self.pos = newPosition; // this new position should be one increment right
} etc...

2)检查子弹是否离开屏幕

if (self.pos[0] > width || self.pos[0] < 0 || self.pos[1] > height || self.pos[1] < 0) {
    //return false;
}

return true;