Example #1
0
def _produce_statics_for_mid_grids(mid_grid, tileset_seq, grid_width,
                                   grid_height):
    # To get proper depth, we need to sort and render each full 'object' separately.
    # This function automatically produces objects, one for each set of horizontally touching tiles.

    # list of uneaten tiles
    uneaten = []
    for layer_name, layer_grid in mid_grid.iteritems():
        for y in range(grid_height):
            for x in range(grid_width):
                if layer_grid[y][x] != -1:
                    uneaten.append((x, y, int(layer_name[3:]
                                              or '0'), layer_grid[y][x]))

    # find groups of horizontally touching tiles
    touching = {}
    for x, y, d, t in uneaten:
        eaten = False
        r = rect.Rect((x * TILE_SIZE, y * TILE_SIZE), (TILE_SIZE, TILE_SIZE))

        for maybe_rect, maybe_friends in touching.iteritems():
            # horizontal touching!
            if rect.Rect(*maybe_rect).inflate(2, 0).colliderect(r):
                eaten = (maybe_rect, maybe_friends)
                break

        if eaten:
            del touching[maybe_rect]
            maybe_friends.append((x, y, d, t))
            touching[rect.Rect(
                *maybe_rect).union(r).to_tuple()] = maybe_friends
        else:
            touching[r.to_tuple()] = [(x, y, d, t)]

    # TODO: tiles might not be joined optimally. e.g. consider block growing left and block
    #  growing right - even though they're touching, they started out not touching, so they
    #  are separate in the list.

    # produce StaticObjects from groups of touching tiles
    static_objects = []
    for k, v in touching.iteritems():
        r = rect.Rect(*k)
        static_objects.append(
            static_object.StaticObject(
                r.x, r.y, r.width, r.height,
                _render_static(r, v, tileset_seq, grid_width, grid_height)))

    return static_objects
Example #2
0
    def check_object_click(self, pos, typ, button=None):
        if typ == 'down':
            if pos[0] > LEVEL_WIDTH or pos[1] > LEVEL_HEIGHT:  # don't check for object outside of level area
                return
            for o_name, o in self.game.objects.iteritems():
                if o == self.game.cursor:
                    continue
                st = SELECTION_TOLERANCE
                temp_rect = rect.Rect((o.coord[0] - st, o.coord[1] - st), (o.dimensions[0] + 2*st, o.dimensions[1] + 2*st))
                if temp_rect.collidepoint(self.game.camera.undo_camera(pos)):

                    if self.object_capture_request:
                        self.object_capture_request = False
                        self.object_capture_function(o_name)
                    elif isinstance(o, character.Character):
                        self.game.disp_object_stats = True
                        self.game.object_stats = o.info_sheet
                        self.game.selected_object = o
                        if self.game.state == EDITOR:
                            self.game.editor.handle_object_click(o_name)

                    self.interaction_this_click = True
                    return
            self.game.selected_object = None
            self.game.disp_object_stats = False
            self.game.object_stats = None
            self.game.editor.object_to_edit_selected(None)
Example #3
0
    def create_new_zone(self):
        trig = self.drop_lists['triggers'].selected

        if trig is None:
            return

        zone = rect.Rect((0, 0), (1, 1))
        trig.add_zone(zone)

        self.drop_lists['zones'].refresh()
        self.drop_lists['zones'].set_to_value(zone)
Example #4
0
    def draw_torch(self):
        # TODO: do this in a sane/clever way
        ppos = (self.game.players['player1'].coord[0] +
                self.game.players['player1'].dimensions[0] // 2,
                self.game.players['player1'].coord[1] +
                self.game.players['player1'].dimensions[1] // 2)

        hole = rect.Rect(
            self.game.camera.apply_camera((ppos[0] - self.light_size[0] // 2,
                                           ppos[1] - self.light_size[1] // 2)),
            self.light_size)

        hole.width *= self.game.camera.zoom
        hole.height *= self.game.camera.zoom

        self.light.scale_x = (200 /
                              self.light.image.height) * self.game.camera.zoom
        self.light.scale_y = (200 /
                              self.light.image.height) * self.game.camera.zoom

        self.light.position = hole.bottomleft

        self.game.screen_objects_to_draw.append(
            primitives.RectPrimitive(x=0,
                                     y=0,
                                     width=hole.right,
                                     height=hole.bottom,
                                     color=(0, 0, 0, 255)))

        self.game.screen_objects_to_draw.append(
            primitives.RectPrimitive(x=hole.right,
                                     y=0,
                                     width=window.width - hole.right,
                                     height=hole.top,
                                     color=(0, 0, 0, 255)))

        self.game.screen_objects_to_draw.append(
            primitives.RectPrimitive(x=hole.left,
                                     y=hole.top,
                                     width=window.width - hole.left,
                                     height=window.height - hole.top,
                                     color=(0, 0, 0, 255)))

        self.game.screen_objects_to_draw.append(
            primitives.RectPrimitive(x=0,
                                     y=hole.bottom,
                                     width=hole.left,
                                     height=window.height - hole.bottom,
                                     color=(0, 0, 0, 255)))

        self.game.screen_objects_to_draw.append(self.light)
Example #5
0
def _produce_collision(mid_layers, width, height):

    coll_grid = [[(False, None) for i in range(width)] for j in range(height)]

    for ml_name, ml in mid_layers.iteritems():
        for y in range(height):
            for x in range(width):
                if ml[y][x] != -1:
                    coll_grid[y][x] = (True,
                                       rect.Rect(
                                           (x * TILE_SIZE, y * TILE_SIZE),
                                           (TILE_SIZE, TILE_SIZE)))

    return coll_grid
Example #6
0
    def load_from_dict(self, d):
        self.options = json.loads(d[u'options'])
        self.object_references = d[u'object_references']

        self.interaction_type = d[u'interaction_type']

        zones = []
        for tup_string in d[u'zones']: # expected format is json((x, y), (w, h))
            tup = json.loads(tup_string)
            z = rect.Rect(tup[0], tup[1])
            zones.append(z)

        self.zones = zones

        actions = json.loads(d[u'actions'])
        action_funcs = [trigger_functions_dict[a] for a in actions]
        for a in action_funcs:
            self.add_action(a)

        self.enable_for_objects()
Example #7
0
    def __init__(self, tile_type_grid, coll_grid, m, pos):
        x, y = pos

        tile_ref = tile_type_grid[y][x]

        if tile_ref != -1:
            self.tileset_coord = ((m.tileset_rows - 1) -
                                  tile_ref // m.tileset_cols,
                                  tile_ref % m.tileset_cols)
        else:
            self.tileset_coord = (m.tileset_rows - 1, 0)

        self.tile_ref = tile_ref
        self.rect = rect.Rect((x * TILE_SIZE, y * TILE_SIZE),
                              (TILE_SIZE, TILE_SIZE))

        if coll_grid and coll_grid[y][x]:
            self.walkable = False
        elif self.tile_ref == -1:
            self.walkable = False
        else:
            self.walkable = True
Example #8
0
    def __init__(self, game, object_refs, actions=None):
        Trigger.__init__(self, game, object_refs, actions)

        self._pos = (0, 0)
        self._size = (1, 1)
        self.zone = rect.Rect(self._pos, self._size)
Example #9
0
 def size(self, s):
     self._size = s
     self.zone = rect.Rect(self._pos, self._size)
Example #10
0
 def pos(self, p):
     self._pos = p
     self.zone = rect.Rect(self._pos, self._size)
Example #11
0
 def __init__(self, x, y, w, h, texture):
     self.rect = rect.Rect((x, y), (w, h))
     self.sprite = sprite.Sprite(texture, x=x, y=y)
     self.coord = (x, y)
     self.flair = {}
Example #12
0
    def __init__(self, game_class, x, y, w, h, sprite_sheet=None, sprite_width=32, sprite_height=32):
        """
        To add an object to a map:
        map.objects['object name'] = object

        Object states:
        Each state has a name (consider using integers if you want to advance through them sequentially)
        Each state is a dict of properties that the object will update to when state_index is changed to that state name
        Ensure that these properties are spelt correctly!
        To change state elsewhere, just set object.state_index = <state_name_here>, properties will automatically update

        Flair:
        Flair is a dict of 'name': (surface, position (relative to object centre)) to additionally render attached to sprite
        E.g. Hats, speech bubbles.

        Collision:
        Each object has a collision_weight.
        Objects can only push objects with equal or less weight.
        Objects can only push a chain of objects up to their own weight.
        If an objects' collision weight is 0, it does not collide with objects.
        Collision rectangle updates automatically if you change obj dimensions (or coord).
        """
        self.game_class = game_class

        self.states = {'state1': {'max_speed': 1, 'fear_radius': 50},
                       'state2': {'max_speed': 5, 'fear_radius': 150}}
        self._state_index = 'state1'

        self._coord = (x, y)  # top left
        self._dimensions = (w, h)
        self.velocity = (0, 0)
        self.min_speed = 0
        self.current_speed = 0
        self.normal_speed = 0
        self.feared_speed = 0
        self.fear_radius = 50
        self.scared_of = []
        self.fears = FearsList(self)
        self.rect = rect.Rect(self.coord, self.dimensions)
        self.update_timer = 40
        self.fear_timer = 0
        self.scream_timer = 0
        self.fear = 0
        self.scream_thresh = 50

        #variables for animation
        if sprite_sheet is not None:
            self.sprite_sheet_name = sprite_sheet
        else:
            self.sprite_sheet_name = 'DudeSheet.png'
        self.sprite_sheet = image.load(os.path.join(CHARACTERS_DIR, self.sprite_sheet_name))

        # disable texture filtering
        texture = self.sprite_sheet.get_texture()
        gl.glBindTexture(texture.target, texture.id)
        gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
        gl.glBindTexture(texture.target, 0)

        self._animation_state = 0
        self.sprite_height = sprite_height
        self.sprite_width = sprite_width
        self._animations = []
        self._create_animations()
        self.sprite = sprite.Sprite(self._animations[self._animation_state], x=self._coord[0], y=self._coord[1])

        #trigger functions
        self.has_touched_function = []
        self.is_touched_function = []
        self.has_untouched_function = []
        self.is_untouched_function = []

        self.move_up = False
        self.move_down = False
        self.move_left = False
        self.move_right = False

        self.highlight_radius = 20

        self.flair = {}
        self.collision_weight = 1  # set to 0 for no collision, can only push things that are lighter, or same weight

        self.cutscene_controlling = []

        self.path = []
Example #13
0
    def movePx(self, x_dir, y_dir):
        self.remove_self_from_touching_list()

        collision = False

        # collide againt map boundaries
        pro_pos = (self.coord[0] + x_dir, self.coord[1] + y_dir)
        pro_rect = rect.Rect(pro_pos, self.dimensions)
        if pro_pos[0] >= 0 and pro_pos[0] + self.dimensions[0] <= LEVEL_WIDTH and \
                        pro_pos[1] >= 0 and pro_pos[1] + self.dimensions[1] <= LEVEL_HEIGHT:
            pass
        else:
            collision = True

        # collision detection against map tiles
        # NOTE: assumes largest object w/ collision is 64x64 (i.e. 2x2 tiles)

        if pro_pos[0] >= 0 and pro_pos[1] >= 0:
            i = pro_pos[0] // TILE_SIZE  # get the index of the lower left tile
            j = pro_pos[1] // TILE_SIZE
        else:
            i = 0
            j = 0

        # check collision against the 9 possible tiles surrounding object
        for ni in range(i, i + 2):
            for nj in range(j, j + 2):
                if 0 <= ni < LEVEL_WIDTH // TILE_SIZE and 0 <= nj < LEVEL_HEIGHT // TILE_SIZE:
                    if self.game_class.map.coll_grid[nj][ni][0]:
                        # pygame.draw.rect(self.game_class.surface, (200, 0, 0), self.rect)
                        # pygame.draw.rect(self.game_class.surface, (0, 200, 0), self.game_class.map.grid[ni][nj].rect)
                        # pygame.display.update()
                        # time.sleep(0.1)
                        # TODO: make collision use (row,col)
                        if pro_rect.colliderect(self.game_class.map.coll_grid[nj][ni][1]):
                            collision = True
                            # print('collision!')

        search_rect = pro_rect.union(self.rect)

        # collision against other objects
        for o in set(self.game_class.object_collision_lookup.candidates_for(search_rect)):
            if not o is self:
                if o.collision_weight and self.collision_weight:  # check if obj collides at all
                    if pro_rect.colliderect(o.rect) and not self.rect.colliderect(o.rect):

                        if 1 + self.collision_weight < o.collision_weight:  # check if obj can be pushed by self
                            collision = True
                        else:  # push object
                            temp = o.collision_weight
                            o.collision_weight = (self.collision_weight - o.collision_weight) or -1  # allows to push chain of objs
                            collision = collision or o.movePx(x_dir, y_dir)  # collsion of self is dependent on whether obj collided
                            o.collision_weight = temp

                        if not (self, o) in self.game_class.touching:
                            self.game_class.touching.append((self, o))  # (toucher, touchee)

        if not collision:
            self.coord = pro_pos

        return collision
Example #14
0
 def dimensions(self, new):
     self._dimensions = new
     self.rect = rect.Rect(self.coord, self.dimensions)
Example #15
0
 def coord(self, new):
     self._coord = new
     self.rect = rect.Rect(self.coord, self.dimensions)
     self.sprite.position = new
     self.game_class.object_collision_lookup.update_for(self)