2

I want to implement solid blocks to my simple platformer game I´m working on, but I don´t know how. I tried lots of things, but nothing work. I want to do following: when I jUMP on it, I will stay there when I jump underneath it, I won´t reach the top when I jump from left side, I won´t reach the right side when I jump from right side, I won´t reach the left side

I would really appreciate your help, thanks.

my code:

from pygame.locals import *
SCREEN_WIDTH = 1923
SCREEN_HEIGHT = 1000


class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super(Player, self).__init__()
        self.surf = pygame.image.load('C:\Sprites\mrkva.png').convert()
        self.surf.set_colorkey((0, 0, 0), RLEACCEL)
        self.rect = self.surf.get_rect()
        self.rect.y = y
        self.rect.x = x

        self.isJump = False
        self.jumpCount = 9

    def update(self, pressed_keys):

        if pressed_keys[K_a]:
            self.rect.move_ip(-10, 0)
        if pressed_keys[K_d]:
            self.rect.move_ip(10, 0)

        if pressed_keys[K_LEFT]:
            self.rect.move_ip(-10, 0)
        if pressed_keys[K_RIGHT]:
            self.rect.move_ip(10, 0)

        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > SCREEN_WIDTH:
            self.rect.right = SCREEN_WIDTH
        if self.rect.top <= 0:
            self.rect.top = 0
        if self.rect.bottom >= 970:
            self.rect.bottom = 970
    
    def jump(self):
        if self.isJump:
            if self.jumpCount >= -10:
                neg = 3
                if self.jumpCount < 0:
                    neg = -3
                self.rect.y -= self.jumpCount**2 * 0.101 * neg
                self.jumpCount -= 1
            else:
                self.isJump = False
                self.jumpCount = 9

class Platform(pygame.sprite.Sprite):
    def __init__(self, xloc, yloc):
        super(Platform, self).__init__()
        self.surf = pygame.image.load('C:\Sprites\kocka.png').convert()
        self.surf.set_colorkey((255, 255, 255), RLEACCEL)
        self.rect = self.surf.get_rect()
        self.rect.y = yloc
        self.rect.x = xloc

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

pygame.display.set_caption('gameee')
platform = Platform(1, 527)
player = Player(1, 969)

all_sprites = pygame.sprite.Group()
all_sprites.add(platform)
all_sprites.add(player)


clock = pygame.time.Clock()
run = True
while run:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                run = False
            elif event.key == K_SPACE:
                player.isJump = True

        elif event.type == QUIT:
            run = False

    clock.tick(35)
    screen.blit(player.surf, player.rect)
    screen.fill((28, 173, 234))
    for entity in all_sprites:
        screen.blit(entity.surf, entity.rect)
    pygame.display.flip()

    pressed_keys = pygame.key.get_pressed()

    player.jump()
    player.update(pressed_keys)

    pygame.display.update()
pygame.quit()```
Meel
  • 67
  • 5
  • The best pygame platform example on Stack Overflow is [Add scrolling to a platformer in pygame](https://stackoverflow.com/questions/14354171/add-scrolling-to-a-platformer-in-pygame). – Rabbid76 Mar 22 '21 at 15:51
  • thanks Rabbid, but I´m not sure if this is the same problem i´m struggling with – Meel Mar 22 '21 at 15:57
  • I´m not going to copy someone´s else code – Meel Mar 22 '21 at 16:02
  • I´m not arguing and I´m sorry if it sounds like I am. Yeah, I´ll copy someone´s answer, but It´ll be only few lines, not full code – Meel Mar 22 '21 at 16:08
  • @sloth I´m not sure if I understood you well, but thanks – Meel Mar 22 '21 at 16:41

1 Answers1

2

When performing a collision test in platformer, you must always consider the direction of movement of the player. The player's reaction is different as they hit a platform from above or below. This can lead to different cases in your code.

I'll give you an example of how to land on a platform, based on your code.


First, correct the code that makes the player jump. Add a constant for the jump count and round the player's y coordinate. So the player falls on the same distance as it moves up:

JUMP_COUNT = 10

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        # [...]

        self.isJump = False
        self.jumpCount = JUMP_COUNT

    # [...]
    
    def jump(self):
        if self.isJump:
            if self.jumpCount >= -JUMP_COUNT:
                neg = 3
                if self.jumpCount < 0:
                    neg = -3
                self.rect.y -= round(self.jumpCount**2 * 0.101 * neg)
                self.jumpCount -= 1
            else:
                self.isJump = False
                self.jumpCount = JUMP_COUNT

Save the player's y coordinate before moving the player. Check for collisions after the player moves. If the player falls and a collision is detected, place the bottom of the player on top of the platform:

run = True
while run:
    # [...]

    prev_y = player.rect.y
    
    player.jump()
    player.update(pressed_keys)

    if player.rect.colliderect(platform.rect):
        dir_y = player.rect.y - prev_y
        if dir_y > 0:
            player.isJump = False
            player.jumpCount = JUMP_COUNT
            player.rect.bottom = platform.rect.top

    pygame.display.update()

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • okey, thanks for help, I read it and I tried to understand it, but it doesn´t work. when I jump **for first time** it will teleport me above – Meel Mar 22 '21 at 17:18
  • @Meel The GIF is created from your code using my suggestions. I've just changed the screen size and position of the player and platform, and I'm using uniform colored surfaces. – Rabbid76 Mar 22 '21 at 17:28
  • That´s weird... I found that the problem is in the your last section this: `if player.rect.colliderect(platform.rect): dir_y = player.rect.y - prev_y if dir_y > 0: player.isJump = False player.jumpCount = JUMP_COUNT player.rect.bottom = platform.rect.top` beacuse when I remove this part, it works – Meel Mar 22 '21 at 17:40
  • @Meel Sorry, that can't be the case. There is another bug in your code. However, I cannot see your code or debug it. – Rabbid76 Mar 22 '21 at 17:44
  • As you said, there was another bug, and I found it. now it works correctly. Please, excuse my previous behavior...:/ – Meel Mar 22 '21 at 19:15
  • @Meel Never mind. I do not have a problem. And I think I didn't get you right. My native language is not English and I have trouble understanding the fine details. – Rabbid76 Mar 22 '21 at 19:20
  • Thanks, by the way my native language is also not English, so for me, it wasn't easy too (and my phrasing is sometimes very awful) – Meel Mar 22 '21 at 19:32