I am working on platformer game and I want to do basic collision with platforms, sadly still can't do it properly. Player movement is calculated like this:
velocity += acceleration
position += velocity + 0.5 * acceleration
All variables are vectors with x
and y
value. This works as expected, problem is with collision. My rules are:
Checking if bottom collide with platform is quite simple, but tricky part is detect, which side collided with platform and be able to set proper position for player.
I was trying to detect corners and middle from every side, but since my speed is not 1px per frame, sometimes player fall to quick and was detected as side as well.
What is good approach to detect which side collided?
I have a couple of platformer-like games in javascript, and this is how I implemented collision:
1. Stop falling when land on the platform: You can give your sprite a rectangle as a boundary area, and then use Pygames built-in Rect class to detect intersection. When this intersection happens between your sprites hitbox (the rectangle) and the platforms rectangle (another rectangle) you would set your players Y velocity to 0.
2. Start falling when running off-platform. I usually have a variable devoted to gravity, and simple constantly apply this to the sprite to push it down. This way, after you are no longer intersecting with a platform, it will fall downwards.
3. Stop moving upwards when hit a platform during a jump: The same thing as the before the intersection simply set the Y velocity to 0 after a rectangle collision, and let the player fall because of the constant gravity.
4. Stop moving to the side when hit wall, but be able to move to the opposite direction: Same thing, but set X velocity to 0 this time. (if you are getting stuck in a wall, you could always set X to more than 0 to nudge you back into play)
One more note, if you only want to do something when your sprite hits a certain edge of a platform, you can just create a rectangle that aligns with the side of a sprite. For example, if I wanted to see if something intersected with the left side of my sprite, I could use - height: same height - width: 1 - x: x + width - y: same y
Documentation on rectangles: https://www.pygame.org/docs/ref/rect.html
Well here is come code that can help to detect when you can jump from a platform:
self.rect.y += 2
platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
self.rect.y -= 2
# If it is ok to jump, set our speed upwards
if len(platform_hit_list) > 0:
velocity += acceleration
position += velocity + 0.5 * acceleration
Then code for detecting when you fall onto a platform:
if self.rect.y >= constants.SCREEN_HEIGHT and self.change_y >= 0:
self.change_y = 0
self.rect.y = constants.SCREEN_HEIGHT
And finally collision code:
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
# If we are moving right,
# set our right side to the left side of the item we hit
if self.change_x > 0:
self.rect.right = block.rect.left
elif self.change_x < 0:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
# Move up/down
velocity += acceleration
position += velocity + 0.5 * acceleration
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_y > 0:
self.rect.bottom = block.rect.top
elif self.change_y < 0:
self.rect.top = block.rect.bottom
# Stop our vertical movement
self.change_y = 0
Hope this all will help in some way to provide you with the answer that you require. Note that the blocks are referring to platforms and will be checking through every platform in a given list, and I use rects as it's one of the best ways to check collisions. As for change_x and change_y it's simply variables that store how much the player will be moving by.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.