def __init__(self, course_info): self.map_name = course_info["map_name"] self.map_size = course_info["map_size"] self.map_rect = pg.Rect((0, 0), self.map_size) self.view_rect = prepare.SCREEN_RECT.copy() self.class_map = {"tree": Tree, "rightgate": RightGate, "leftgate": LeftGate, "jump": Jump, "rock": Rock, "greensign": GreenSign, "bluesign": BlueSign, "blacksign": BlackSign, "pylon": Pylon } self.chairlift = ChairLift(self.map_size) self.obstacles = pg.sprite.Group() self.gates = pg.sprite.Group() self.load_from_info(course_info) self.make_sections()
class Course(object): def __init__(self, course_info): self.map_name = course_info["map_name"] self.map_size = course_info["map_size"] self.map_rect = pg.Rect((0, 0), self.map_size) self.view_rect = prepare.SCREEN_RECT.copy() self.class_map = {"tree": Tree, "rightgate": RightGate, "leftgate": LeftGate, "jump": Jump, "rock": Rock, "greensign": GreenSign, "bluesign": BlueSign, "blacksign": BlackSign, "pylon": Pylon } self.chairlift = ChairLift(self.map_size) self.obstacles = pg.sprite.Group() self.gates = pg.sprite.Group() self.load_from_info(course_info) self.make_sections() def make_sections(self, split_num=1000): """Divide the obstacles into different sections to avoid unnecessary collision checks.""" self.obstacles.add(self.chairlift.pylons.sprites()) num = max(1, int(len(self.obstacles) / split_num)) section_length = int(self.map_size[1] / num) self.sections = {} for y in range(0, self.map_size[1], section_length): rect_info = (0, y, self.map_size[0], section_length) rect = pg.Rect(rect_info) self.sections[rect_info] = pg.sprite.Group([x for x in self.obstacles if rect.collidepoint(x.rect.midbottom)]) def get_section_sprites(self): """Return sprites from sections that collide with self.view_rect.""" visible = set() for rect_info in self.sections: if pg.Rect(rect_info).colliderect(self.view_rect): visible.update(self.sections[rect_info]) return visible def load_from_info(self, course_info): """Instantiate course objects from course_info, a dict loaded from JSON.""" for item in course_info["obstacles"]: klass = self.class_map[item[0].lower()] midbottom = item[1] obstacle = klass(midbottom, self.obstacles) if "gate" in item[0].lower(): self.gates.add(obstacle) def reset(self): """Get course ready for player to take another run down the slope.""" for gate in self.gates: gate.reset() def update(self, dt, boarder): self.chairlift.update(dt) self.view_rect.center = boarder.rect.center self.view_rect.clamp_ip(self.map_rect) self.gates.update(boarder) self.collidables = {x for x in self.get_section_sprites() if x.rect.colliderect(self.view_rect)} for collidable in (c for c in self.collidables if c.collider.colliderect(boarder.collider)): collidable.collide_with_boarder(boarder) if boarder.collider.colliderect(self.chairlift.bottom_lifthut.rect): boarder.reset((self.map_rect.centerx, 50)) self.reset() def draw(self, surface, boarder=None): offset = -self.view_rect.left, -self.view_rect.top if boarder: self.collidables.add(boarder) onscreen = self.collidables else: onscreen = {x for x in self.get_section_sprites() if x.rect.colliderect(self.view_rect)} for obstacle in sorted(onscreen, key=lambda x: x.collider.bottom): obstacle.draw(surface, offset) self.chairlift.draw(surface, offset)