Changed collision to using blockers for sprites and objects
Justin Armstrong justinmeister@gmail.com
Mon, 10 Mar 2014 17:39:47 -0700
3 files changed,
75 insertions(+),
20 deletions(-)
M
data/collision.py
→
data/collision.py
@@ -6,21 +6,40 @@ """Handles collisions between the user, blockers and computer
characters""" def __init__(self, player, blockers, sprites): self.player = player - self.blockers = blockers + self.blockers = self.make_blocker_list(blockers, sprites) self.sprites = sprites self.collided = False + + def make_blocker_list(self, blockers, sprites): + """Return a combined list of sprite blockers and object blockers""" + for sprite in sprites: + blockers.extend(sprite.blockers) + + return blockers + def update(self): """Checks for collisions between game objects""" + self.update_blockers() self.player.rect.x += self.player.x_vel self.player.rect.y += self.player.y_vel + self.check_for_blockers() + self.update_blockers() + for sprite in self.sprites: + sprite.rect.x += sprite.x_vel + sprite.rect.y += sprite.y_vel self.check_for_blockers() if self.player.rect.x % 32 == 0 and self.player.rect.y % 32 == 0: self.player.begin_resting() + def update_blockers(self): + """Update blockers list""" + + + def check_for_blockers(self): """Checks for collisions with blocker rects""" for blocker in self.blockers:@@ -30,10 +49,6 @@
if self.collided: self.reset_after_collision() self.collided = False - self.player.begin_resting() - - elif pg.sprite.spritecollide(self.player, self.sprites, False): - self.reset_after_collision() self.player.begin_resting()
M
data/components/person.py
→
data/components/person.py
@@ -1,4 +1,5 @@
__author__ = 'justinarmstrong' +import math import pygame as pg from .. import setup@@ -17,12 +18,15 @@ self.direction = direction
self.image_list = self.animation_dict[self.direction] self.image = self.image_list[self.index] self.rect = self.image.get_rect(left=x, top=y) + self.old_rect = self.rect self.state_dict = self.create_state_dict() self.vector_dict = self.create_vector_dict() - self.state = 'resting' self.x_vel = 0 self.y_vel = 0 self.timer = 0.0 + self.current_time = 0.0 + self.state = 'resting' + self.blockers = self.set_blockers() def create_spritesheet_dict(self, sheet_key):@@ -83,9 +87,40 @@
return vector_dict - def update(self, *args): + def update(self, keys, current_time): """Implemented by inheriting classes""" - pass + self.blockers = self.set_blockers() + self.current_time = current_time + self.check_for_input() + state_function = self.state_dict[self.state] + state_function() + + + def set_blockers(self): + """Sets blockers to prevent collision with other sprites""" + blockers = [] + + if self.state == 'resting': + blockers.append(pg.Rect(self.rect.x, self.rect.y, 32, 32)) + + elif self.state == 'moving': + if self.rect.x % 32 == 0: + tile_float = self.rect.y / float(32) + tile1 = (self.rect.x, math.ceil(tile_float)*32) + tile2 = (self.rect.x, math.floor(tile_float)*32) + tile_rect1 = pg.Rect(tile1[0], tile1[1], 32, 32) + tile_rect2 = pg.Rect(tile2[0], tile2[1], 32, 32) + blockers.extend([tile_rect1, tile_rect2]) + + elif self.rect.y % 32 == 0: + tile_float = self.rect.x / float(32) + tile1 = (math.ceil(tile_float)*32, self.rect.y) + tile2 = (math.floor(tile_float)*32, self.rect.y) + tile_rect1 = pg.Rect(tile1[0], tile1[1], 32, 32) + tile_rect2 = pg.Rect(tile2[0], tile2[1], 32, 32) + blockers.extend([tile_rect1, tile_rect2]) + + return blockers def resting(self):@@ -103,6 +138,14 @@
def moving(self): """Increment index and set self.image for animation.""" + self.animation() + + assert(self.rect.x % 32 == 0 or self.rect.y % 32 == 0), \ + 'Not centered on tile' + + + def animation(self): + """Adjust sprite image frame based on timer""" if (self.current_time - self.timer) > 100: if self.index < (len(self.image_list) - 1): self.index += 1@@ -112,8 +155,6 @@ self.timer = self.current_time
self.image = self.image_list[self.index] - assert(self.rect.x % 32 == 0 or self.rect.y % 32 == 0), \ - 'Not centered on tile' def begin_moving(self, direction):@@ -122,6 +163,7 @@ self.direction = direction
self.image_list = self.animation_dict[direction] self.timer = self.current_time self.state = 'moving' + self.old_rect = self.rect if self.rect.x % 32 == 0: self.y_vel = self.vector_dict[self.direction][1]@@ -145,6 +187,7 @@
def update(self, keys, current_time): """Updates player behavior""" + self.blockers = self.set_blockers() self.keys = keys self.current_time = current_time self.check_for_input()@@ -163,11 +206,6 @@ elif self.keys[pg.K_LEFT]:
self.begin_moving('left') elif self.keys[pg.K_RIGHT]: self.begin_moving('right') - - - - -@@ -175,7 +213,7 @@ class Soldier(Person):
"""Soldier for the castle""" def __init__(self): - super(Soldier, self).__init__('soldier') + super(Soldier, self).__init__('soldier', x, y) class FemaleVillager(Person):@@ -189,5 +227,5 @@ class MaleVillager(Person):
"""Male Person for town""" def __init__(self): - super(MaleVillager, self).__init__('male villager') + super(MaleVillager, self).__init__('male villager', x, y)
M
data/states/town.py
→
data/states/town.py
@@ -262,16 +262,16 @@ def create_blockers(self):
"""Creates invisible rect objects that will prevent the player from walking into trees, buildings and other solid objects""" tile_map = open(os.path.join('data', 'states', 'town_blocker_layer.txt'), 'r') - blocker_list = [] + blockers = [] for row, line in enumerate(tile_map): for column, letter in enumerate(line): if letter == 'B': - blocker_list.append(pg.Rect(column*32, row*32, 32, 32)) + blockers.append(pg.Rect(column*32, row*32, 32, 32)) tile_map.close() - return blocker_list + return blockers def create_viewport(self):@@ -313,11 +313,13 @@
self.draw_level(surface) + def draw_level(self, surface): """Blits all images to screen""" self.level_surface.blit(self.town_map['surface'], self.viewport, self.viewport) self.level_surface.blit(self.player.image, self.player.rect) self.town_sprites.draw(self.level_surface) + surface.blit(self.level_surface, (0,0), self.viewport)