Pygame when moving into another object the player object should stop

Question:

I’m working on this prototype in pygame where you control a square and I’m currently working on collisions with other objects. When the player collides with the object, the player should not be able to move into the object.

import pygame,sys

pygame.init()
Clock = pygame.time.Clock()
FPS = 60
size = [1000,800]
bg = [0,0,0]
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Movement')


class Player:
    def __init__(self,vel,x,y):
        self.vel = vel
        
        self.x = x
        self.y = y
        self.jump = False

    def move(self):
        k = pygame.key.get_pressed()
        if k[pygame.K_a]:
            self.x -= self.vel
        if k[pygame.K_d]:
            self.x += self.vel
        if k[pygame.K_w]:
            self.y -= self.vel
        if k[pygame.K_s]:
            self.y += self.vel
  

    def draw(self):
        pygame.draw.rect(screen,"red",(self.x,self.y,50,50))

    def bordercollsion(self):
        if self.x <=0:
            self.x=0
        if self.x >=950:
            self.x=950
        if self.y <=0:
            self.y=0
        if self.y >=750:
            self.y=750
        
        

    def do(self):
        self.move()
        self.draw()
        self.bordercollsion()
        
    

player = Player(1,500,600)

while True:
    screen.fill(bg)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))
            if event.key == pygame.K_ESCAPE:
                run = False
                pygame.quit
                sys.exit()
        
    player.do()
    en = pygame.draw.rect(screen,"blue",(10,20,50,50))
    pygame.display.update()
Asked By: Zero

||

Answers:

See How do I detect collision in pygame?. Use pygame.Rect/colliderect to detect collisions of rectangles.

Store the position of the player

player_pos = player.x, player.y

Move the palyer:

player.do()

Set up a rectangle for the player and the obstacle:

player_rect = pygame.Rect(player.x, player.y, 50, 50)
obstacle_rect = pygame.Rect(10, 20, 50, 50)

Reset the position of the player, when the rectangles collide:

if player_rect.colliderect(obstacle_rect):
    player.x, player.y = player_pos

Complete application loop

while True:
    screen.fill(bg)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))
            if event.key == pygame.K_ESCAPE:
                run = False
                pygame.quit
                sys.exit()
        
    player_pos = player.x, player.y
    player.do()
    player_rect = pygame.Rect(player.x, player.y, 50, 50)
    obstacle_rect = pygame.Rect(10, 20, 50, 50)
    if player_rect.colliderect(obstacle_rect):
        player.x, player.y = player_pos

    en = pygame.draw.rect(screen,"blue",(10,20,50,50))
    pygame.display.update()
    
Answered By: Rabbid76

I see that someone has already posted a good answer to your question, but my answer has been shoe-horned into your original code. I’ve marked my changes with ‘###’ to make them easier to find/identify.

There are a few ways to detect a collision in PyGame; this demonstrates PyGames colliderect() method. There is also a method using sprites and masking. The method you use depends on what you need.

import pygame,sys

pygame.init()
Clock = pygame.time.Clock()
FPS = 60
size = [1000,800]
bg = [0,0,0]
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Movement')


class Buscemi():    ### new class for the blue square
    '''Blue rectangle with which we must collide!'''    ###
    # def __init__(self):
        # pass
        # Normally you'd have an __init__() method, but this is one of
        #   those unusual cases were we don't actually need one.  It still
        #   returns a Buscemi object
    
    def draw(self):                                             ###
        '''Draws the rectangle and returns the Rect().'''       ###
        return pygame.draw.rect(screen,"blue",(10,20,50,50))    ###


class Player:
    def __init__(self,vel,x,y,buscemi): ### added buscemi argument
        self.vel = vel
        self.buscemi=buscemi    ### blue rectangle

        self.x = x
        self.y = y
        self.xold = None    ### for storing x before moving
        self.yold = None    ### for storing y before moving
        self.jump = False
        self.draw()     ### because we need self.dude

    def move(self):
        if not self.dude.colliderect(self.buscemi.draw()):  ### redraw blue and check collision
            k = pygame.key.get_pressed()
            self.xold = self.x  ###
            self.yold = self.y  ###
            if k[pygame.K_a]:
                self.x -= self.vel
            if k[pygame.K_d]:
                self.x += self.vel
            if k[pygame.K_w]:
                self.y -= self.vel
            if k[pygame.K_s]:
                self.y += self.vel
        else:   ### restore x and y
            self.x = self.xold  ###
            self.y = self.yold  ###
  

    def draw(self):
        self.dude = pygame.draw.rect(screen,"red",(self.x,self.y,50,50))    ### named the rectangle

    def bordercollsion(self):
        if self.x <=0:
            self.x=0
        if self.x >=950:
            self.x=950
        if self.y <=0:
            self.y=0
        if self.y >=750:
            self.y=750
        
        

    def do(self):
        self.move()
        self.draw()
        self.bordercollsion()
        
    

en = Buscemi()  ### we need en as an object
player = Player(1,500,600,en)   ### added one more argument

while True:
    screen.fill(bg)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))
            if event.key == pygame.K_ESCAPE:
                run = False
                pygame.quit
                sys.exit()
        
    # en = pygame.draw.rect(screen,"blue",(10,20,50,50))    ### made a class out of this
    player.do()
    pygame.display.update()
Answered By: Ian Moote
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.