python - Pygame: Collision With tiles not working -


i working on abstraction layer pygame, , have come across problem when trying check collisions maps. able load , display map, store rectangles collidable. when print list of rectangles, see in place, when iterate on every rect , try check collision rect, returns true when rects not collide. also, when try debug rects drawing red-outlined rectangle on each 1 of them, nothing gets drawn though when print rectangle, prints rectangle exists.

here few snippets framework:

class tilemap(object): """this tilemap object, takes array of strings object, , places surface have in strings. supports 1 surface per map, have make multiple maps floor, walls, etc.""" def __init__(self, level_surface,level_string = none, string_char = "#", surface = none, surface_dim = vector2(50, 50),surface_color = (255, 255, 255)):     self.level = level_string     self.char = string_char     self.surface = surface     if self.surface none:         self.surface = pygame.surface(surface_dim)         self.surface.fill(surface_color)      self.surface_width = self.surface.get_rect().w     self.surface_height = self.surface.get_rect().h     self.collision_list = []     y in xrange(len(self.level)):         x in xrange(len(self.level[y])):             if self.level[y][x] self.char:                 self.collision_list.insert(len(self.collision_list), rect((x) * self.surface_width,(y) * self.surface_height, self.surface_width, self.surface_height))     print self.collision_list     y in xrange(len(self.level)):         x in xrange(len(self.level[y])):             if self.level[y][x] self.char:                 level_surface.blit(self.surface.convert_alpha(), (self.surface_width * x, self.surface_height * y))  def replace_char_with(self, level_surface,char = ".", surface = none):     y in xrange(len(self.level)):         x in xrange(len(self.level[y])):             if self.level[y][x] char:                 level_surface.blit(surface.convert_alpha(), (surface.get_width() * x, surface.get_height() * y))  def check_col(self, rect):     tilerect in self.collision_list:         if rect.x + rect.w > tilerect.x or rect.y + rect.h > tilerect.y or rect.x < tilerect.x + tilerect.w or rect.y < tilerect.y + tilerect.h:             return true         else:             return false  def debug_draw(self, screen):     rect in self.collision_list:         pygame.draw.rect(screen, (255, 0, 0), rect, 2) 

snippet # 2, testing code:

def main(): pygame.locals import k_w, k_a, k_s, k_d pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.clock() player = sprite(pygame.image.load("trapdoor_tile.png"), vector2(100, 100)) floor = ["########################################",          "########################################",          "#####...##.#.#..###.#.###..#############",          "#####.######.#.#.####.##.#.#############",          "######.###.#.##..##.#.###.##############",          "#####.####.########.####################",          "#####.#.##.###.#.##.#.##.#.#############",          "########################################",          "#######################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################"          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################",          "########################################"]  walls = ["########################################",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "#......................................#",          "########################################"]  level_surf = pygame.surface((640, 480)) floor_map = tilemap(level_surf, floor, "#", pygame.image.load("ground_tile.png").convert_alpha()) floor_map.replace_char_with(level_surf, ".", pygame.image.load("trapdoor_tile.png").convert_alpha()) wall_map = tilemap(level_surf, walls, "#", pygame.image.load("wall_tile.png").convert_alpha())  while true:     screen.fill((0, 0, 0))     milliseconds = clock.tick(60) / 10.      event in pygame.event.get():         if event.type == pygame.locals.quit:             pygame.quit()             raise systemexit      wall_map.debug_draw(screen);      screen.blit(level_surf, vector2(0, 0))      if wall_map.check_col(player.dummyrect):         player.colliding = true         print "why!"     else:         player.colliding = false      player.update(milliseconds)     player.draw(screen)      keystate = pygame.key.get_pressed()      player.apply_drag()      if keystate[k_w]:         player.set_accel_y(-5)     elif keystate[k_s]:         player.set_accel_y(5)     elif keystate[k_a]:         player.set_accel_x(-5)     elif keystate[k_d]:         player.set_accel_x(5)      pygame.display.flip() 

the sprite class player created:

class sprite(object): def __init__(self, surface = none, initial_position = (100, 100)):     self.surface = surface     self.rect = self.surface.get_rect(center = initial_position)     self.acceleration = vector2(0, 0)     self.delta_time = none     self.dummyrect = self.rect     self.colliding = false  def update(self, delta_time):     self.dummyrect = self.rect.move(self.acceleration.x * delta_time, self.acceleration.y * delta_time)     if not self.colliding:         self.rect = self.dummyrect     else:         self.dummyrect = self.rect     self.delta_time = delta_time  def draw(self, screen):     screen.blit(self.surface, self.rect)  def draw_to_cam(self, screen,camera):     screen.blit(self.surface, camera.to_camera_coords(vector2(self.rect.x, self.rect.y)))  def collide(self, rectangle):     if self.rect.x + self.rect.w > rectangle.x:         self.rect.x -= 1;     if self.rect.x < rectangle.x + rectangle.w:         self.rect.x += 1     if self.rect.y < rectangle.y + rectangle.h:         self.rect.y += 1;     if self.rect.y + self.rect.h > rectangle.y:         self.rect.y -= 1;  def set_accel_x(self, new_val):     self.acceleration.x = new_val  def set_accel_y(self, new_val):     self.acceleration.y = new_val  def apply_drag(self, drag_mul = 1):     if self.acceleration.x > 0:         self.acceleration.x -= self.delta_time * drag_mul     else:         self.acceleration.x += self.delta_time * drag_mul      if self.acceleration.y > 0:         self.acceleration.y -= self.delta_time * drag_mul     else:         self.acceleration.y += self.delta_time * drag_mul      if self.acceleration.x < 0.1 or self.acceleration.x > -0.1:         self.acceleration.x = 0     if self.acceleration.x < 0.1 or self.acceleration.x > -0.1:         self.acceleration.x = 0     if self.acceleration.y < 0.1 or self.acceleration.y > -0.1:         self.acceleration.y = 0     if self.acceleration.y < 0.1 or self.acceleration.y > -0.1:         self.acceleration.y = 0  def get_center(self):     return vector2(self.rect.centerx, self.rect.centery) 

those 3 main snippets involved, have no idea why collision returned every time, seems so. if has answer, or explanation @ least, why occurs, please brother out!

your check_col function using 'or' operators, meaning you're returning true collision long 1 condition met. here code:

def check_col(self, rect): tilerect in self.collision_list:     if rect.x + rect.w > tilerect.x or rect.y + rect.h > tilerect.y or rect.x < tilerect.x + tilerect.w or rect.y < tilerect.y + tilerect.h:         return true     else:         return false 

what want more this:

def check_col(self, rect):     tilerect in self.collision_list:         if ((rect.x + rect.w > tilerect.x , rect.x <= tilerect.x + tilerect.width) or             (tilerect.x + tilerect.width > rect.x , tilerect.x <= rect.x + rect.width)) ,             ((rect.y + rect.h > tilerect.y , rect.y <= tilerect.y + tilerect.height) or             (tilerect.y + tilerect.height > rect.y , tilerect.y <= rect.y + rect.height))              return true         else:             return false 

also, might worth pointing out pygame's rect class has own set of collision detection functions. detect collision between 2 rects can use rect.colliderect(rect).

http://www.pygame.org/docs/ref/rect.html#pygame.rect.colliderect


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -