diff options
author | raylu <ray.lu@getclever.com> | 2013-10-12 03:48:28 -0700 |
---|---|---|
committer | raylu <ray.lu@getclever.com> | 2013-10-12 03:51:01 -0700 |
commit | fe8e0249c1916c74eed97d9750b16b03e87953e7 (patch) | |
tree | 045d1ae8fd5be2797a4cd30140d2b0a1fddac902 | |
parent | b3dcf3217957b0b02e5f367d44dad14b66702ae4 (diff) | |
download | troll-fe8e0249c1916c74eed97d9750b16b03e87953e7.tar.xz |
collision detection!
-rw-r--r-- | character.py | 46 | ||||
-rw-r--r-- | tileset.py | 14 | ||||
-rwxr-xr-x | troll | 4 |
3 files changed, 44 insertions, 20 deletions
diff --git a/character.py b/character.py index 9129c1e..51521ce 100644 --- a/character.py +++ b/character.py @@ -3,12 +3,14 @@ import pygame from tileset import Tileset class Character(object): + SPEED = 2 movement = [0, 0] - def __init__(self, start_pos): - self.render_x, self.render_y = start_pos - self.render_x *= Tileset.TILESIZE - self.render_y *= Tileset.TILESIZE + def __init__(self, start_pos, collisions): + self.pos = list(start_pos) + self.render_x = self.pos[0] * Tileset.TILESIZE + self.render_y = self.pos[1] * Tileset.TILESIZE + self.collisions = collisions def frame(self, keys): # are we done moving? @@ -17,27 +19,41 @@ class Character(object): if self.render_y % Tileset.TILESIZE == 0: self.movement[1] = 0 - SPEED = 2 - direction = None # can we start moving? + direction = None + movement_x = movement_y = None if self.movement[1] == 0: - if keys[pygame.K_DOWN] or keys[pygame.K_j]: - self.movement[1] = SPEED + if (keys[pygame.K_DOWN] or keys[pygame.K_j]): + movement_y = 1 direction = Tileset.DOWN elif keys[pygame.K_UP] or keys[pygame.K_k]: - self.movement[1] = -SPEED + movement_y = -1 direction = Tileset.UP + # vertical collision detection + # each direction is checked separately because holding + # down+right on a right wall should still move you down + if movement_y and (self.pos[0], self.pos[1] + movement_y) in self.collisions: + movement_y = 0 if self.movement[0] == 0: if keys[pygame.K_RIGHT] or keys[pygame.K_l]: - self.movement[0] = SPEED - if not self.movement[1]: # prefer up/down when moving diagonally + movement_x = 1 + if self.movement[1] == 0 and movement_y is None: # prefer up/down when moving diagonally direction = Tileset.RIGHT elif keys[pygame.K_LEFT] or keys[pygame.K_h]: - self.movement[0] = -SPEED - if not self.movement[1]: + movement_x = -1 + if self.movement[1] == 0 and movement_y is None: direction = Tileset.LEFT + # horizontal collision detection + if movement_x and (self.pos[0] + movement_x, self.pos[1]) in self.collisions: + movement_x = 0 + if movement_x: + self.movement[0] = movement_x + self.pos[0] += movement_x + if movement_y: + self.movement[1] = movement_y + self.pos[1] += movement_y # move! - self.render_x += self.movement[0] - self.render_y += self.movement[1] + self.render_x += self.movement[0] * self.SPEED + self.render_y += self.movement[1] * self.SPEED return direction @@ -5,6 +5,7 @@ import pygame class Tileset(object): TILESIZE = 16 + MAPSIZE = 50 RIGHT = 0 DOWN = 1 LEFT = 2 @@ -56,7 +57,14 @@ class Tileset(object): # read as array of 4-byte ints array = list(struct.unpack('<{}i'.format(len(data)/4), data)) loaded[name] = array + self.level_array = loaded['level'] + collidables = frozenset([6, 7, 8, 22, 24, 38, 39, 40]) + collisions = set() + for i, tile in enumerate(loaded['level']): + if tile in collidables: + y, x = divmod(i, self.MAPSIZE) + collisions.add((x, y)) units = { self.ENEMY1: [], @@ -64,15 +72,15 @@ class Tileset(object): } for i, tile in enumerate(loaded['units']): if tile in units.iterkeys(): - y, x = divmod(i, 50) + y, x = divmod(i, self.MAPSIZE) units[tile].append((x, y)) if len(units[self.PLAYER]) != 1: raise Exception('expected exactly 1 player tile in units layer, found ' + str(len(units[self.PLAYER]))) - return units + return collisions, units def render_level(self): for i, tile in enumerate(self.level_array): - y, x = divmod(i, 50) + y, x = divmod(i, self.MAPSIZE) x *= self.TILESIZE y *= self.TILESIZE tile_y, tile_x = divmod(tile - 1, self.TILESIZE) # those 1-indexing fuckers @@ -8,8 +8,8 @@ from character import Character pygame.init() screen = pygame.display.set_mode((800, 800)) tileset = Tileset(screen) -units = tileset.load_level() -character = Character(units[Tileset.PLAYER][0]) +collisions, units = tileset.load_level() +character = Character(units[Tileset.PLAYER][0], collisions) clock = pygame.time.Clock() black = (0, 0, 0) |