Exemplo n.º 1
0
class TestsViewer():
    def __init__(self, stage, tests):
        self.layer = Layer()
        self.stage = stage
        self.tests = tests
        data = DictClass(load(file('data/common/tests_viewer.yaml')))
        layers = [test.get_layer() for test in tests]
        self.paginator = Paginator(self.stage, layers,
                                   data.get("pagination", None))
        for item in self.stage.create_items_from_yaml(data.other, self):
            self.layer.add(item)

    def handle_confirm(self, item, args):
        failed = 0
        for test in self.tests:
            if not test.check():
                failed += 1
        if failed:
            fail_dialog = Fail(self.stage, failed)
            fail_dialog.start()
        else:
            self.stop()
            win = Win(self.stage)
            win.start()

    def handle_close(self, item, args):
        self.stop()

    def exit(self):
        self.paginator.exit()
        self.paginator = None
        self.stage = None
        self.layer.exit()
        self.layer = None
        for test in self.tests:
            test.exit()
        self.tests = None

    def stop(self):
        for layer in self.paginator.get_layers():
            self.stage.remove_layer(layer)
        self.stage.close_dialog(self.layer)

    def start(self):
        self.stage.show_dialog(self.layer, None)
        for layer in self.paginator.get_layers():
            self.stage.add_layer(layer)
Exemplo n.º 2
0
class Intro:
    def __init__(self, stage, data, next_cb):
        self.next_cb = next_cb
        self.layer = Layer()
        self.stage = stage
        self.layer.add(stage.create_image(data.intro)[0])
        self.layer.add(stage.create_button(data.next, self)[0])

    def stop(self):
        self.stage.close_dialog(self.layer)

    def start(self):
        self.stage.show_dialog(self.layer, None)

    def handle_next(self, *args, **kwargs):
        self.stop()
        self.next_cb()
        self.next_cb = None
        self.layer.exit()
        self.stage = None
Exemplo n.º 3
0
class Paginator():
    def __init__(self, stage, items, optional_data=None):
        self.layer = Layer()
        self.items_layer = Layer()
        self.items = items
        self.stage = stage
        from yaml import load
        data = load(file('data/common/pagination.yaml'))
        if optional_data is not None:
            data.update(optional_data)
        self.current = 1
        if len(self.items):
            self.current_layer = self.items[0]
        else:
            self.current_layer = Layer()
        self.min = 1
        self.max = len(self.items)
        self.count = len(self.items)
        for item in items:
            item.set_visible(False)
        self.previous = stage.create_button(data["previous"], self)[0]
        self.next = stage.create_button(data["next"], self)[0]
        self.last = None
        if "last" in data:
            self.last = stage.create_button(data["last"], self)[0]
        if "page_count" in data and data["page_count"]:
            self.page_count_text = stage.create_text(data["page_count"])[0]
            self.page_count_base_text = data["page_count"]["text"]
        else:
            self.page_count_text = None
        self.update_page_count()
        self.update_items()
        self.update_buttons()

        self.layer.add(self.previous)
        self.layer.add(self.next)
        if self.page_count_text:
            self.layer.add(self.page_count_text)
        if self.last:
            self.layer.add(self.last)

    def exit(self):
        self.layer.exit()
        self.items_layer.exit()
        for item in self.items:
            item.exit()
        self.items = None
        self.stage = None
        self.previous.exit()
        self.previous = None
        self.next.exit()
        self.next = None
        if self.last:
            self.last.exit()
            self.last = None
        if self.page_count_text:
            self.page_count_text.exit()
            self.page_count_text = None

    def update_page_count(self):
        if self.page_count_text:
            self.page_count_text.set_text(self.page_count_base_text % {
                "page": self.current,
                "total": self.max
            })

    def update_items(self):
        self.current_layer.set_visible(False)
        if len(self.items) > 0:
            self.current_layer = self.items[self.current - 1]
        self.current_layer.set_visible(True)

    def update_buttons(self):
        if self.current > self.min:
            self.previous.set_visible(True)
        else:
            self.previous.set_visible(False)
        if self.current < self.max:
            self.next.set_visible(True)
        else:
            self.next.set_visible(False)
        if self.last:
            if self.current == self.max:
                self.last.set_visible(False)
            else:
                self.last.set_visible(True)

    def handle_previous(self, item, args):
        if self.current > self.min:
            self.current -= 1
        self.update_buttons()
        self.update_page_count()
        self.update_items()

    def handle_next(self, item, args):
        if self.current < self.max:
            self.current += 1
        self.update_buttons()
        self.update_page_count()
        self.update_items()

    def get_current(self):
        return self.current

    def go_to(self, current):
        if current < self.max:
            self.current = current
        else:
            self.current = current
        self.update_buttons()
        self.update_page_count()
        self.update_items()

    def go_to_last(self):
        self.current = self.max
        self.update_buttons()
        self.update_page_count()
        self.update_items()

    def handle_go_to_last(self, item, args):
        self.go_to_last()

    def get_layers(self):
        return [self.layer] + self.items
Exemplo n.º 4
0
class BackPack:
    ITEMS_PER_PAGE = 5

    def __init__(self, stage, elements):
        self.stage = stage
        self.layer = Layer()
        self.elements_layer = Layer()
        from yaml import load
        data = load(file('data/common/backpack.yaml'))
        self.elements = elements
        self.close_button = stage.create_button(data["close"], self)[0]
        self.next_button = stage.create_button(data["next"], self)[0]
        self.previous_button = stage.create_button(data["previous"], self)[0]
        self.description_text = stage.create_text(data["description"])[0]
        self.element_count_text = stage.create_text_count(
            data["element_count"], len(elements))[0]
        self.previous_button.set_visible(False)
        self.current_page = 0
        self.create_elements(data, elements)
        if len(elements) <= self.ITEMS_PER_PAGE:
            self.next_button.set_visible(False)
        self.set_elements()

        self.other = stage.create_items_from_yaml(data["other"])
        for other in self.other:
            self.layer.add(other)
        self.layer.add(self.close_button)
        self.layer.add(self.next_button)
        self.layer.add(self.previous_button)
        self.layer.add(self.description_text)
        self.layer.add(self.element_count_text)
        self.current_items = []

    def create_elements(self, data, elements):
        self.elements = []
        start_top = data["elements_pos"]["top"]
        inter = data["elements_pos"]["interspace"]
        element_data = DictClass(load(file('data/common/books.yaml')))
        current = 0
        for page in xrange(0, len(elements) / self.ITEMS_PER_PAGE + 1):
            start_left = 0
            for element in elements[page * self.ITEMS_PER_PAGE:(page + 1) *
                                    self.ITEMS_PER_PAGE]:
                element_data[element.type]['action'] = 'click'
                new = self.stage.create_button(element_data[element.type],
                                               manager=self)[0]
                new.set_top(start_top)
                new.set_left(start_left)
                new.add_event_handler(ItemEvent.MOUSE_ENTER,
                                      self.handle_element_enter)
                new.add_event_handler(ItemEvent.MOUSE_LEAVE,
                                      self.handle_element_leave)
                new.info = element
                start_left += new.get_width() + inter
                self.elements.append(new)
                current += 1
            start_left -= inter
            new_left = (data["elements_pos"]["width"] -
                        start_left) / 2 + data["elements_pos"]["left"]
            for element in self.elements[page *
                                         self.ITEMS_PER_PAGE:(page + 1) *
                                         self.ITEMS_PER_PAGE]:
                element.set_left(element.get_left() + new_left)

    def set_elements(self):
        self.elements_layer.empty()
        fromm = self.current_page * self.ITEMS_PER_PAGE
        for element in self.elements[fromm:fromm + self.ITEMS_PER_PAGE]:
            self.elements_layer.add(element)

    def start(self):
        self.stage.show_dialog(self.layer, None)
        self.stage.add_layer(self.elements_layer)

    def handle_close(self, item, args):
        self.stage.remove_layer(self.elements_layer)
        self.stage.close_dialog(self.layer)
        self.layer.exit()
        self.layer = None
        self.close_button.exit()
        self.next_button.exit()
        self.previous_button.exit()
        self.description_text.exit()
        self.element_count_text.exit()
        self.previous_button.exit()
        for element in self.elements:
            element.exit()
        self.elements = None
        self.elements_layer.exit()
        self.elements_layer = None

    def handle_next(self, item, args):
        self.current_page += 1
        if len(
                self.elements
        ) - self.current_page * self.ITEMS_PER_PAGE <= self.ITEMS_PER_PAGE:
            self.next_button.set_visible(False)
        self.previous_button.set_visible(True)
        self.set_elements()

    def handle_previous(self, item, args):
        self.current_page -= 1
        if not self.current_page:
            self.previous_button.set_visible(False)
        if len(self.elements) > self.ITEMS_PER_PAGE:
            self.next_button.set_visible(True)
        self.set_elements()

    def handle_element_enter(self, item, args):
        self.description_text.set_text(item.info.title)

    def handle_element_leave(self, item, args):
        self.description_text.set_text("")

    def handle_click(self, item, args):
        paginate = Content(self.stage, item.info.title, item.info.text)
        paginate.start()
Exemplo n.º 5
0
class Map(GameStage):
    def __init__(self, game):
        GameStage.__init__(self, game)

    INTERVAL = 30

    def initialize(self):
        GameStage.initialize(self)

        self.tests = None
        self.h_key = None
        self.v_key = None
        self.map_character = None
        self.named_layers = None
        self.collisions = None
        self.map_manager = None

        if self.game.datastore.datamodel.current_map_index:
            self.current_map_index = self.game.datastore.datamodel.current_map_index
            self.game.datastore.datamodel.current_map_index = None
        else:
            self.current_map_index = 4

        # Load the sound
        self.street_ambience_sound = assets.load_sound(
            'DGI_street_ambience.ogg')
        self.street_ambience_sound.play(-1)

    def set_up_background(self):
        return

    def load_quadrant(self):
        # remove the character before it gets destroyed
        if self.named_layers and hasattr(self.named_layers, "character"):
            self.named_layers.character.remove(self.map_character.item)
        if self.layers:
            self.remove_layer(self.gui)
        for layer in self.layers:
            layer.exit()
        self.empty_layers()
        data = DictClass(
            load(file('data/map/quadrant_%d.yaml' % self.current_map_index)))
        self.named_layers, layers = self.create_layers(data["layers"])
        self.named_layers.character.add(self.map_character.item)

        if self.game.datastore.datamodel.map_character_left:
            self.map_character.item.set_left(
                self.game.datastore.datamodel.map_character_left)
            self.game.datastore.datamodel.map_character_left = None
        if self.game.datastore.datamodel.map_character_top:
            self.map_character.item.set_top(
                self.game.datastore.datamodel.map_character_top)
            self.game.datastore.datamodel.map_character_top = None

        class Collision():
            def __init__(self, collision_map, trans_x=0, trans_y=0):
                self.collision_map = collision_map
                self.trans_x = trans_x
                self.trans_y = trans_y

            def get_at(self, pos):
                return self.collision_map.get_at(
                    (pos[0] + self.trans_x, pos[1] + self.trans_y))

            def bottom(self):
                return self.collision_map.get_height() - self.trans_y

            def left(self):
                return -self.trans_x

            def right(self):
                return self.collision_map.get_width() - self.trans_x

            def top(self):
                return -self.trans_y

            def exit(self):
                self.collision_map = None

        if "collision" in data:
            if self.collisions:
                for col in self.collisions:
                    col.exit()
            self.collisions = []
            base_data = data.collision.base
            self.collisions.append(
                Collision(assets.load_mask(base_data.src),
                          base_data.get("trans_x", 0),
                          base_data.get("trans_y", 0)))
            if self.game.datastore.datamodel.unlocked_level >= 3:
                self.collisions.append(
                    Collision(assets.load_mask(data.collision.trash.src)))
            if self.game.datastore.datamodel.unlocked_level >= 4:
                self.collisions.append(
                    Collision(assets.load_mask(data.collision.lights.src)))
            if self.game.datastore.datamodel.unlocked_level >= 5 and "vegetation" in data.collision:
                self.collisions.append(
                    Collision(assets.load_mask(data.collision.vegetation.src)))
        else:
            self.collisions = []
        if "entrance" in data:
            self.entrance = assets.load_mask(data.entrance.src)
            to = data.entrance.to
            index = to.rfind(".")
            if (index > 1):
                self.entrance_class = getattr(
                    __import__(to[:index], globals(), locals(),
                               to[index + 1:]), to[index + 1:])
            else:
                self.entrance_class = globals()[to]
        else:
            self.entrance = None
        if self.map_manager:
            self.map_manager.exit()
        self.map_manager = MapManager(self, self.map_character.item,
                                      self.named_layers.character)
        for layer in layers:
            self.add_layer(layer)
        self.add_layer(self.gui)

        # Start processing events after everything is loaded
        self.start_timer(0, self.INTERVAL, self.manage_key)

    def prepare(self):
        data = DictClass(load(file('data/map/common.yaml')))
        self.gui = Layer()
        for item in self.create_items_from_yaml(data.gui):
            self.gui.add(item)
        self.create_selected_map_character(data.character)
        self.load_quadrant()
        self.tests_counter = self.create_text(data.counters.tests)[0]
        self.backpack_counter = self.create_text(data.counters.backpack)[0]
        self.games_counter = self.create_text(data.counters.games)[0]
        self.gui.add(self.tests_counter)
        self.gui.add(self.backpack_counter)
        self.gui.add(self.games_counter)
        self.backpack_counter.set_text(
            str(
                len(self.game.datastore.datamodel.backpack[
                    self.game.datastore.datamodel.level - 1])))
        self.tests_counter.set_text(
            str(
                len(self.game.datastore.levels[
                    self.game.datastore.datamodel.level].tests)))
        self.games_counter.set_text(
            str(self.game.datastore.datamodel.unlocked_level - 1))

    def create_selected_map_character(self, data):
        if not self.map_character:
            character = self.game.datastore.datamodel.character
            params = data[character]
            params['base'] = data.base[character].small
            params["jumping"] = None
            self.map_character = Character(**params)
        return [self.map_character.item]

    def create_buildings(self, data):
        return self.create_items_from_yaml(data["items"])

    def create_background(self, data):
        if self.game.datastore.datamodel.unlocked_level <= 1:
            return self.create_image(data["dirty"])
        else:
            return self.create_image(data["clean"])

    def create_text_tab(self, data):
        args, kwargs = self.text_arguments(data)
        return [ItemTextTab(*args, **kwargs)]

    def create_trash(self, data):
        if self.game.datastore.datamodel.unlocked_level <= 2:
            return self.create_items_from_yaml(data["before"])
        else:
            return self.create_items_from_yaml(data["after"])

    def create_lights(self, data):
        if self.game.datastore.datamodel.unlocked_level <= 3:
            return []
        else:
            return self.create_items_from_yaml(data["items"])

    def create_level_counter(self, data):
        data["src"] = data["src"][self.game.datastore.datamodel.level]
        return self.create_image(data)

    def create_vegetation(self, data):
        if self.game.datastore.datamodel.unlocked_level <= 4:
            return []
        else:
            return self.create_items_from_yaml(data["items"])

    def handle_backpack(self, items, args):
        backpack = BackPack(self, [
            self.game.datastore.contents[content_id]
            for content_id in self.game.datastore.datamodel.backpack[
                self.game.datastore.datamodel.level - 1]
        ])
        backpack.start()

    def handle_exercises(self, item, args):
        if not self.tests:
            tests = []
            for test in self.game.datastore.levels[
                    self.game.datastore.datamodel.level].tests:
                test = self.game.datastore.tests[test]
                if test.type == "multiple":
                    tests.append(
                        MultipleChoice(self, test.title, test.description,
                                       test.options, test.answer))
                elif test.type == "true_false":
                    tests.append(
                        TrueFalse(self, test.title, test.description,
                                  test.options, test.answer))
                elif test.type == "joining":
                    tests.append(
                        Joining(self, test.title, test.description,
                                test.left_options, test.right_options,
                                map(tuple, test.answer),
                                test.get("visualization", None)))
            self.tests = TestsViewer(self, tests)
        self.tests.start()

    def handle_games(self, item, args):
        games = GamesViewer(self)
        games.start()

    def handle_activity(self, item, args):
        activity = Activity(self)
        activity.start()

    def handle_previous(self, item, args):
        if self.actual_screen == 0:
            from presentation import Presentation
            presentation = Presentation(self.game, 2)
            self.game.set_stage(presentation)
        else:
            self.show_previous_screen()

    def exit(self, other_self):
        GameStage.exit(self, other_self)
        self.gui.exit()
        self.gui = None
        if self.tests:
            self.tests.exit()
        self.tests = None
        self.map_character.exit()
        self.map_character = None
        if self.collisions:
            for col in self.collisions:
                col.exit()
        self.collisions = None
        self.named_layers = None
        self.entrance = None
        if self.map_manager:
            self.map_manager.exit()
            self.map_manager = None

    def handle_back(self, *args, **kwargs):
        dialog = ExitDialog(self, self.on_exit_no)
        self.stop_timer(0)
        dialog.start()

    def on_exit_no(self):
        self.start_timer(0, self.INTERVAL, self.manage_key)

    def handle_next(self, item, args):
        self.show_next_screen()

    def handle_event(self, e):
        if e.type == KEYDOWN:
            if (e.key == K_LEFT or e.key == K_RIGHT):
                self.h_key = e.key
            elif (e.key == K_UP or e.key == K_DOWN):
                self.v_key = e.key
        if e.type == KEYUP:
            if self.h_key == e.key:
                self.h_key = None
            elif self.v_key == e.key:
                self.v_key = None

    def manage_key(self, key, data):
        if self.map_character:
            if not self.h_key and self.v_key == K_UP:
                x = 0
                y = -1
            elif not self.h_key and self.v_key == K_DOWN:
                x = 0
                y = 1
            elif self.h_key == K_LEFT and not self.v_key:
                x = -1
                y = 0
            elif self.h_key == K_RIGHT and not self.v_key:
                x = 1
                y = 0
            elif self.h_key == K_LEFT and self.v_key == K_UP:
                x = -cos(1)
                y = -sin(1)
            elif self.h_key == K_LEFT and self.v_key == K_DOWN:
                x = -cos(1)
                y = sin(1)
            elif self.h_key == K_RIGHT and self.v_key == K_UP:
                x = cos(1)
                y = -sin(1)
            elif self.h_key == K_RIGHT and self.v_key == K_DOWN:
                x = cos(1)
                y = sin(1)
            else:
                x = 0
                y = 0
            r = 4
            x *= r
            y *= r
            self.move_character(x, y)

    def move_character(self, delta_left, delta_top):
        current_map_index = self.current_map_index
        window_width, window_height = self.game.get_window_size()

        character = self.map_character.item
        height = character.get_height()
        width = character.get_width()
        left = character.get_left()
        top = character.get_top()
        new_left = left + delta_left
        new_top = top + delta_top

        if (self.check_entrance(new_left + width / 2, new_top + height)):
            self.game.datastore.datamodel.current_map_index = self.current_map_index
            self.game.datastore.datamodel.map_character_left = self.map_character.item.get_left(
            )
            self.game.datastore.datamodel.map_character_top = self.map_character.item.get_top(
            )
            self.game.set_stage(self.entrance_class(self.game))
            return
        if delta_left or delta_top:
            new_left, new_top = self.check_collition(left + width / 2,
                                                     top + height,
                                                     new_left + width / 2,
                                                     new_top + height)
            new_left -= width / 2
            new_top -= height

        self.map_manager.update()
        if self.current_map_index == 1:
            if new_left < 0:
                new_left = 0
            elif new_left > window_width - width / 2:
                new_left = -width / 2
                self.current_map_index = 2

            if new_top < 0:
                new_top = 0
            elif new_top > window_height - height / 2:
                new_top = -height / 2
                self.current_map_index = 4

        elif self.current_map_index == 2:
            if new_left < -width / 2:
                new_left = window_width - width / 2
                self.current_map_index = 1
            elif new_left > window_width - width:
                new_left = window_width - width

            if new_top < 0:
                new_top = 0
            elif new_top > window_height - height / 2:
                new_top = -height / 2
                self.current_map_index = 3

        elif self.current_map_index == 3:
            if new_left < -width / 2:
                new_left = window_width - width / 2
                self.current_map_index = 4
            elif new_left > window_width - width:
                new_left = window_width - width

            if new_top < -height / 2:
                new_top = window_height - height / 2
                self.current_map_index = 2
            elif new_top > window_height - height:
                new_top = window_height - height

        elif self.current_map_index == 4:
            if new_left < 0:
                new_left = 0
            elif new_left > window_width - width / 2:
                new_left = -width / 2
                self.current_map_index = 3
            if new_top < -height / 2:
                new_top = window_height - height / 2
                self.current_map_index = 1
            elif new_top > window_height - height:
                new_top = window_height - height

        if (left != new_left or top != new_top):
            character.set_left(new_left)
            character.set_top(new_top)
        self.map_character.update(self.INTERVAL, delta_left, delta_top)

        if self.current_map_index != current_map_index:
            self.load_quadrant()

    def check_entrance(self, left, top):
        if self.game.datastore.levels[
                self.game.datastore.datamodel.
                level].place_quadrant != self.current_map_index - 1:
            return False
        entrance = self.entrance
        if not entrance: return False
        c_width = entrance.get_width()
        c_height = entrance.get_height()
        return left >= 0 and top >= 0 and left < c_width and top < c_height \
            and entrance.get_at((int(left), int(top))) == ENTRANCE_COLOR

    def handle_level_change(self):
        if self.game.datastore.datamodel.level < 4:
            from presentation import Presentation
            presentation = Presentation(self.game, 3)
            self.game.datastore.changed_data = True
            self.game.set_stage(presentation)
        else:
            self.game.set_stage(Map(self.game))

    def check_collition_color(self, left, top):
        exists = False
        for collision in self.collisions:
            if left < collision.right() and left >= collision.left() and top < collision.bottom()\
                and top >= collision.top():
                if collision.get_at((left, top)) == COLLISION_COLOR:
                    return True
                exists = True
        return not exists

    def check_collition(self, left, top, new_left, new_top):
        if self.check_collition_color(int(new_left), int(new_top)):
            Dx = float(new_left - left)
            Dy = float(new_top - top)
            left = float(left)
            top = float(top)
            dx = Dx / 4.0
            dy = Dy / 4.0
            n_dx = dy
            n_dy = -dx
            Dx = fabs(Dx)
            Dy = fabs(Dy)
            fdy = fabs(dy)
            fdx = fabs(dx)
            total = sqrt(Dx * Dx + Dy * Dy)
            while total > 0:
                left = left + dx
                top = top + dy
                found = True
                if self.check_collition_color(int(left), int(top)):
                    slide_total = total
                    slide_left = left + n_dx
                    slide_top = top + n_dy
                    found = False
                    while slide_total > 0:
                        if self.check_collition_color(int(slide_left),
                                                      int(slide_top)):
                            slide_left = slide_left + n_dx
                            slide_top = slide_top + n_dy
                            slide_total -= sqrt(n_dx**2 + n_dy**2)
                        else:
                            total = slide_total - sqrt(fdx**2 + fdy**2)
                            left = slide_left
                            top = slide_top
                            found = True
                            break
                    if not found:
                        slide_total = total
                        slide_left = left - n_dx
                        slide_top = top - n_dy
                        while slide_total > 0:
                            if self.check_collition_color(
                                    int(slide_left), int(slide_top)):
                                slide_left = slide_left - n_dx
                                slide_top = slide_top - n_dy
                                slide_total -= sqrt(n_dx**2 + n_dy**2)
                            else:
                                total = slide_total - sqrt(fdx**2 + fdy**2)
                                left = slide_left
                                top = slide_top
                                found = True
                                break
                    if not found:
                        return left - dx, top - dy
                else:
                    Dx -= fdx
                    Dy -= fdy
                    total -= sqrt(fdx**2 + fdy**2)
            return left, top
        return new_left, new_top