Problem with collision detection... - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: Problem with collision detection... (/thread-22414.html) |
Problem with collision detection... - michael1789 - Nov-12-2019 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 RE: Problem with collision detection... - ThomasL - Nov-12-2019 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. RE: Problem with collision detection... - michael1789 - Nov-12-2019 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() RE: Problem with collision detection... - ThomasL - Nov-12-2019 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 RE: Problem with collision detection... - michael1789 - Nov-12-2019 They are all wrong and changing at strange intervals. I clearly have my "* tile_size" in wrong spots. Thank you! |