Игрок не будет двигаться правильно из-за силы тяжести, толкающей его в землю - PullRequest
0 голосов
/ 04 мая 2020

Я делаю платформер карты тайла с помощью pygame. Я определил движение X и Y для игрока, а также силу Y, которая представляет силу гравитации, чтобы заставить его правильно прыгать. Однако, когда мой игрок падает на землю и начинается игра, он не движется правильно ни вправо, ни влево из-за силы тяжести, которая продолжает толкать его вниз . Кроме того, когда игрок прыгает, а я перемещаю его вправо, он как бы не распознает столкновение с нижним прямоугольником стены ( см. Рисунок ниже для визуального объяснения этого ) .

Я пытался отключить эту силу гравитации, когда игрок падает на землю, и включить ее, когда игрок прыгает, но она не сработала, как ожидалось, и у меня возникли проблемы с управлением столкновениями ( также Нет смысла отключать гравитацию, верно? )

Here's a gif of the issue i'm facing with

Вот мой класс Игрока:

class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.sprites
        pg.sprite.Sprite.__init__(self, self.groups)

        self.game = game

        self.image = pg.Surface((TILESIZE, TILESIZE))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()

        self.move_left = self.move_right = False

        self.pos = pg.math.Vector2(x, y)
        self.acc = pg.math.Vector2(0, GRAVITY)
        self.vel = pg.math.Vector2(0, 0)

    def jump(self):
        self.vel.y -= 3

    def update(self):
        self.vel.x = 0

        if self.move_left:
            self.vel.x = -PLAYER_SPEED
        if self.move_right:
            self.vel.x = PLAYER_SPEED

        self.vel += self.acc

        self.pos += self.vel
        self.rect.x = self.pos.x * TILESIZE
        self.rect.y = self.pos.y * TILESIZE

        if self.vel.y > 0.5:
            self.vel.y = 0.5

        hits = pg.sprite.spritecollide(self, self.game.walls, False)
        if hits:
            if self.vel.x > 0:
                self.pos -= self.vel
                self.rect.right = hits[0].rect.left
                self.vel.x = 0
            if self.vel.x < 0:
                self.pos -= self.vel
                self.rect.left = hits[0].rect.right
                self.vel.x = 0

        hits = pg.sprite.spritecollide(self, self.game.walls, False)
        if hits:
            if self.vel.y > 0:
                self.pos -= self.vel
                self.rect.bottom = hits[0].rect.top
                self.vel.y = 0
            if self.vel.y < 0:
                self.pos -= self.vel
                self.rect.top = hits[0].rect.bottom
                self.vel.y = 0

1 Ответ

2 голосов
/ 04 мая 2020

Проблема вызывается spritecollide дважды, в сочетании с обновлением позиции:

        hits = pg.sprite.spritecollide(self, self.game.walls, False)
        if hits:
            # If one of these conditions are true, the position will be updated,
            # continuing the previous velocity, i.e. going through the roof.
            if self.vel.x > 0:
                self.pos -= self.vel
                # [...]
            if self.vel.x < 0:
                self.pos -= self.vel
                # [...]

        # After you go through the roof, there's no more collision...
        hits = pg.sprite.spritecollide(self, self.game.walls, False)
        if hits:
            if self.vel.y > 0:
                self.pos -= self.vel
                # [...]
                self.vel.y = 0

Два случая с текущим кодом:

  • Если вы прыгаете без х- скорость, вы не обновите положение (ака go через крышу). Таким образом, второй вызов spritecollide возвращает непустой hits, и вы отскочите на крышу.
  • Если скорость х не равна нулю, вы обновите позицию go через крышу, а второй if hits: является ложным.

Решение: вызовите hits = pg.sprite.spritecollide(self, self.game.walls, False) только один раз и не меняйте положение, пока не будут обновлены все скорости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...