0

So i have been trying to get a 4-way collision to work for my platformer game, and i have come across a weird interaction where my rectangle is cliping through the platform when i hit it with a certain angle. It is when you hit the platform in the bottom corners of it and all it does is make my player glide through the platform.

Any ideas to why this is happening?

All of the code i use is on this github page: https://github.com/dejvano02/Jump-man

The collision code is in the main.py file, under the "update" function.

code:

# Jump man

import pygame as pg
import random
import os
from settings import *
from sprites import *


class Game:

    def __init__(self):
        # initialize game window, etc
        # pass = do nothing
        pg.init()
        pg.mixer.init()
        self.screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pg.display.set_caption(TITLE)
        self.clock = pg.time.Clock()
        self.running = True
        self.font_name = pg.font.match_font(FONT_NAME)

    def new(self):
        # start a new game
        self.all_sprites = pg.sprite.Group()
        self.platforms = pg.sprite.Group()
        self.plat_start = pg.sprite.Group()
        self.player = Player(self)
        self.all_sprites.add(self.player)
        p1 = Platform(0, SCREEN_HEIGHT-20, SCREEN_WIDTH, 120)
        self.all_sprites.add(p1)
        self.plat_start.add(p1)
        p2 = Platform(SCREEN_WIDTH / 2 - 50, SCREEN_HEIGHT / 2, 100, 100)
        self.all_sprites.add(p2)
        self.platforms.add(p2)
        p3 = Platform(SCREEN_WIDTH / 2 + 250, SCREEN_HEIGHT / 3, 100, 200)
        self.all_sprites.add(p3)
        self.platforms.add(p3)
        self.run()

    def run(self):
        # Game loop
        self.playing = True
        while self.playing:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()

    def update(self):
        # Game loop - Update
        self.all_sprites.update()
        # add collision to all side of the ascending platform
        hits_other_plat = pg.sprite.spritecollide(self.player, self.platforms, False)
        if hits_other_plat:
            # all if statements are checking all sides of the platforms
            # Checking collision on the top of the platforms
            if self.player.rect.top < hits_other_plat[0].rect.top:
                self.player.pos.y = hits_other_plat[0].rect.top + 1
                self.player.vel.y = 0
                # removes stuttering of player on platforms
                self.player.vx = 0
            # Checking collision on the bottom of the platforms
            elif self.player.rect.bottom > hits_other_plat[0].rect.bottom:
                self.player.vel.y *= COLLISION_CONST
            # Checking collision on the left of the platforms
            elif self.player.rect.right > hits_other_plat[0].rect.left:
                self.player.vx *= -1
                self.player.vel.y *= 1
            # Checking collision on the right of the platforms
            elif self.player.rect.left < hits_other_plat[0].rect.right:
                self.player.vx *= -1
                self.player.vel.y *= 1
        # add collision to the top of the starting platform
        hits_start_plat = pg.sprite.spritecollide(self.player, self.plat_start, False)
        if hits_start_plat:
            self.player.pos.y = hits_start_plat[0].rect.top + 1
            self.player.vel.y = 0
            self.player.vx = 0
        # if player is high enough, scroll screen
        if self.player.rect.top <= SCREEN_HEIGHT / 4:
            self.player.pos.y += abs(self.player.vel.y)
            for plat in self.platforms:
                plat.rect.y += abs(self.player.vel.y)
            for plat1 in self.plat_start:
                plat1.rect.y += abs(self.player.vel.y)
        # if player is low enough, scroll screen
        if self.player.rect.top >= SCREEN_HEIGHT - (SCREEN_HEIGHT / 5):
            self.player.pos.y -= abs(self.player.vel.y)
            for plat in self.platforms:
                plat.rect.y -= abs(self.player.vel.y)
            for plat in self.plat_start:
                plat.rect.y -= abs(self.player.vel.y)

    def events(self):
        # Game loop - events
        for event in pg.event.get():
            # check for closing of window
            keys = pg.key.get_pressed()
            if event.type == pg.QUIT:
                if self.playing:
                    self.playing = False
                    self.running = False
            if keys[pg.K_ESCAPE]:
                if self.playing:
                    self.playing = False
                    self.running = False
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_SPACE:
                    # print("space is pressed")
                    self.player.jump_charge_right()
            if event.type == pg.KEYUP:
                if event.key == pg.K_SPACE:
                    # print("space is released")
                    self.player.jump_release_right()

            # if event.type == pg.KEYDOWN:
            #     if event.key == pg.K_SPACE:
            #         pass
            #     if event.key == pg.K_RIGHT and PLAYER_CHARGE_RIGHT_X <= 15:
            #         self.vx += 1
            #     if event.key == pg.K_LEFT and PLAYER_CHARGE_LEFT_X <= -15:
            #         PLAYER_VEL_LEFT_X == 0
            #         PLAYER_VEL_RIGHT_X == 0
            #         PLAYER_CHARGE_LEFT_X -= 3

    def draw(self):
        # Game loop - draw
        self.screen.fill(BGCOLOR)
        self.all_sprites.draw(self.screen)
        # *after* drawing everything, flip the display
        pg.display.flip()

    def show_start_screen(self):
        # start menu / splash screen
        self.screen.fill(BGCOLOR)
        self.draw_text(TITLE, 48, WHITE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 4)
        self.draw_text("Space to jump, Arrows to move", 22,
                       WHITE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)
        self.draw_text("Press a key to play", 22, WHITE, SCREEN_WIDTH / 2, SCREEN_HEIGHT * 3 / 4)
        pg.display.flip()
        self.wait_for_key()

    def show_go_screen(self):
        # game over/continue
        if not self.running:
            return
        self.screen.fill(BGCOLOR)
        self.draw_text("GAME OVER", 48, WHITE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 4)
        self.draw_text("Press a key to play", 22, WHITE, SCREEN_WIDTH / 2, SCREEN_HEIGHT * 3 / 4)
        pg.display.flip()
        self.wait_for_key()

    def wait_for_key(self):
        waiting = True
        while waiting:
            self.clock.tick(FPS)
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    waiting = False
                    self.running = False
                if event.type == pg.KEYUP:
                    waiting = False

    def draw_text(self, text, size, color, x, y):
        pg.init()
        font = pg.font.Font(self.font_name, size)
        text_surface = font.render(text, True, color)
        text_rect = text_surface.get_rect()
        text_rect.midtop = (x, y)
        self.screen.blit(text_surface, text_rect)


g = Game()
g.show_start_screen()
while g.running:
    g.new()
    g.show_go_screen()

pg.quit()
Thomas Kerby
  • 1,118
  • 2
  • 13
  • 38
  • 2
    You have to past the relevant code in the question! – Rabbid76 Apr 29 '20 at 08:52
  • what python and pygame version are you running. if you can try and implement the walrus operator as it will make somethings go faster and help remove clutter – user19273 Apr 29 '20 at 17:29

0 Answers0