Exemplo n.º 1
0
    def keyDown(self, list_entities):
        """
        Sets the current active menu object to inactive and then selects
        the next element in down direction to active.
        If no element is found, it spins around and selects the topmost
        element as active.
        Very similar to keyUp, just different direction when searching.
        @list_entities: list including entities to be processed.
        """
        # Find current active entity
        for entity in list_entities:
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)
            if state_comp.state == "active":
                active_entity = entity
                break

        # Get current location of active entity
        position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
        active_x, active_y = helper.xyToPygame(position_comp.x, position_comp.y)

        # Set current active button to inactive
        state_comp.state = "inactive"

        # Search the next button (top direction)
        active_y += 1
        new_entity = None
        possible_entities = []
        break_loop = False
        # First of all search for all possible entities
        for i in range(active_y, WIN_HEIGHT, 1):
            for entity in list_entities:
                position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
                x, y = helper.xyToPygame(position_comp.x, position_comp.y)
                if y == i:
                    possible_entities.append(entity)
                    break_loop = True
            if break_loop:
                break

        # If we didn't find any entity, the before button is set to active again
        if not possible_entities:
            state_comp.state = "active"
            return

        # If we did in fact find any new entity, select the one who is nearer
        # at a height level
        distances = []
        for entity in possible_entities:
            position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
            x, y = helper.xyToPygame(position_comp.x, position_comp.y)
            distances.append((x - active_x) ** 2)
        distances = list(enumerate(distances))  # add enumeration from 0 to n
        distances.sort(key=lambda x: x[1])  # sort by distance from less to high
        n = distances[0][0]  # select the enumeration of the first element after sorting
        new_entity = possible_entities[n]  # the new entity will be the nearest one

        # Mark the found entity as active
        state_comp = self.entity_manager.getComponent(new_entity, StateComponent.__name__)
        state_comp.state = "active"
Exemplo n.º 2
0
    def keyLeft(self, list_entities):
        """
        Setlects the left button in position to the actual active button if that's
        possible, else the current button remains active.
        @list_entities: list including entities to be processed.
        """
        # Find current active entity
        for entity in list_entities:
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)
            if state_comp.state == "active":
                active_entity = entity
                break

        # Get current location of active entity
        position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
        active_x, active_y = helper.xyToPygame(position_comp.x, position_comp.y)

        # Set current active button to inactive
        state_comp.state = "inactive"

        # Search the next button (top direction)
        active_x -= 1
        new_entity = None
        possible_entities = []
        break_loop = False
        # First of all search for all possible entities
        for i in range(active_x, 0, -1):
            for entity in list_entities:
                position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
                x, y = helper.xyToPygame(position_comp.x, position_comp.y)
                if x == i:
                    possible_entities.append(entity)
                    break_loop = True
            if break_loop:
                break

        # If we didn't find any entity, the before button is set to active again
        if not possible_entities:
            state_comp.state = "active"
            return

        # If we did in fact find any new entity, select the one who is nearer
        # at a height level
        distances = []
        for entity in possible_entities:
            position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
            x, y = helper.xyToPygame(position_comp.x, position_comp.y)
            distances.append((y - active_y) ** 2)
        distances = list(enumerate(distances))  # add enumeration from 0 to n
        distances.sort(key=lambda x: x[1])  # sort by distance from less to high
        n = distances[0][0]  # select the enumeration of the first element after sorting
        new_entity = possible_entities[n]  # the new entity will be the nearest one

        # Mark the found entity as active
        state_comp = self.entity_manager.getComponent(new_entity, StateComponent.__name__)
        state_comp.state = "active"
Exemplo n.º 3
0
    def createObstructor(self, x, y, width, height):
        """
        @x, y: real coordinates (will be translated)
        """
        new_entity = self.entity_manager.createEntity()

        pyg_x, pyg_y = helper.xyToPygame(x, y) 
        rect = pygame.Rect(pyg_x, pyg_y, width, height)

        new_position_component = PositionComponent(x, y, rect)

        self.entity_manager.addComponent(new_entity, new_position_component)

        self.group_manager.add(new_entity, 'obstructor')
        return new_entity
Exemplo n.º 4
0
    def update(self):
        # Get hero entity
        hero = self.group_manager.get('hero')[0]

        # Get camera entity
        camera = self.group_manager.get('camera')[0]

        # Get components
        hero_pos_comp = self.entity_manager.getComponent(hero, PositionComponent.__name__)
        hero_state_comp = self.entity_manager.getComponent(hero, StateComponent.__name__)
        camera_pos_comp = self.entity_manager.getComponent(camera, PositionComponent.__name__)

        # Get level info component
        level_info = self.group_manager.get('level_info')[0]
        level_info_comp = self.entity_manager.getComponent(level_info, LevelInfoComponent.__name__)

        # Check if hero has got to the final of the level
        end = level_info_comp.player_finish
        x, y = helper.xyToPygame(end[0], end[1])
        x -= camera_pos_comp.x
        y += camera_pos_comp.y

        if hero_pos_comp.rect.collidepoint(x, y):
            hero_state_comp.state = 'win'

        # Iterate over those components that have physics component.
        # If they no longer have body or shape, delete them.
        entity_list = self.entity_manager.getEntitiesHavingComponent(PhysicsComponent.__name__)
        for entity in entity_list:
            physics_comp = self.entity_manager.getComponent(entity, PhysicsComponent.__name__)
            if physics_comp.shape.group == REMOVE_GROUP:
                self.group_manager.removeCompletely(entity)
                self.entity_manager.removeEntity(entity)


        # Check music status
        # if self.first_time:
        #     pygame.mixer.music.stop()
        #     level_name = level_info_comp.level_name
        #     pygame.mixer.music.load(MUSIC_MAP[level_name])
        #     pygame.mixer.music.play(-1, 0.0)
            
            
                    


        # Indicate that we have, at least, updated the system once
        self.first_time = False
Exemplo n.º 5
0
    def update(self):
        list_entities = self.entity_manager.getEntitiesHavingComponents(
                                                PositionComponent.__name__,
                                                StateComponent.__name__
                                            )

        # Search if any element is active
        active = False
        for entity in list_entities:
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)
            if state_comp.state == 'active':
                active = True
                break

        # If we can't find any active element, we force the topmost to be active
        if active:
            return
        try:            
            for height in range(WIN_HEIGHT):
                for entity in list_entities:
                    position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
                    x, y = helper.xyToPygame(position_comp.x, position_comp.y)
                    if y == height:
                        raise FoundException()
        except FoundException:
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)
            state_comp.state = 'active'

        # Manage sound
        # The first time we are on this system, we stop the music and play the
        # menu music.
        if self.first_time:
            if not pygame.mixer.music.get_busy():
                pygame.mixer.music.stop()
                pygame.mixer.music.load(MENU_MUSIC)
                pygame.mixer.music.play(-1, 0.0)

        self.first_time = False
Exemplo n.º 6
0
    def update(self):
        #### JUST FOR DEBUG PURPOSES
        level_info = self.group_manager.get('level_info')[0]
        level_info_comp = self.entity_manager.getComponent(level_info, LevelInfoComponent.__name__)
        ####

        # Get all the lights
        list_entities = self.entity_manager.getEntitiesHavingComponents(
                                                    LightComponent.__name__
                                                )

        # Get the camera information
        camera = self.group_manager.get('camera')[0]
        camera_pos_component = self.entity_manager.getComponent(camera, PositionComponent.__name__)
        camera_x = camera_pos_component.x
        camera_y = camera_pos_component.y

        # Get hero's information
        hero = self.group_manager.get('hero')[0]
        hero_pos_comp = self.entity_manager.getComponent(hero, PositionComponent.__name__)
        hero_state_comp = self.entity_manager.getComponent(hero, StateComponent.__name__)

        # Populate a list of the obstructors only if it's the first time we're
        # updating the system
        obstructors = []
        if self.first_time:
            if self.group_manager.doesGroupExist('obstructor'):
                list_obstructors = self.group_manager.get('obstructor')            
                for obstructor in list_obstructors:
                    position_comp = self.entity_manager.getComponent(obstructor,
                                                        PositionComponent.__name__)
                    x, y = helper.xyToPygame(position_comp.x, position_comp.y)
                    # x = x - camera_x
                    # y = y + camera_y 
                    position_comp.rect.topleft = (x, y)
                    obstructors.append(position_comp.rect)

        # Create a list for temporal (auxiliar) obstructors
        auxiliar_obstructors = []
        # Add the dynamic obstructors to that list
        if self.group_manager.doesGroupExist('dynamic_obstructor'):
            list_obstructors = self.group_manager.get('dynamic_obstructor')
            for obstructor in list_obstructors:
                position_comp = self.entity_manager.getComponent(obstructor, PositionComponent.__name__)
                auxiliar_obstructors.append(position_comp.rect)

        # Update the lights
        for entity in list_entities:
            light_comp = self.entity_manager.getComponent(entity, LightComponent.__name__)
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)

            # If mask isn't created, we initiate it
            if light_comp.light.mask is None:
                light_comp.light.createMask()

            # If the light isn't active, don't update it
            if state_comp.state != 'active':
                continue

            # Update position
            x, y = helper.xyToPygame(light_comp.light.x, light_comp.light.y)
            x = x - camera_x
            y = y + camera_y
            light_comp.light.light_rect.center = x, y
            
            # Update obstructors
            if not light_comp.light.obstructors:
                light_comp.light.setObstructors(obstructors)
            if auxiliar_obstructors:
                light_comp.light.setObstructors(auxiliar_obstructors, auxiliar=True)

            ## May need to apply some logic around the update
            ## because it may be computationally intensive.
            ## Currently, we just update if there are any dynamic obstructors and
            ## or we are on the first update
            if self.first_time:
                # Update the constructors with the camera movement
                light_comp.light.updateObstructors(camera_x, camera_y)
                # Update the camera mask
                light_comp.light.update() # Without dynamic objects we will only render the mask once!
            elif auxiliar_obstructors:
                # Update the constructors with the camera movement
                light_comp.light.updateObstructors(camera_x, camera_y)
                # Update the light (update it's mask to be rendered)
                light_comp.light.update()
                ## Only update if the any obstructor is inside the light area
                # for obstructor in auxiliar_obstructors:
                #     if light_comp.light.isRectInsideLight(obstructor, x, y,
                #                                            camera_x, camera_y):
                #         light_comp.light.update()
                #         break

            # Draw the light onto the screen
            light_comp.light.blit(DISPLAYSURF)

            # Hero is in light range -> kill him
            hero_rect = hero_pos_comp.rect
            # print(hero_rect.topleft)
            if light_comp.light.isRectInsideLight(hero_rect, x, y, camera_x, camera_y):
                hero_state_comp.state = 'dead'

            # Clean the auxiliar obstructors
            light_comp.light.cleanAuxiliar()

        # Indicate that we have, at least, updated this system once
        self.first_time = False


        #####
        #####
        ## DEBUG THINGS
        if level_info_comp.debug:
            # draw obstructors
            for entity in list_entities:
                light_comp = self.entity_manager.getComponent(entity, LightComponent.__name__)
                for obstructor in light_comp.light.obstructors + light_comp.light.auxiliar_obstructors:
                    pygame.draw.rect(DISPLAYSURF, BLACK, obstructor, 3)

            # draw light 
            for entity in list_entities:
                # draw rect
                light_comp = self.entity_manager.getComponent(entity, LightComponent.__name__)
                rect = light_comp.light.light_rect
                pygame.draw.rect(DISPLAYSURF, YELLOW, rect, 3)

                # draw middle of rect
                pygame.draw.circle(DISPLAYSURF, BLUE, rect.center, 3)
Exemplo n.º 7
0
    def update(self):
        #### JUST FOR DEBUG PURPOSES
        has_level_info = self.group_manager.doesGroupExist('level_info')
        if has_level_info:
            level_info = self.group_manager.get('level_info')[0]
            level_info_comp = self.entity_manager.getComponent(level_info, LevelInfoComponent.__name__)
        ####

        list_entities = self.entity_manager.getEntitiesHavingComponents(
                            PositionComponent.__name__,
                            RenderComponent.__name__)

        has_camera = self.group_manager.doesGroupExist('camera')
        if has_camera:
            camera_entity = self.group_manager.get('camera')[0]
            camera_position = self.entity_manager.getComponent(camera_entity, PositionComponent.__name__)
            camera_x = camera_position.x
            camera_y = camera_position.y

        for entity in list_entities:
            position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)
            render_comp = self.entity_manager.getComponent(entity, RenderComponent.__name__)

            x,y = helper.xyToPygame(position_comp.x, position_comp.y)
            if has_camera:
                x -= camera_x
                y += camera_y
            position_comp.rect.centerx = x
            position_comp.rect.centery = y
            self.surface.blit(render_comp.sprite, position_comp.rect)







        #####
        #####
        ## DEBUG THINGS
        if not has_level_info:
            return
        if level_info_comp.debug:
            # paint collision
            list_entities = self.group_manager.get('collision')
            for entity in list_entities:
                # collision rectangle
                physics_comp = self.entity_manager.getComponent(entity, PhysicsComponent.__name__)
                shape = physics_comp.shape
                vertices = shape.get_points() 
                x,y = helper.toPygame(vertices[0])
                width = helper.toPygame(vertices[1])[0] - x
                height = y - helper.toPygame(vertices[3])[1]
                x = int(x - camera_x)
                y = int(y + camera_y - height)   
                rect = pygame.Rect(x, y, width, height)
                pygame.draw.rect(DISPLAYSURF, RED, rect, 3) 

                # gravity center
                center = helper.toPygame(physics_comp.body.position)
                center = (int(center[0] - camera_x), int(center[1] + camera_y))
                pygame.draw.circle(DISPLAYSURF, BLUE, center, 3)

            # paint hero center of gravity
            hero = self.group_manager.get('hero')[0]
            physics_comp = self.entity_manager.getComponent(hero, PhysicsComponent.__name__)
            center = helper.toPygame(physics_comp.body.position)
            center = (int(center[0] - camera_x), int(center[1] + camera_y))
            pygame.draw.circle(DISPLAYSURF, BLUE, center, 3)
Exemplo n.º 8
0
    def update(self):
        #### JUST FOR DEBUG PURPOSES
        level_info = self.group_manager.get('level_info')[0]
        level_info_comp = self.entity_manager.getComponent(level_info, LevelInfoComponent.__name__)
        #########

        # Get all entities that have light and pos component
        list_entities = self.entity_manager.getEntitiesHavingComponents(
                                LightComponent.__name__,
                                PositionComponent.__name__,
                                StateComponent.__name__)

        # Get camera information
        camera = self.group_manager.get('camera')[0]
        camera_pos_component = self.entity_manager.getComponent(camera, PositionComponent.__name__)
        camera_x = camera_pos_component.x
        camera_y = camera_pos_component.y

        # Get hero's information
        hero = self.group_manager.get('hero')[0]
        hero_pos_comp = self.entity_manager.getComponent(hero, PositionComponent.__name__)
        hero_state_comp = self.entity_manager.getComponent(hero, StateComponent.__name__)

        # Fill a obstructors list with objects that must block light
        list_obstructors = self.group_manager.get('obstructor')
        obstructors = []
        for obstructor in list_obstructors:
            position_comp = self.entity_manager.getComponent(obstructor, PositionComponent.__name__)
            x, y = helper.xyToPygame(position_comp.x, position_comp.y)
            x = x - camera_x 
            y = y + camera_y 
            position_comp.rect.topleft = (x, y)
            obstructors.append(position_comp.rect)

        # Add dynamic obstructors, such as crates, to the obstructors list
        list_obstructors = self.group_manager.get('dynamic_obstructor')
        for obstructor in list_obstructors:
            position_comp = self.entity_manager.getComponent(obstructor, PositionComponent.__name__)
            obstructors.append(position_comp.rect)

        # Iterate over the light entities and update them
        for entity in list_entities:
            # Get components for current entity
            state_comp = self.entity_manager.getComponent(entity, StateComponent.__name__)            
            light_comp = self.entity_manager.getComponent(entity, LightComponent.__name__)
            position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)

            # If it's not active we just ignore it and continue to the next one
            if state_comp.state != 'active':
                continue

            # Reset the containers and set to the new ones
            light_comp.light.clean()
            light_comp.light.addRectList(obstructors)

            # Get info and adapt it to camera
            x, y = helper.xyToPygame(position_comp.x, position_comp.y)
            x = int(x - camera_x)
            y = int(y + camera_y)
            size = light_comp.size
            
            # Set the border (limit) of the light
            light_comp.light.setBorderWithSize(x, y, size, input = 'pygame')

            # Set position
            light_comp.light.setLightLocation(x, y, input = 'pygame')

            # Run the sweep method (create light triangles)
            light_comp.light.sweep()

            # Finally paint the light onto the screen
            light_comp.light.blit(DISPLAYSURF, light_comp.color, light_comp.alpha)

            # Check if hero is inside the light
            hero_rect = hero_pos_comp.rect
            if light_comp.light.isRectInsideLight(hero_rect):
                hero_state_comp.state = 'dead'




        #####
        #####
        ## DEBUG THINGS
        if level_info_comp.debug:
            # draw obstructors
            for obstructor in obstructors:
                pygame.draw.rect(DISPLAYSURF, BLACK, obstructor, 3)

            # draw light 
            for entity in list_entities:                
                light_comp = self.entity_manager.getComponent(entity, LightComponent.__name__)
                position_comp = self.entity_manager.getComponent(entity, PositionComponent.__name__)

                # draw rect
                x, y = helper.xyToPygame(position_comp.x, position_comp.y)
                x = int(x - camera_x)
                y = int(y + camera_y)
                size = light_comp.size
                pygame.draw.rect(DISPLAYSURF, YELLOW, (x-size//2, y-size//2, size, size), 5)

                # draw light center
                pygame.draw.circle(DISPLAYSURF, RED, (x,y), 5)