Python Forum
Problem with collision detection...
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problem with collision detection...
#1
Hello,

This is a piece of my current project. It is in my "class Player()". It's pretty standard, but not working. The "walls" group is defined globally at the top, and when tested has sprites in it, yet my player sprite just moves right through walls and I don't get any errors.



    def move(self, dx=0, dy=0):
        
        if not self.collide_with_walls(dx, dy):
            self.rect.x += dx * tile_size
            self.rect.y += dy * tile_size
        
    
    def collide_with_walls(self, dx=0, dy=0):
        
        for wall in walls:
            if wall.rect.x==self.rect.x + dx and wall.rect.y == self.rect.y + dy:
                
                return True
        return False
Reply
#2
Your condition
if wall.rect.x==self.rect.x + dx and wall.rect.y == self.rect.y + dy:
seems never to be True.
Are you sure to test for equality? Maybe you need to test for being within a range?
Without more code it´s difficult to help, it´s just guessing.
Reply
#3
Here is the whole thing. It runs and makes the map, puts my player and he can move around fine... he just ignores the walls entirely.

How do I "test for equality"? I've used "print" to look at what I know how to.

import pygame
import random
import time

pygame.init()

blue = (5, 5, 200)
green = (4, 80, 4)
red = (250, 0, 0)
grey = (30, 30, 30)
black = (0, 0, 0)
brown = (100, 100, 5)
width = 600
height = 600
tile_size = 25


wallimage = pygame.image.load("C:/Users/owner/Desktop/python3/dungeongraphics/wall1.png")
heroimage = pygame.image.load("C:/Users/owner/Desktop/python3/dungeongraphics/hero_1.png")
diggers = pygame.sprite.Group()
players = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
base_tiles = pygame.sprite.Group()
floor_tiles = pygame.sprite.Group()        
walls = pygame.sprite.Group()


class Player(pygame.sprite.Sprite):
    def __init__(self, game, x, y):
        
    
        
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.image = pygame.transform.scale(heroimage, (tile_size, tile_size)) 
        
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

    def move(self, dx=0, dy=0):
        
        if not self.collide_with_walls(dx, dy):
            self.rect.x += dx * tile_size
            self.rect.y += dy * tile_size
        
    def collide_with_walls(self, dx=0, dy=0):
        print(walls)
        for wall in walls:
            if wall.rect.x==self.rect.x + dx and wall.rect.y == self.rect.y + dy:
                
                return True
        return False
    
   
    
    def update(self):
        
        self.rect.x = self.x * TILESIZE
        self.rect.y = self.y * TILESIZE



class Floor(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.image = pygame.Surface((tile_size, tile_size))
        self.image.fill(brown)
        self.rect = self.image.get_rect()   
        self.rect.x = x
        self.rect.y = y
        
        
        
        

class Base(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.colour = grey
        self.image = pygame.draw.rect(game.window, (self.colour), (x, y, tile_size, tile_size), 0)
        self.rect = pygame.Rect(x, y, tile_size, tile_size)
        self.x = x
        self.y = y
        pygame.display.flip()
        
class Wall(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.colour = red
        
        self.game = game
        
        self.image = pygame.transform.scale(wallimage, (tile_size, tile_size)) 
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        
        pygame.display.flip()


class Digger(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
     
    
        
        self.image = pygame.Surface((tile_size, tile_size))
        self.image.fill(red)
        self.rect = self.image.get_rect()   #pygame.Rect(self.rectx, self.recty, tile_size, tile_size)
        self.rect.x = x
        self.rect.y = y
        
def Make_map():
    
    for x in range(0, width, tile_size):
        for y in range(0, height, tile_size):
            
            base = Base(x, y)
            base_tiles.add(base)
     
    digger = Digger((width / 2), (height / 2))
    
    diggers.add(digger)
    all_sprites.add(digger)
    
    for i in range(70): 
        
        (dx, dy) = random.choice([(0, tile_size), (0, -tile_size), (-tile_size, 0), (tile_size, 0)])
   
        digger.rect.x = digger.rect.x + dx
        digger.rect.y = digger.rect.y + dy
        pygame.sprite.spritecollide(digger, floor_tiles, True)
        floor = Floor(digger.rect.x, digger.rect.y)
        all_sprites.add(floor)
        floor_tiles.add(floor)
        
        pygame.sprite.spritecollide(digger, base_tiles, True)
        
        
        all_sprites.draw(game.window)   
        pygame.display.update()    
        time.sleep(.01)    
        
    for floor in floor_tiles:
         
        for delta_x, delta_y in ((tile_size, 0), (0, tile_size), (-tile_size, 0), (0, -tile_size), (-tile_size, tile_size), (tile_size, -tile_size), (-tile_size, -tile_size), (tile_size, tile_size)):
      
            floor.rect.x = floor.rect.x + delta_x
            floor.rect.y = floor.rect.y + delta_y
            hits = pygame.sprite.spritecollide(floor, base_tiles, False)
            
            floor.rect.x = floor.rect.x - delta_x
            floor.rect.y = floor.rect.y - delta_y
            
            for hit in hits:
               
                wall = Wall(hit.rect.x, hit.rect.y)       
                all_sprites.add(wall)
                walls.add(wall)
            time.sleep(.01)        
    floor = Floor((width / 2), (height / 2))
    all_sprites.add(floor)
    floor_tiles.add(floor)        
                
class Game():
    def __init__(self):
        pygame.init()
        self.window = pygame.display.set_mode((width, height))
        pygame.display.set_caption("Dungeon")
        self.clock = pygame.time.Clock()
        pygame.key.set_repeat(500, 100)
        
    def New(self):
        
        Make_map()
       
        self.player = Player(game, (width / 2), (height / 2))
        all_sprites.add(self.player)
        players.add(self.player)
        self.run()
        all_sprites.draw(window)
        pygame.display.flip()
        
        
        
        

        
        
    def run(self):
        playing = True
        while playing:
               
            self.update()
            
            self.draw()
            self.events()
            

    def quit(self):
        pygame.quit()
        sys.exit()

    def update(self):
        print("update")
        all_sprites.draw(game.window)
        
        
           

    def draw(self):
        print("draw")
        self.window.fill(black)
        all_sprites.draw(self.window)
        pygame.display.flip()
  

    def events(self):
        # catch all events here
        
        check = True
        while check:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.quit()
                    if event.key == pygame.K_LEFT:
                        self.player.move(dx=-1)
                        check = False
                    if event.key == pygame.K_RIGHT:
                        self.player.move(dx=1)
                        check = False
                    if event.key == pygame.K_UP:
                        self.player.move(dy=-1)
                        check = False
                    if event.key == pygame.K_DOWN:
                        self.player.move(dy=1)
                        check = False





game = Game()
game.New()
Reply
#4
For debugging print the values you are comparing and look at the values that are printed when player hits a wall.

    def collide_with_walls(self, dx=0, dy=0):
        for wall in walls:
            print(wall.rect.x, self.rect.x+dx, wall.rect.y, self.rect.y+dy)
            if wall.rect.x==self.rect.x + dx and wall.rect.y == self.rect.y + dy:
                return True
        return False
Reply
#5
They are all wrong and changing at strange intervals. I clearly have my "* tile_size" in wrong spots.

Thank you!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Question [PyGame] Problem with collision of player and enemy Nekotrooper 1 600 Dec-08-2023, 03:29 PM
Last Post: deanhystad
  can't get collision detection to work in platform game chairmanme0wme0w 10 3,662 Aug-19-2022, 03:51 PM
Last Post: deanhystad
  [PyGame] Collision in not happening onizuka 3 3,359 Sep-07-2020, 11:30 AM
Last Post: metulburr
  [PyGame] No collision detection onizuka 6 3,596 Aug-18-2020, 01:29 PM
Last Post: onizuka
  Arcade Collision Problem randor 0 2,656 Oct-28-2019, 11:17 PM
Last Post: randor
  Multiple wall collision in pacman rustyjoe 4 4,029 Aug-11-2019, 08:08 AM
Last Post: rustyjoe
  drawing, moving, and collision problems (pygame) SheeppOSU 26 14,435 Apr-22-2019, 03:09 AM
Last Post: SheeppOSU

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020