Esempio n. 1
0
    def __init__(self, graphics):
        self.__log = get_logger("world")
        self.graphics = graphics
        self.entity_manager = EntityManager(self)
        self.team_manager = TeamManager()
        self.action_manager = ActionManager()

        self.__cfg_header = "header"
        self.__cfg_entities = "entities"
        self.__cfg_map = "map"
        self.__started = False
Esempio n. 2
0
    def handle_event(self, evt, game_events):
        if evt.type == pygame.QUIT or (evt.type == pygame.KEYDOWN
                                       and evt.key == pygame.K_ESCAPE):
            self.consume(evt)
            self._finished = True
            return

        self.frame.handle_event(evt, game_events)

        # if absolutely nothing handled the event, the user has tried to do some kind of interaction
        # with the map itself
        if not self.is_consumed(evt):
            if evt.type == pygame.MOUSEBUTTONDOWN:
                self.consume(evt)
                self.current_mode.on_map_mousedown(evt, pygame.mouse.get_pos())
            elif evt.type == pygame.MOUSEMOTION and pygame.mouse.get_pressed(
            )[0]:
                self.consume(evt)
                self.current_mode.on_map_motion(evt, pygame.mouse.get_pos())

            elif evt.type == pygame.KEYDOWN and evt.key == pygame.K_t:
                # copy level state -> we don't want the actual movement and deaths of entities to be reflected
                # in our copy of the level

                # easiest way to handle this is to serialize our level, then load it rather than some
                # complicated deepcopy incomplementation
                stats = copy.copy(self.level.stats)

                test_level = Level(self.assets, EntityManager.create_default(),
                                   stats)
                test_level.deserialize(self.level.serialize())
                test_level.position = self.level.position

                state_stack.push(
                    PerformanceMeasurement(
                        state_stack, self.game_events,
                        RunLevel(self.game_events, self.assets, test_level,
                                 stats)))

        if evt.type == pygame.MOUSEBUTTONUP:
            self.current_mode.on_map_mouseup(evt, pygame.mouse.get_pos())
Esempio n. 3
0
def main():
    """ 
	The main method. Handles initial startup arguments and sets up the game 
	object

	"""

    entityManager = EntityManager.EntityManager()
    componentManager = ComponentManager.ComponentManager()
    systemManager = SystemManager.SystemManager(entityManager,
                                                componentManager)
    clock = pygame.time.Clock()

    # TODO - create a massive JSON file with data on all entities, including base components and default values
    createPlayer(entityManager, componentManager, systemManager)

    while (True):

        systemManager.update()
        clock.tick(30)

    input("Press the enter key to continue")
Esempio n. 4
0
 def __init__(self):
     super().__init__()
     self.entity_manager = EntityManager()
     self.entity_manager.add(Player(100, 100))
     self.add_bawx(-100, -100, 500, 500)
Esempio n. 5
0
class GameState(State):
    def __init__(self):
        super().__init__()
        self.entity_manager = EntityManager()
        self.entity_manager.add(Player(100, 100))
        self.add_bawx(-100, -100, 500, 500)

    def add_phorm(self, px, py, pw):
        self.entity_manager.add(Platform(px, py, pw, 5))

    def add_bawx(self, bx, by, bw, bh):
        self.entity_manager.add(Platform(bx, by, bw, 5))
        self.entity_manager.add(Platform(bx, by, 5, bh))
        self.entity_manager.add(Platform(bx + bw, by, 5, bh + 5))
        self.entity_manager.add(Platform(bx, by + bh, bw + 5, 5))

    def tick(self):
        self.entity_manager.tick(self)

    def draw(self, screen):
        self.entity_manager.draw(screen)
Esempio n. 6
0
class World(object):  # pylint: disable=R0902
    """Stores the information about the environment and terrain"""
    def __init__(self, graphics):
        self.__log = get_logger("world")
        self.graphics = graphics
        self.entity_manager = EntityManager(self)
        self.team_manager = TeamManager()
        self.action_manager = ActionManager()

        self.__cfg_header = "header"
        self.__cfg_entities = "entities"
        self.__cfg_map = "map"
        self.__started = False

    def start(self):
        """Initializes or restart the World values"""
        if self.__started:
            return
        self.entity_manager.start()
        self.team_manager.start()
        self.action_manager.start()

        self.redraw_map = True
        self.redraw_minimap = True
        self.map = []
        self.map_name = None
        self.set_folder(MAP_FOLDER)
        self.__queue_map = deque()
        self.__queue_minimap = deque()
        self.__started = True

    def close(self):
        """Called when the World is asked to close"""
        if not self.__started:
            return
        self.entity_manager.close()
        self.team_manager.close()
        self.action_manager.close()

        self.map = None
        self.map_name = None
        self.__folder = None
        self.__queue_map = None
        self.__queue_minimap = None
        self.__started = False

    def restart(self):
        """Restarts the world"""
        self.close()
        self.start()

    def update(self):
        """Sends the update call to entity manager and the rest of systems"""
        if self.__started:
            self.entity_manager.update()   # Check the deleted entities and propagate the update() call
            self.__action_update()         # Handle the pending actions

    def submit_action(self, action):
        """Called when game related action has ocurred and must be added to action manager"""
        self.action_manager.new_action(action)

    def __action_update(self):
        """Called when we need to handle game actions"""
         # TODO: handle actions when actions code is done
         # for action in self.action_manager:  # Read any pending action
         #    atype = action.type
         #    pass
        pass

    def get_folder(self):
        """Returns the current World load/save folder"""
        return self.__folder

    def set_folder(self, folder):
        """Sets the current World load/save folder"""
        self.__folder = get_base_dir() + sep + folder

    def list(self):
        """Returns the maps in current selected folder"""
        files = {}
        files_names = []
        files_full = []
        folder = self.get_folder()
        check_dir(folder)
        for name in listdir(folder):
            full = folder + sep + name
            if isfile(full):
                files[name] = full
                files_names.append(name)
                files_full.append(full)
        return files, files_names, files_full

    def load(self, filename):
        """Loads the text map data and deserializes entities"""
        self.map_name = filename
        file_path = self.get_folder() + sep + filename
        config = SafeConfigParser()
        if not config.read(file_path):
            raise IOError("Map filename '%s' doesn't exist" % file_path)

         # Get the save header
        s = self.__cfg_header
        version = float(config.get(s, "version"))
        if version != WORLD_VERSION:
            self.__log.warning("Version mismatch, save is %s, and internal version is %s" % (version, WORLD_VERSION))

         # Deserialize and load each entity
        s = self.__cfg_entities
        for uid in config.options(s):
            data = chr_bytes(config.get(s, uid))
            self.entity_manager.deserialize_entity(int(uid), data)

        s = self.__cfg_map
        self.map = []
        for str_x in config.options(s):
            x = int(str_x)
            while len(self.map) <= x:
                self.map.append(None)  # Fill the unnallocated space
            y = config.get(s, str_x)
            self.map[x] = y

        for x, line in enumerate(self.map):
            if line == None:
                raise ParsingError("Missing map line definition at line %s" % x)
        self.redraw_map = True
        self.redraw_minimap = True
        self.__log.info("Loaded world %s" % filename)

    def save(self, filename):
        """Saves the text map and serialized entities"""
        folder = self.get_folder()
        check_dir(folder)
        file_path = folder + sep + filename
        config = SafeConfigParser()

         # Add the save header
        s = self.__cfg_header
        config.add_section(s)
        config.set(s, "version", str(WORLD_VERSION))

         # Serialize and save each entity
        s = self.__cfg_entities
        config.add_section(s)
        for entity in self.entity_manager.get_entities().values():
            uid = entity.get_uid()
            data = self.entity_manager.serialize_entity(uid)
            config.set(s, str(uid), ord_bytes(data))

         # Add the map content
        s = self.__cfg_map
        config.add_section(s)
        for x, y in enumerate(self.map):
            config.set(s, str(x), y)

        cfg_file = open(file_path, "w")
        config.write(cfg_file)
        cfg_file.close()
        self.redraw_map = True
        self.redraw_minimap = True
        self.__log.info("Saved world %s" % filename)

    def get_size(self):
        """Returns the size of the map"""
        sx = len(self.map)
        try:
            sy = len(self.map[0])
        except IndexError:
            sy = 0
        return (sx, sy)

    def get_cell(self, pos):
        """Returns the cell value in the specified position"""
        x, y = pos
        return self.map[x][y]

    def set_cell(self, pos, value):
        """Sets the cell value in the specified position"""
        x, y = pos
        line = self.map[x]
        self.map[x] = line[:y] + value + line[y+1:]

    def draw_cell(self, cell, pos, size):
        """Draws a single cell"""
        color = CELL_COLORS[cell]
        x, y = pos
        self.graphics.draw_rect(color, [ceil(x), ceil(y), ceil(size[0]), ceil(size[1])], 0)

    def draw(self):
        """Draws the map"""
        if len(self.__queue_map):
            return self.draw_map_queue()
        elif not self.redraw_map:
            self.graphics.draw_preset("world-map")
            return False
        else:
            self.redraw_map = False
            size = (WORLD_CELL_SIZE, WORLD_CELL_SIZE)
             # Center the map
            for y, line in enumerate(self.map):
                if line == None: continue
                for x, char in enumerate(line):
                    cell = CELL_TYPES_INVERSE[char]
                    data = (cell, (x, y), size)
                    self.__queue_map.append(data)
            self.graphics.use_preset("world-map")
            self.graphics.draw_fill(COLOR_BLACK)  # Cleans the preset before start drawing
            self.graphics.use_preset(None)
            return self.draw_map_queue()

        self.entity_manager.draw()     # Propagate the draw() call

    def draw_map_queue(self):
        """Handles the queue of cells to be drawed in map, returns if drawing time was exceeded"""
        start_time = time()
        self.graphics.use_preset("world-map")
        exceeded = False
        while not exceeded:
            if len(self.__queue_map) == 0:
                break
            elif time() - start_time > MAP_DRAW_TIME:
                exceeded = True
            else:
                cell, pos, size = self.__queue_map.pop()
                self.draw_minicell(cell, pos, size)
        self.graphics.use_preset(None)
        return exceeded

    def draw_minicell(self, cell, pos, size):
        """Draws a single pixel cell"""
        color = CELL_COLORS[cell]
        x, y = pos
        if (size[0] < 1 or size[1] < 1) and self.graphics.get_implementation() == "pygame":
            self.graphics.draw_circle(color, [int(ceil(x)), int(ceil(y))], 0, 0)
        else:
            self.graphics.draw_rect(color, [ceil(x), ceil(y), ceil(size[0]), ceil(size[1])], 0)

    def draw_minimap(self, rect):   # pylint: disable=R0914
        """Draws the minimap, returns if drawing didn't finished"""
        if len(self.__queue_minimap):
            return self.draw_minimap_queue()
        elif not self.redraw_minimap:
            self.graphics.draw_preset("world-minimap", rect)
            return False
        else:
            self.redraw_minimap = False
            self.graphics.use_preset("world-minimap")
            self.graphics.draw_fill(COLOR_BLACK)  # Cleans the preset before start drawing
            self.graphics.use_preset(None)
            mx, my = self.get_size()
            if mx == 0 or my == 0:
                return True  # Not loaded
            px, py, sx, sy = rect
            sx, sy = sx - 2, sy - 2
            biggest = float(max(mx, my))
            smallest = min(mx, my)
            cell_size = (sx / biggest, sy / biggest)
             # Center the minimap
            bx = px + (((mx - smallest) / 2.0) * cell_size[0])
            by = py + (((my - smallest) / 2.0) * cell_size[1])
            for y, line in enumerate(self.map):
                if line == None: continue
                for x, char in enumerate(line):
                    cell = CELL_TYPES_INVERSE[char]
                    data = (cell, (bx + (x * cell_size[0]), by + (y * cell_size[1])), cell_size)
                    self.__queue_minimap.append(data)
            return True

    def draw_minimap_queue(self):
        """Handles the queue of cells to be drawed in minimap, returns if drawing time was exceeded"""
        start_time = time()
        self.graphics.use_preset("world-minimap")
        exceeded = False
        while not exceeded:
            if len(self.__queue_minimap) == 0:
                break
            elif time() - start_time > MINIMAP_DRAW_TIME:
                exceeded = True
            else:
                cell, pos, size = self.__queue_minimap.pop()
                self.draw_minicell(cell, pos, size)
        self.graphics.use_preset(None)
        return exceeded

    def started(self):
        """Returns the started flag"""
        return self.__started
Esempio n. 7
0
import time
from sys import stdin

import ids
from barfly import BarFly
from entities import EntityManager
from messages import MessageDispatcher
from miner import Miner
from minerswife import MinersWife

entities = EntityManager()
messages = MessageDispatcher(entities)

entities.register(Miner(messages, ids.MINER))
entities.register(MinersWife(messages, ids.ELSA))
entities.register(BarFly(messages, ids.BAR_FLY))

while True:
    for i in range(10):
        [e.update() for e in entities]
        time.sleep(1)
        messages.dispatch_delayed_messages()
    print("Enter to continue")
    stdin.readline()
Esempio n. 8
0
    def __init__(self, assets):
        super().__init__()

        self.assets = assets  # type: AssetManager
        self.entity_manager = EntityManager(
            [constants.Interface],
            [constants.Interface])  # own manager for interface

        # create a level to edit
        self.level = Level(assets, EntityManager.create_editor(),
                           Statistics(Labels()))

        # shim to create a callback before UI draws
        self.entity_manager.register(_ModeDrawHelper(self.on_pre_ui_draw))

        # frame to contain all other windows
        self.frame = Frame(make_vector(0, 0), config.screen_rect.size)
        self.entity_manager.register(self.frame)

        # scrollbars to move map
        self.scroll_map_horizontal = create_slider(
            self.assets.gui_atlas,
            make_vector(*config.screen_rect.bottomleft) + make_vector(10, -20),
            config.screen_rect.width - 20,
            0,
            self.level.tile_map.width * self.level.tile_map.tileset.tile_width,
            on_value_changed=bind_callback_parameters(
                self.on_horizontal_scroll),
            thumb=self.assets.gui_atlas.load_static("sb_thumb"),
            thumb_mo=self.assets.gui_atlas.load_static("sb_thumb_light"),
            sb_type=ScrollbarType.HORIZONTAL)

        self.scroll_map_vertical = create_slider(
            self.assets.gui_atlas,
            make_vector(*config.screen_rect.topright) + make_vector(-20, 10),
            config.screen_rect.height - 40,
            0,
            self.level.tile_map.height *
            self.level.tile_map.tileset.tile_height,
            on_value_changed=bind_callback_parameters(self.on_vertical_scroll),
            thumb=self.assets.gui_atlas.load_static("sb_thumb"),
            thumb_mo=self.assets.gui_atlas.load_static("sb_thumb_light"),
            sb_type=ScrollbarType.VERTICAL)

        self.frame.add_child(self.scroll_map_horizontal)
        self.frame.add_child(self.scroll_map_vertical)

        # ... the various dialogs used by editor
        self.entity_tool_dialog = EntityToolDialog(self.assets.gui_atlas)
        self.frame.add_child(self.entity_tool_dialog)

        self.tile_dialog = TilePickerDialog(self.assets)
        self.frame.add_child(self.tile_dialog)

        self.config_dialog = LevelConfigDialog(self.level,
                                               self.assets.gui_atlas)
        self.frame.add_child(self.config_dialog)

        self.entity_dialog = EntityPickerDialog(self.level)
        self.frame.add_child(self.entity_dialog)

        self.entity_tools = EntityToolDialog
        # editor states to handle relevant actions
        self.current_mode = None

        self.place_mode = PlaceMode(self.tile_dialog, self.level)
        self.passable_mode = PassableMode(self.level)
        self.config_mode = ConfigMode()
        self.entity_mode = EntityMode(self.entity_dialog,
                                      self.entity_tool_dialog, self.level)

        self.set_mode(self.place_mode)

        self.mode_dialog = ModeDialog(
            self.assets.gui_atlas,
            on_tile_mode_callback=bind_callback_parameters(
                self.set_mode, self.place_mode),
            on_passable_mode_callback=bind_callback_parameters(
                self.set_mode, self.passable_mode),
            on_config_mode_callback=bind_callback_parameters(
                self.set_mode, self.config_mode),
            on_entity_mode_callback=bind_callback_parameters(
                self.set_mode, self.entity_mode))

        self.frame.add_child(self.mode_dialog)

        self._finished = False
Esempio n. 9
0
class EditorState(GameState, EventHandler):
    def __init__(self, assets):
        super().__init__()

        self.assets = assets  # type: AssetManager
        self.entity_manager = EntityManager(
            [constants.Interface],
            [constants.Interface])  # own manager for interface

        # create a level to edit
        self.level = Level(assets, EntityManager.create_editor(),
                           Statistics(Labels()))

        # shim to create a callback before UI draws
        self.entity_manager.register(_ModeDrawHelper(self.on_pre_ui_draw))

        # frame to contain all other windows
        self.frame = Frame(make_vector(0, 0), config.screen_rect.size)
        self.entity_manager.register(self.frame)

        # scrollbars to move map
        self.scroll_map_horizontal = create_slider(
            self.assets.gui_atlas,
            make_vector(*config.screen_rect.bottomleft) + make_vector(10, -20),
            config.screen_rect.width - 20,
            0,
            self.level.tile_map.width * self.level.tile_map.tileset.tile_width,
            on_value_changed=bind_callback_parameters(
                self.on_horizontal_scroll),
            thumb=self.assets.gui_atlas.load_static("sb_thumb"),
            thumb_mo=self.assets.gui_atlas.load_static("sb_thumb_light"),
            sb_type=ScrollbarType.HORIZONTAL)

        self.scroll_map_vertical = create_slider(
            self.assets.gui_atlas,
            make_vector(*config.screen_rect.topright) + make_vector(-20, 10),
            config.screen_rect.height - 40,
            0,
            self.level.tile_map.height *
            self.level.tile_map.tileset.tile_height,
            on_value_changed=bind_callback_parameters(self.on_vertical_scroll),
            thumb=self.assets.gui_atlas.load_static("sb_thumb"),
            thumb_mo=self.assets.gui_atlas.load_static("sb_thumb_light"),
            sb_type=ScrollbarType.VERTICAL)

        self.frame.add_child(self.scroll_map_horizontal)
        self.frame.add_child(self.scroll_map_vertical)

        # ... the various dialogs used by editor
        self.entity_tool_dialog = EntityToolDialog(self.assets.gui_atlas)
        self.frame.add_child(self.entity_tool_dialog)

        self.tile_dialog = TilePickerDialog(self.assets)
        self.frame.add_child(self.tile_dialog)

        self.config_dialog = LevelConfigDialog(self.level,
                                               self.assets.gui_atlas)
        self.frame.add_child(self.config_dialog)

        self.entity_dialog = EntityPickerDialog(self.level)
        self.frame.add_child(self.entity_dialog)

        self.entity_tools = EntityToolDialog
        # editor states to handle relevant actions
        self.current_mode = None

        self.place_mode = PlaceMode(self.tile_dialog, self.level)
        self.passable_mode = PassableMode(self.level)
        self.config_mode = ConfigMode()
        self.entity_mode = EntityMode(self.entity_dialog,
                                      self.entity_tool_dialog, self.level)

        self.set_mode(self.place_mode)

        self.mode_dialog = ModeDialog(
            self.assets.gui_atlas,
            on_tile_mode_callback=bind_callback_parameters(
                self.set_mode, self.place_mode),
            on_passable_mode_callback=bind_callback_parameters(
                self.set_mode, self.passable_mode),
            on_config_mode_callback=bind_callback_parameters(
                self.set_mode, self.config_mode),
            on_entity_mode_callback=bind_callback_parameters(
                self.set_mode, self.entity_mode))

        self.frame.add_child(self.mode_dialog)

        self._finished = False

    def draw(self, screen):
        screen.fill(self.level.background_color)
        self.level.draw(screen)
        self.entity_manager.draw(screen, self.level.view_rect, False)

    def set_mode(self, new_mode):
        if new_mode is self.place_mode:
            # turn on/off relevant dialogs
            self.tile_dialog.enabled = True
            self.entity_tool_dialog.enabled = False
            self.config_dialog.enabled = False
            self.entity_dialog.enabled = False
        elif new_mode is self.passable_mode:
            self.tile_dialog.enabled = False
            self.entity_tool_dialog.enabled = False
            self.config_dialog.enabled = False
            self.entity_dialog.enabled = False
        elif new_mode is self.config_mode:
            self.tile_dialog.enabled = False
            self.entity_tool_dialog.enabled = False
            self.config_dialog.enabled = True
            self.entity_dialog.enabled = False
        elif new_mode is self.entity_mode:
            self.tile_dialog.enabled = False
            self.entity_tool_dialog.enabled = True
            self.config_dialog.enabled = False
            self.entity_dialog.enabled = True
        else:
            raise NotImplementedError  # unknown mode

        self.current_mode = new_mode

    def update(self, dt):
        self.entity_manager.update(dt, self.level.view_rect, False)

    @property
    def finished(self):
        return self._finished

    def on_pre_ui_draw(self, screen):
        self.current_mode.draw(screen)

    def activated(self):
        self.game_events.register(self)

    def deactivated(self):
        self.game_events.unregister(self)

    def handle_event(self, evt, game_events):
        if evt.type == pygame.QUIT or (evt.type == pygame.KEYDOWN
                                       and evt.key == pygame.K_ESCAPE):
            self.consume(evt)
            self._finished = True
            return

        self.frame.handle_event(evt, game_events)

        # if absolutely nothing handled the event, the user has tried to do some kind of interaction
        # with the map itself
        if not self.is_consumed(evt):
            if evt.type == pygame.MOUSEBUTTONDOWN:
                self.consume(evt)
                self.current_mode.on_map_mousedown(evt, pygame.mouse.get_pos())
            elif evt.type == pygame.MOUSEMOTION and pygame.mouse.get_pressed(
            )[0]:
                self.consume(evt)
                self.current_mode.on_map_motion(evt, pygame.mouse.get_pos())

            elif evt.type == pygame.KEYDOWN and evt.key == pygame.K_t:
                # copy level state -> we don't want the actual movement and deaths of entities to be reflected
                # in our copy of the level

                # easiest way to handle this is to serialize our level, then load it rather than some
                # complicated deepcopy incomplementation
                stats = copy.copy(self.level.stats)

                test_level = Level(self.assets, EntityManager.create_default(),
                                   stats)
                test_level.deserialize(self.level.serialize())
                test_level.position = self.level.position

                state_stack.push(
                    PerformanceMeasurement(
                        state_stack, self.game_events,
                        RunLevel(self.game_events, self.assets, test_level,
                                 stats)))

        if evt.type == pygame.MOUSEBUTTONUP:
            self.current_mode.on_map_mouseup(evt, pygame.mouse.get_pos())
            # don't consume this event

    def on_horizontal_scroll(self, new_val):
        existing = self.level.position
        existing.x = new_val
        self.level.position = existing

        self.scroll_map_horizontal.max_value = self.level.tile_map.width * self.level.tile_map.tile_width

    def on_vertical_scroll(self, new_val):
        existing = self.level.position
        existing.y = new_val
        self.level.position = existing

        self.scroll_map_vertical.max_value = self.level.tile_map.height * self.level.tile_map.height