2

I've been trying to get a Sonic The Hedgehog game working in Pygame and it works for the most part. Sonic can run fast, jump across platforms like a normal platformer, gets affected by gravity, collects rings, etc. (check attached video)

https://imgur.com/a/q1YrAXO

However, I cannot for the life of me get Sonic to run at different angles and go up slopes and loops like in the real games. I am aware such a project doesn't exist in Pygame (for the public to access anyway) and making the precise, mathematically accurate scripts can be hard to do.

Problematic code:
(from levels.py)

    def update(self):
        self.sonic.update()
        self.camera.update(self.sonic)  # Follow Sonic

        # Keep Sonic grounded
        self.sonic.grounded = False  
        for tile in self.tile_group:
            if self.sonic.mask.overlap(tile.mask, (tile.rect.x - self.sonic.hitbox.x, tile.rect.y - self.sonic.hitbox.y)):  
                self.sonic.Yvel = 0
                self.sonic.grounded = True  
                self.sonic.jumped = False
                self.sonic.angle = tile.angle
                break 

(from characters.py)

        if not self.grounded:
            self.Yvel += self.gravityforce  # Apply gravity
            self.Yvel = min(self.Yvel, 10)  # Cap max fall speed
            self.Xvel = self.groundSpeed
        else:
            # Adjusting speed with some trigonometry
            self.Yvel = self.groundSpeed * math.sin(self.angle * -1)
            self.Xvel = self.groundSpeed * math.cos(self.angle)    

        self.x += self.Xvel
        self.rect.x = self.x  # Update self.rect with the new x coordinate
        self.y += self.Yvel
        self.rect.y = self.y
        self.hitbox.x = self.x
        self.hitbox.y = self.y

I am using Tiled for mapmaking by the way, I'm not sure if that helps in my situation. I've manually added an angle attribute to the tiles currently in use and given them unique angles such as 20, 45, 90, etc. (which is why Sonic suddenly changes angle and jumps/phases through floor at times).

With all that being said, can anyone help or offer some advice? Literally anything will be appreciated.

0

1 Answer 1

1

You can use vector math so that the character follows the surface angle. Create a horizontal movement vector and then rotate it by the negative of the surface angle. That way when the character position is updated the movement should be aligned along the slope.

e.g.

if not self.grounded:
    # Apply gravity normally when in the air.
    self.Yvel += self.gravityforce
    self.Yvel = min(self.Yvel, 10)
else:
    # On the ground, create a horizontal movement vector…
    speed = self.groundSpeed * move_direction  # move_direction = -1, 0, or 1
    speed_vector = pygame.math.Vector2(speed, 0)
    # ...then rotate it to follow the surface.
    # (Note: the minus sign adjusts for your coordinate system.)
    speed_vector = speed_vector.rotate(-self.angle)
    self.Xvel = speed_vector.x
    self.Yvel = speed_vector.y

Example output of pygame script I wrote to show this working.

enter image description here

enter image description here

enter image description here

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

This seems like a rather useful approach to my problem. Only question is, will this method only work with sharp angle increments? (e.g 0 straight to 45, instead of going up by 10 like a smooth slope). I ask this because I intend to add loops and gradual slopes and I will have to use precise angles like 22.8 degrees for example.
@MitchellMartin Yes, should definitely work for a continuous slope as long as you are sampling the angle frequently enough. As long as you have a good way of getting the angle such as collision normals or ray-casting in your physics engine, it should work.
Okay, thanks for the info. Just one other thing, do you know what the best way to allocate angles to tiles are? Currently, I have to edit each individual tile in a tileset (using Tiled) and provide an angle such as 22.7 or 45. This is hard to do and also inaccurate as the angles are just slightly off. Do you have any ideas? In real classic Sonic games, they have an array with every possible slope and an angle with each. Each tile they made was based off a mask in the array and stitched together.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.