Physique de glissement simple, agissant différemment lors du déplacement vers la gauche ou vers la droite [dupliquer]

Nov 24 2020

Mon code agit différemment pour les vitesses négatives que pour les vitesses positives

J'essaie d'implémenter la physique des plates-formes, le joueur a une vitesse dans la direction X, la vitesse est augmentée ou diminuée lorsque l'utilisateur appuie respectivement sur "A" ou "D", ou définie sur 0 lorsque le joueur entre en collision avec un mur.

Pour simuler le frottement avec le sol, la vitesse X du joueur est multipliée par "self.drag" (un flotteur inférieur à 1)

Je m'attendais à ce que ce code réduise la vélocité X des joueurs, en la réduisant de manière négligeable près de 0, sans réellement inverser la vélocité (comme le ferait la soustraction d'une valeur), cela empêcherait le joueur de glisser de manière incontrôlable lorsque l'utilisateur n'impute pas de commandes de mouvement .

Cela fonctionne comme prévu lorsque vous vous déplacez vers la droite, mais lorsque vous vous déplacez vers la gauche, cela agit différemment, lorsque vous vous déplacez vers la gauche, le joueur semble continuer à flotter pendant un certain temps avant de s'arrêter.

Voici le code qui prend l'entrée du joueur, à l'intérieur de la classe de lecteur, exécutez chaque image:

dx = 0
if pygame.key.get_pressed()[pygame.K_a]:
        dx -= self.speed
if pygame.key.get_pressed()[pygame.K_d]:
        dx += self.speed

# to slow down horizontal movement
self.vx *= self.drag

# Add change in velocity to total velocity
self.vx += dx
self.vy += dy

Peut-être que le concept fonctionne et que je l'ai mal implémenté? Il y a un code de collision qui peut affecter les vitesses d'une manière que je n'ai pas remarquée? Ce système fonctionne-t-il différemment pour les vitesses positives et négatives?

Merci! Toute aide est très appréciée

Réponses

1 Rabbid76 Nov 24 2020 at 04:59

Le problème est causé, car pygame.Rectstocke les coordonnées intégrales:

Les coordonnées des objets Rect sont toutes des entiers. [...]

Le composant fraction de dxet dyest perdu lorsque vous effectuez:

self.Rect.x += dx
self.Rect.y += dy

Vous devez faire les calculs avec une précision en virgule flottante. Ajoutez un attribut xet yà la classe. Incrémentez les attributs moveet synchronisez l' Rectattribut:

class Player:
    def __init__(self, color):
        self.Rect = pygame.Rect([50, 50], [30, 50])
        self.x = self.Rect.x
        self.y = slef.Rect.y
        # [...]

    def move(self, dx, dy, platforms):
        # Test for collisions with platforms

        # handle movement on the X axis
        self.x += dx
        self.Rect.x = round(self.x)
        for platform in platforms:
            if self.Rect.colliderect(platform.Rect):
                if dx > 0:
                    self.Rect.right = platform.Rect.left
                if dx < 0:
                    self.Rect.left = platform.Rect.right
                self.x = self.Rect.x
                # Reset velocity when collision with wall
                self.vx = 0

        # handle movement on the Y axis
        self.Rect.y += dy
        self.Rect.y = round(self.y)
        for platform in platforms:
            if self.Rect.colliderect(platform.Rect):
                if dy > 0:
                    self.Rect.bottom = platform.Rect.top
                if dy < 0:
                    self.Rect.top = platform.Rect.bottom
                self.y = self.Rect.y
                # Reset velocity when collision with floor or roof
                self.vy = 0

        # return correctly collided rect to draw()
        return self.Rect