예제 #1
0
    def __load_items(self, text, data, top, height):
        self.items = []

        def create_text(stage, next, text, top, height):
            text_item = stage.create_text(data.text)[0]
            text_item.break_text_into(next)
            text_item.set_text(text)
            text_item.set_top(top)
            text_item.set_dimensions(data.text.width, height)
            text_item.break_text_into(None)
            return text_item

        # Usamos una clase que tiene el metodo set_text para saber si hay que dividir el texto
        class Next:
            def __init__(self):
                self.text = None

            def set_text(self, text):
                self.text = text

        next = Next()
        layer = Layer()
        layer.add(create_text(self.stage, next, text, top, height))
        self.items.append(layer)
        while next.text:
            layer = Layer()
            layer.add(create_text(self.stage, next, next.text, top, height))
            self.items.append(layer)
예제 #2
0
    def view_post_web_cb(self, result):
        if result.error:
            self.error_try_again_later()
            return
        data = DictClass(result.data)
        self.layers.view_post.title.set_text(self.title)
        self.layers.view_post.author.set_text(data.author_name + ":")
        # Usamos una clase que tiene el metodo set_text para saber si hay que dividir el texto
        items = []
        next = Next()
        layer = Layer()

        def create_text(stage, next, text, data):
            text_item = stage.create_text(data)[0]
            set_text(next, text, text_item)
            return text_item

        layer.add(
            create_text(self.stage, next, data.text,
                        self.layers.view_post.post.data))
        items.append(layer)
        while next.text:
            layer = Layer()
            layer.add(
                create_text(self.stage, next, next.text,
                            self.layers.view_post.post.data))
            items.append(layer)
        paginator = Paginator(self.stage, items, self.data.pager_post)
        self.change_layer([self.layers.view_post.layer] +
                          paginator.get_layers() + [self.layers.logged.layer])
예제 #3
0
 def create_items(self, data):
     items = DictClass()
     layer = Layer()
     self.stage._items_manager = self
     for i in data:
         item = items[i.name] = self.stage.create_item(i)[0]
         item.data = i
         layer.add(item)
     self.stage._items_manager = None
     items["layer"] = layer
     return items
예제 #4
0
 def create_layers(self, data):
     class ExtraLayers:
         pass
     layers = ExtraLayers()
     layer_list = []
     for layer in data:
         new_layer = Layer()
         layer_list.append(new_layer)
         if "name" in layer:
             setattr(layers, layer["name"], new_layer)
         items = self.create_items_from_yaml(layer["items"])
         if items:
             for item in items:
                 new_layer.add(item)
     return layers, layer_list
예제 #5
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)
예제 #6
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
예제 #7
0
class Content():
    def __init__(self, stage, title, text):
        self.layer = Layer()
        self.stage = stage
        data = DictClass(load(file('data/common/content_viewer.yaml')))
        title_item = self.title_text = stage.create_text(data.title)[0]
        title_item.set_top(data.container.top)
        self.title_text.set_text(title)
        text_top = title_item.get_top() + title_item.get_height() + 10
        text_height = data.container.height - (text_top - data.container.top)
        self.close = stage.create_button(data.close, self)[0]
        self.__load_items(text, data, text_top, text_height)
        self.paginator = Paginator(self.stage, self.items,
                                   data.get("pagination", None))
        for item in self.stage.create_items_from_yaml(data.other):
            self.layer.add(item)
        self.layer.add(self.title_text)
        self.layer.add(self.close)

    def __load_items(self, text, data, top, height):
        self.items = []

        def create_text(stage, next, text, top, height):
            text_item = stage.create_text(data.text)[0]
            text_item.break_text_into(next)
            text_item.set_text(text)
            text_item.set_top(top)
            text_item.set_dimensions(data.text.width, height)
            text_item.break_text_into(None)
            return text_item

        # Usamos una clase que tiene el metodo set_text para saber si hay que dividir el texto
        class Next:
            def __init__(self):
                self.text = None

            def set_text(self, text):
                self.text = text

        next = Next()
        layer = Layer()
        layer.add(create_text(self.stage, next, text, top, height))
        self.items.append(layer)
        while next.text:
            layer = Layer()
            layer.add(create_text(self.stage, next, next.text, top, height))
            self.items.append(layer)

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

    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)
예제 #8
0
class GamesViewer():
    def __init__(self, stage):
        self.layer = Layer()
        self.stage = stage
        data = DictClass(load(file('data/common/games_viewer.yaml')))
        for item in stage.create_items_from_yaml(data.other):
            self.layer.add(item)
        self.close = stage.create_button(data.close, self)[0]
        self.layer.add(self.close)
        quantity = stage.game.datastore.datamodel.unlocked_level - 1
        if quantity == 1:
            data.header['text'] = data.header.singular.pre + str(
                quantity) + data.header.singular.pos
        else:
            data.header['text'] = data.header.plural.pre + str(
                quantity) + data.header.plural.pos
        self.header = stage.create_text(data.header)[0]
        self.layer.add(self.header)
        self.footer = stage.create_text(data.footer)[0]
        for data_game in data.games:
            Game(stage, self.layer, data_game, self.footer)

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

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

    def start(self):
        self.stage.show_dialog(self.layer, None)
예제 #9
0
    def load_items(self, data, items):
        layer = Layer()

        left = self.data.post_box.left
        top = self.data.post_box.top
        cant_items = 0
        i = 0
        for item in data:
            if cant_items >= self.data.post_box.items_per_page:
                items.append(layer)
                layer = Layer()
                top = self.data.post_box.top
                cant_items = 0
            self.stage._items_manager = self
            text_item = self.stage.create_item(self.data.post_item)[0]
            text_item.data_item = item
            text_item.set_top(top)
            text_item.set_left(left)

            def set_post_text(text_item, text):
                next = Next()
                set_text(next, text, text_item)
                if next.text:
                    new_dict = dict(self.data.post_item)
                    new_dict["width"] = -1
                    ellipsis = self.stage.create_item(new_dict)[0]
                    ellipsis.set_text("...")
                    ellipsis.set_top(text_item.get_top())
                    ellipsis.set_left(text_item.get_left() +
                                      text_item.lines[0])
                    return ellipsis
                return None

            def on_enter(text_item, *args, **kwargs):
                item = text_item.data_item
                text_item.set_text("&#c200,0,0!%s&#c!: %s" %
                                   (item.author_name, item.text))

            def on_leave(text_item, *args, **kwargs):
                item = text_item.data_item
                text_item.set_text("&#c58,129,188!%s&#c!: %s" %
                                   (item.author_name, item.text))

            text_item.add_event_handler(ItemEvent.MOUSE_ENTER, on_enter)
            text_item.add_event_handler(ItemEvent.MOUSE_LEAVE, on_leave)
            text_item.add_event_handler(ItemEvent.CLICK,
                                        self.handle_post_click)
            text_item.post_id = item.id
            text_item.post_index = i
            self.stage._items_manager = None
            other_item = set_post_text(
                text_item,
                "&#c58,129,188!%s&#c!: %s" % (item.author_name, item.text))
            if other_item:
                layer.add(other_item)
            layer.add(text_item)
            top += self.data.post_box.inter_line
            cant_items += 1
            i += 1

        if len(layer.items) > 0:
            items.append(layer)
예제 #10
0
class Activity():
    def __init__(self, stage):
        global DEFAULT_NAME, DEFAULT_ROOM

        self.go_to_last = False
        self.dialog = None
        self.paginator = None
        self.background = Layer()
        self.foreground = Layer()
        self.focus_group = FocusGroup()
        self.stage = stage
        self.current_callback = None
        self.current_id = None
        data = self.data = DictClass(load(file('data/common/activity.yaml')))
        self.clock_image = ItemImage(0, 0, assets.load_image(data.clock.src))
        layers = self.layers = DictClass()
        for k, i in data.layers.items():
            layers[k] = self.create_items(i)
        self.layers.main.name_input.set_focus_group(self.focus_group)
        self.layers.main.name_input.set_on_enter(self.handle_next)
        self.layers.main.name_input.set_text(DEFAULT_NAME)
        self.layers.main.room_input.set_focus_group(self.focus_group)
        self.layers.main.room_input.set_on_enter(self.handle_next)
        self.layers.main.room_input.set_text(DEFAULT_ROOM)
        self.current_layers = [layers.main.layer]
        text_box = self.layers.post.text_box = self.create_text_box(
            data.text_box)
        self.layers.post.layer.add(text_box)

        for item in self.stage.create_items_from_yaml(data["background"],
                                                      self):
            self.background.add(item)
        for item in self.stage.create_items_from_yaml(data["foreground"],
                                                      self):
            self.foreground.add(item)

        self.stage.start_timer('msgclock', 15000, self.update_messages_tick)

    def create_items(self, data):
        items = DictClass()
        layer = Layer()
        self.stage._items_manager = self
        for i in data:
            item = items[i.name] = self.stage.create_item(i)[0]
            item.data = i
            layer.add(item)
        self.stage._items_manager = None
        items["layer"] = layer
        return items

    def change_layer(self, new_layers):
        for layer in self.current_layers:
            self.stage.remove_layer(layer)
        self.stage.remove_layer(self.foreground)
        self.current_layers = new_layers
        for layer in self.current_layers:
            self.stage.add_layer(layer)
        self.stage.add_layer(self.foreground)

    def handle_back(self, *args, **kwargs):
        if self.current_callback:
            return
        if self.layers.room.layer in self.current_layers:
            self.change_layer([self.layers.main.layer])
        if self.layers.post.layer in self.current_layers \
            or self.layers.view_post.layer in self.current_layers:
            self.change_layer([self.layers.room.layer] +
                              self.paginator.get_layers() +
                              [self.layers.logged.layer])

    def handle_refresh(self, item, args):
        self.refresh_messages()

    def update_messages_tick(self, key, data):
        if self.paginator != None:
            self.refresh_messages(False)

    def refresh_messages(self, show_clock=True):
        callback = get_web_cb(self, self.refresh_cb, show_clock)
        web.query(WEB_DIR_ACT % self.layers.main.room_input.get_text(),
                  callback=callback)

    @web_callback
    def refresh_cb(self, result):
        if result.error:
            return

        data = [DictClass(item) for item in result.data["posts"]]

        # Check if the data change, only update the screen if changed
        if data != self.posts:
            self.posts = data

            items = []
            self.load_items(self.posts, items)

            current = self.paginator.get_current()
            self.paginator = Paginator(self.stage, items, self.data.pager)
            self.paginator.go_to(current)
            self.change_layer([self.layers.room.layer] +
                              self.paginator.get_layers() +
                              [self.layers.logged.layer])

    def handle_post(self, *args, **kwargs):
        if self.current_callback:
            return
        web.send_data(WEB_DIR_NEW_POST %
                      self.layers.main.room_input.get_text(), {
                          "post[author_name]":
                          unicode(self.layers.main.name_input.get_text(),
                                  "latin-1").encode("utf-8"),
                          "post[machine_id]":
                          "id",
                          "post[text]":
                          unicode(self.layers.post.text_box.get_text(),
                                  "latin-1").encode("utf-8")
                      },
                      callback=get_web_cb(self, self.post_web_cb))

    @web_callback
    def post_web_cb(self, result):
        if result.error:
            self.error_try_again_later()
            return
        self.layers.post.text_box.text("")
        self.go_to_last = True
        self.go_to_room()

    def go_to_room(self):
        if self.current_callback:
            return

        global DEFAULT_NAME, DEFAULT_ROOM
        DEFAULT_NAME = self.layers.main.name_input.get_text()
        DEFAULT_ROOM = self.layers.main.room_input.get_text()

        web.query(WEB_DIR_ACT % self.layers.main.room_input.get_text(),
                  callback=get_web_cb(self, self.go_to_room_web_cb))

    @web_callback
    def go_to_room_web_cb(self, result):
        if result.error:
            if result.error == web.Error.SERVER and result.code == 404:
                self.the_room_doesnt_exist()
            else:
                self.error_try_again_later()
            return

        data = DictClass(result.data)
        self.title = data.title
        self.layers.room.title.set_text(self.title)
        self.layers.room.description.set_text(data.description)
        self.layers.room.code.set_text(self.layers.room.code.data.text %
                                       self.layers.main.room_input.get_text())
        self.layers.logged.login_name.set_text(
            self.layers.main.name_input.get_text())
        data = [DictClass(item) for item in data.posts]
        self.posts = data

        items = []
        self.load_items(data, items)

        self.paginator = Paginator(self.stage, items, self.data.pager)
        if self.go_to_last:
            self.go_to_last = False
            self.paginator.go_to_last()
        self.change_layer([self.layers.room.layer] +
                          self.paginator.get_layers() +
                          [self.layers.logged.layer])

    def load_items(self, data, items):
        layer = Layer()

        left = self.data.post_box.left
        top = self.data.post_box.top
        cant_items = 0
        i = 0
        for item in data:
            if cant_items >= self.data.post_box.items_per_page:
                items.append(layer)
                layer = Layer()
                top = self.data.post_box.top
                cant_items = 0
            self.stage._items_manager = self
            text_item = self.stage.create_item(self.data.post_item)[0]
            text_item.data_item = item
            text_item.set_top(top)
            text_item.set_left(left)

            def set_post_text(text_item, text):
                next = Next()
                set_text(next, text, text_item)
                if next.text:
                    new_dict = dict(self.data.post_item)
                    new_dict["width"] = -1
                    ellipsis = self.stage.create_item(new_dict)[0]
                    ellipsis.set_text("...")
                    ellipsis.set_top(text_item.get_top())
                    ellipsis.set_left(text_item.get_left() +
                                      text_item.lines[0])
                    return ellipsis
                return None

            def on_enter(text_item, *args, **kwargs):
                item = text_item.data_item
                text_item.set_text("&#c200,0,0!%s&#c!: %s" %
                                   (item.author_name, item.text))

            def on_leave(text_item, *args, **kwargs):
                item = text_item.data_item
                text_item.set_text("&#c58,129,188!%s&#c!: %s" %
                                   (item.author_name, item.text))

            text_item.add_event_handler(ItemEvent.MOUSE_ENTER, on_enter)
            text_item.add_event_handler(ItemEvent.MOUSE_LEAVE, on_leave)
            text_item.add_event_handler(ItemEvent.CLICK,
                                        self.handle_post_click)
            text_item.post_id = item.id
            text_item.post_index = i
            self.stage._items_manager = None
            other_item = set_post_text(
                text_item,
                "&#c58,129,188!%s&#c!: %s" % (item.author_name, item.text))
            if other_item:
                layer.add(other_item)
            layer.add(text_item)
            top += self.data.post_box.inter_line
            cant_items += 1
            i += 1

        if len(layer.items) > 0:
            items.append(layer)

    def handle_next(self, *args, **kwargs):
        if self.dialog:
            return
        self.paginator = None
        self.layers.main.name_input.set_text(
            self.layers.main.name_input.get_text().strip())
        self.layers.main.room_input.set_text(
            self.layers.main.room_input.get_text().strip())
        if not self.layers.main.name_input.get_text(
        ) or not self.layers.main.room_input.get_text():
            self.fill_inputs()
            return
        self.go_to_room()

    def handle_next_post(self, *args, **kwargs):
        self.current_post += 1
        self.update_post_buttons()
        web.query(WEB_DIR_POST % (self.layers.main.room_input.get_text(),
                                  self.posts[self.current_post].id),
                  callback=get_web_cb(self, self.view_post_web_cb))

    def handle_previous_post(self, *args, **kwargs):
        self.current_post -= 1
        self.update_post_buttons()
        web.query(WEB_DIR_POST % (self.layers.main.room_input.get_text(),
                                  self.posts[self.current_post].id),
                  callback=get_web_cb(self, self.view_post_web_cb))

    def update_post_buttons(self):
        view_post = self.layers.view_post
        if self.current_post > 0:
            view_post.previous_post.set_visible(True)
        else:
            view_post.previous_post.set_visible(False)
        if self.current_post < len(self.posts) - 1:
            view_post.next_post.set_visible(True)
        else:
            view_post.next_post.set_visible(False)
        view_post.post_count.set_text(self.data.pager.page_count.text % {
            "page": self.current_post + 1,
            "total": len(self.posts)
        })

    def handle_post_click(self, item, *args, **kwargs):
        if self.current_callback:
            return
        self.current_post = item.post_index
        self.update_post_buttons()
        web.query(WEB_DIR_POST %
                  (self.layers.main.room_input.get_text(), item.post_id),
                  callback=get_web_cb(self, self.view_post_web_cb))

    @web_callback
    def post_message_cb(self, result):
        if result.error:
            self.error_try_again_later()
            self.change_layer([self.layers.room.layer] +
                              self.paginator.get_layers() +
                              [self.layers.logged.layer])
            return
        self.go_to_room()

    @web_callback
    def view_post_web_cb(self, result):
        if result.error:
            self.error_try_again_later()
            return
        data = DictClass(result.data)
        self.layers.view_post.title.set_text(self.title)
        self.layers.view_post.author.set_text(data.author_name + ":")
        # Usamos una clase que tiene el metodo set_text para saber si hay que dividir el texto
        items = []
        next = Next()
        layer = Layer()

        def create_text(stage, next, text, data):
            text_item = stage.create_text(data)[0]
            set_text(next, text, text_item)
            return text_item

        layer.add(
            create_text(self.stage, next, data.text,
                        self.layers.view_post.post.data))
        items.append(layer)
        while next.text:
            layer = Layer()
            layer.add(
                create_text(self.stage, next, next.text,
                            self.layers.view_post.post.data))
            items.append(layer)
        paginator = Paginator(self.stage, items, self.data.pager_post)
        self.change_layer([self.layers.view_post.layer] +
                          paginator.get_layers() + [self.layers.logged.layer])

    def handle_new_post(self, *args, **kwargs):
        self.layers.post.title.set_text(self.title)
        self.change_layer([self.layers.post.layer] +
                          [self.layers.logged.layer])
        self.layers.post.text_box.begin()
        pass

    def handle_close(self, item, args):
        self.current_id = None
        self.stage.reset_mouse_cursor()
        self.stop()

    def create_text_box(self, data):
        return TextBox(data.left, data.top, data.width, data.height,
                       getattr(self.stage, data.font), eval(data.color))

    def stop(self):
        for layer in self.current_layers:
            self.stage.remove_layer(layer)
        self.stage.remove_layer(self.foreground)
        self.stage.close_dialog(self.background)
        self.stage.stop_timer('msgclock')

    def start(self):
        self.stage.show_dialog(self.background, None)
        for layer in self.current_layers:
            self.stage.add_layer(layer)
        self.stage.add_layer(self.foreground)
        self.layers.main.room_input.set_editable(True)
        self.layers.main.room_input.set_edit_on_click(
            self.layers.main.room_input)
        self.layers.main.name_input.set_editable(True)
        self.layers.main.name_input.set_edit_on_click(
            self.layers.main.name_input)
        self.layers.main.name_input.begin_edit()

    def on_exit_dialog(self):
        self.dialog = None

    def error_try_again_later(self):
        self.dialog = dialog = ErrorDialog(self.stage, self.on_exit_dialog)
        dialog.set_message(self.data.messages.unknown)
        dialog.start()

    def the_room_doesnt_exist(self):
        self.dialog = dialog = ErrorDialog(self.stage, self.on_exit_dialog)
        dialog.set_message(self.data.messages.no_activity)
        dialog.start()

    def fill_inputs(self):
        self.dialog = dialog = ErrorDialog(self.stage, self.on_exit_dialog)
        dialog.set_message(self.data.messages.fill_inputs)
        dialog.start()
예제 #11
0
class MemoryMinigame(GameStage):
    GO_BACK_TIME = 3000
    ONE_SECOND_INTERVAL = 1000

    def __init__(self, game):
        GameStage.__init__(self, game)

    def initialize(self):
        GameStage.initialize(self)
        stream = file('data/fonts.yaml', 'r')
        fonts = load(stream)
        for font in fonts:
            setattr(
                self, font,
                assets.load_font(fonts[font]['file_name'],
                                 fonts[font]['size']))

        self.data = DictClass(load(file('data/memory.yaml')))

        self.game_over_layer = Layer()
        image = assets.load_image(
            self.data.game_over[self.game.datastore.datamodel.character].src)
        item = ItemImage(self.data.game_over.left, self.data.game_over.top,
                         image)
        self.game_over_layer.add(item)

        self.main_layer = Layer()
        self.top_layer = Layer()

        self.time = self.data.time.max
        self.timer = DictClass({})
        image = assets.load_image(self.data.time.src)
        self.timer['skin'] = ItemImage(self.data.time.left, self.data.time.top,
                                       image)
        self.timer['value'] = ItemText(self.data.time.left,
                                       self.data.time.top,
                                       self.font,
                                       0,
                                       format_time(self.time),
                                       width=image.get_width(),
                                       height=image.get_height(),
                                       h_align=2,
                                       v_align=2)
        self.top_layer.add(self.timer.skin)
        self.top_layer.add(self.timer.value)

        self.score = 0
        self.score_board = DictClass({})
        image = assets.load_image(self.data.score.src)
        self.score_board['skin'] = ItemImage(self.data.score.left,
                                             self.data.score.top, image)
        self.score_board['value'] = ItemText(self.data.score.left,
                                             self.data.score.top,
                                             self.font,
                                             0,
                                             str(self.score),
                                             width=image.get_width(),
                                             height=image.get_height(),
                                             h_align=2,
                                             v_align=2)
        self.top_layer.add(self.score_board.skin)
        self.top_layer.add(self.score_board.value)

        self.deck = []
        image_back = assets.load_image(self.data.board.card_back)
        for k in range(0, len(self.data.board.cards)):
            image = assets.load_image(self.data.board.cards[k])
            self.deck.append([
                Card(self, k, image, image_back),
                Card(self, k, image, image_back)
            ])

        self.range = self.data.start
        self.cards = []
        self.deal()

        # Load the sound
        self.card_flip_sound = assets.load_sound('DGI_card_flip.ogg')
        self.item_found_sound = assets.load_sound('DGI_item_found.ogg')
        self.wrong_sound = assets.load_sound('DGI_wrong.ogg')
        self.lose_bell_sound = assets.load_sound('DGI_lose_bell.ogg')
        self.lose_music_sound = assets.load_sound('DGI_lose_music.ogg')

    def deal(self):
        self.first = None
        self.second = None

        for k in range(0, self.range):
            self.cards.append(self.deck[k][0])
            self.cards.append(self.deck[k][1])
        random.shuffle(self.cards)

        d = ceil(sqrt(2 * self.range))
        for i, card in zip(range(2 * self.range), self.cards):
            card.item.set_left(self.data.board.left + card.item.get_width() *
                               (i % d))
            card.item.set_top(self.data.board.top +
                              card.item.get_height() * int(i / d))
            self.main_layer.add(card.item)

    def select(self, card):
        self.card_flip_sound.play()
        if not self.second:
            if self.first:
                if self.first != card:
                    self.second = card
                    card.select()
                    self.start_timer(1, 500, self.check_match)
            else:
                self.first = card
                card.select()

    def check_match(self, key, data):
        self.stop_timer(1)
        if self.first.key == self.second.key:
            self.item_found_sound.play()
            self.cards.remove(self.first)
            self.cards.remove(self.second)
            self.main_layer.remove(self.first.item)
            self.main_layer.remove(self.second.item)
            self.score += self.data.score.points
            self.score_board.value.set_text(str(self.score))
        else:
            self.wrong_sound.play()
        self.first.unselect()
        self.second.unselect()
        self.first = self.second = None
        if len(self.cards) == 2:
            self.first = self.cards[0]
            self.second = self.cards[1]
            self.first.select()
            self.second.select()
            self.start_timer(1, 500, self.check_match)
        elif not self.cards:
            if self.range + self.data.step <= len(self.deck):
                self.range += self.data.step
            self.deal()

    def prepare(self):
        self.show_board()
        dialog = Intro(self, self.data.intro, self.start_game)
        dialog.start()

    def start_game(self):
        self.start_timer(0, self.ONE_SECOND_INTERVAL, self.update_time)

    def update_time(self, key, data):
        self.time -= 1
        self.timer.value.set_text(format_time(self.time))
        if not self.time:
            self.game_over()

    def show_board(self):
        self.add_layer(self.main_layer)
        self.add_layer(self.top_layer)

    def game_over(self):
        self.lose_bell_sound.play()
        self.lose_music_sound.play()
        self.stop_timer(0)
        for card in self.cards:
            card.item.remove_event_handler(ItemEvent.CLICK, card.handle_click)
        self.add_layer(self.game_over_layer)
        self.start_timer("go_back_timer", self.GO_BACK_TIME, self.go_back)

    def exit(self, other_item):
        GameStage.exit(self, other_item)
        for card1, card2 in self.deck:
            card1.exit()
            card2.exit()
        self.deck = None
        self.cards = None

    def go_back(self, *args, **kwargs):
        from game.stages.map import Map
        self.game.set_stage(Map(self.game))
예제 #12
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
예제 #13
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()
예제 #14
0
class AsteroidsMinigame(GameStage):
    GO_BACK_TIME = 3000
    ONE_SECOND_INTERVAL = 1000
    MARGIN = 70

    def __init__(self, game):
        GameStage.__init__(self, game)

    def initialize(self):
        GameStage.initialize(self)
        stream = file('data/fonts.yaml', 'r')
        fonts = load(stream)
        for font in fonts:
            setattr(
                self, font,
                assets.load_font(fonts[font]['file_name'],
                                 fonts[font]['size']))

        self.data = DictClass(load(file('data/asteroids.yaml')))

        self.game_over_layer = Layer()
        image = assets.load_image(
            self.data.game_over[self.game.datastore.datamodel.character].src)
        item = ItemImage(self.data.game_over.left, self.data.game_over.top,
                         image)
        self.game_over_layer.add(item)

        self.main_layer = Layer()
        self.top_layer = Layer()

        self.time = self.data.time.max
        self.timer = DictClass({})
        image = assets.load_image(self.data.time.src)
        self.timer['skin'] = ItemImage(self.data.time.left, self.data.time.top,
                                       image)
        self.timer['value'] = ItemText(self.data.time.left,
                                       self.data.time.top,
                                       self.font,
                                       0,
                                       format_time(self.time),
                                       width=image.get_width(),
                                       height=image.get_height(),
                                       h_align=2,
                                       v_align=2)
        self.top_layer.add(self.timer.skin)
        self.top_layer.add(self.timer.value)

        self.score = 0
        self.score_board = DictClass({})
        image = assets.load_image(self.data.score.src)
        self.score_board['skin'] = ItemImage(self.data.score.left,
                                             self.data.score.top, image)
        self.score_board['value'] = ItemText(self.data.score.left,
                                             self.data.score.top,
                                             self.font,
                                             0,
                                             str(self.score),
                                             width=image.get_width(),
                                             height=image.get_height(),
                                             h_align=2,
                                             v_align=2)
        self.top_layer.add(self.score_board.skin)
        self.top_layer.add(self.score_board.value)

        self.level = self.data.start
        self.asteroids = []

        self.max_width = 0
        self.max_height = 0
        for a in self.data.asteroids:
            item = assets.load_image(a)
            if self.max_width < item.get_width():
                self.max_width = item.get_width()
            if self.max_height < item.get_height():
                self.max_height = item.get_height()
        self.max_col = int(SCREEN_WIDTH / self.max_width)
        self.max_row = int(SCREEN_HEIGHT / self.max_height)
        self.margin_left = (SCREEN_WIDTH % self.max_width) / 2
        self.margin_top = (SCREEN_HEIGHT % self.max_height) / 2

        # Load the sound
        self.click_sound = assets.load_sound('DGI_Click.ogg')
        self.item_found_sound = assets.load_sound('DGI_item_found.ogg')
        self.wrong_sound = assets.load_sound('DGI_wrong.ogg')
        self.lose_bell_sound = assets.load_sound('DGI_lose_bell.ogg')
        self.lose_music_sound = assets.load_sound('DGI_lose_music.ogg')

    def prepare(self):
        self.show()
        self.add_layer(self.main_layer)
        self.add_layer(self.top_layer)
        dialog = Intro(self, self.data.intro, self.start_game)
        dialog.start()

    def start_game(self):
        self.start_timer(0, self.ONE_SECOND_INTERVAL, self.update_time)

    def show(self):
        if 'selector' in self.data.levels[self.level]:
            selector = eval(self.data.levels[self.level].selector)
            aux_seq = eval(self.data.levels[self.level][selector])
        else:
            aux_seq = eval(self.data.levels[self.level].range)

        self.sequence = []
        for value in range(0, self.data.levels[self.level].quantity):
            value = random.choice(aux_seq)
            aux_seq.remove(value)
            self.sequence.append(value)

        self.sequence = sorted(self.sequence)
        self.sequence.reverse()

        positions = range(0, self.max_col * self.max_row)

        for value in self.sequence:
            src = random.choice(self.data.asteroids)
            asteroid = Asteroid(self, 0, 0, src, value)

            position = random.choice(positions)
            positions.remove(position)
            i = int(position / self.max_col)
            j = int(position % self.max_col)
            left = self.margin_left + j * self.max_width + random.uniform(
                0, self.max_width % asteroid.item.get_width())
            top = self.margin_top + i * self.max_height + random.uniform(
                0, self.max_height % asteroid.item.get_height())

            asteroid.set_left(left)
            asteroid.set_top(top)
            self.asteroids.append(asteroid)
            self.main_layer.add(asteroid.item)
            self.main_layer.add(asteroid.text)

        if self.level + self.data.step <= self.data.max:
            self.level += self.data.step

    def select(self, asteroid):
        self.click_sound.play()
        expected = self.sequence.pop()
        if asteroid.value == expected:
            self.item_found_sound.play()
            self.score += self.data.score.points
            self.score_board.value.set_text(str(self.score))

            self.asteroids.remove(asteroid)
            self.main_layer.remove(asteroid.item)
            self.main_layer.remove(asteroid.text)
            asteroid.exit()
        else:
            self.wrong_sound.play()
            self.sequence.append(expected)
        if not self.asteroids:
            self.show()

    def update_time(self, key, data):
        self.time -= 1
        self.timer.value.set_text(format_time(self.time))
        if not self.time:
            self.game_over()

    def game_over(self):
        self.lose_bell_sound.play()
        self.lose_music_sound.play()
        self.stop_timer(0)
        for asteroid in self.asteroids:
            asteroid.item.remove_event_handler(ItemEvent.CLICK,
                                               asteroid.handle_click)
        self.add_layer(self.game_over_layer)
        self.start_timer("go_back_timer", self.GO_BACK_TIME, self.go_back)

    def go_back(self, *args, **kwargs):
        from game.stages.map import Map
        self.game.set_stage(Map(self.game))
예제 #15
0
class InvadersMinigame(GameStage):
    MOVE_INTERVAL = 30
    GOOD_INDICATOR_INTERVAL = 1000
    DIFFICULTY_INTERVAL = 10000
    GO_BACK_TIME = 3000

    def __init__(self, game):
        GameStage.__init__(self, game, Color('#333333'))

    def initialize(self):
        GameStage.initialize(self)
        stream = file('data/fonts.yaml', 'r')

        fonts = load(stream)
        for font in fonts:
            setattr(
                self, font,
                assets.load_font(fonts[font]['file_name'],
                                 fonts[font]['size']))

        self.data = DictClass(load(file('data/invaders.yaml')))

        self.good = self.data.start.good
        self.velocity = self.data.start.velocity
        self.interval = self.data.start.interval

        self.game_over_layer = Layer()
        image = assets.load_image(
            self.data.bad[self.game.datastore.datamodel.character].src)
        item = ItemImage(self.data.bad.left, self.data.bad.top, image)
        self.game_over_layer.add(item)
        image = assets.load_image(
            self.data.game_over[self.game.datastore.datamodel.character].src)
        item = ItemImage(self.data.game_over.left, self.data.game_over.top,
                         image)
        self.game_over_layer.add(item)

        image = assets.load_image(
            self.data.good[self.game.datastore.datamodel.character].src)
        self.good_indicator = ItemImage(self.data.good.left,
                                        self.data.good.top, image)

        self.text_indicators = []

        self.main_layer = Layer()
        self.top_layer = Layer()

        self.score = 0
        self.score_board = DictClass({})
        image = assets.load_image(self.data.score.src)
        self.score_board['skin'] = ItemImage(self.data.score.left,
                                             self.data.score.top, image)
        self.score_board['value'] = ItemText(self.data.score.left,
                                             self.data.score.top,
                                             self.font,
                                             0,
                                             str(self.score),
                                             width=image.get_width(),
                                             height=image.get_height(),
                                             h_align=2,
                                             v_align=2)
        self.top_layer.add(self.score_board.skin)
        self.top_layer.add(self.score_board.value)

        data = DictClass(load(file('data/map/common.yaml')))
        params = data.character[self.game.datastore.datamodel.character]
        params['base'] = data.character.base[
            self.game.datastore.datamodel.character].big
        self.character_animation = Character(**params)
        self.character = self.character_animation.item
        self.character.set_left(
            (SCREEN_WIDTH - self.character.get_width()) / 2)
        self.character.set_top(SCREEN_HEIGHT - self.character.get_height())
        left = self.character.get_left() + self.data.collision.left
        top = self.character.get_top() + self.data.collision.top
        width = self.character.get_width(
        ) - self.data.collision.left - self.data.collision.right
        height = self.character.get_height(
        ) - self.data.collision.top - self.data.collision.bottom
        if DEBUG:
            self.debug_character = ItemRect(left,
                                            top,
                                            width,
                                            height,
                                            border=(255, 255, 255))
        self.invaders = []

        # Load the sound
        self.item_found_sound = assets.load_sound('DGI_item_found.ogg')
        self.lose_hit_sound = assets.load_sound('DGI_lose_hit.ogg')
        self.lose_music_sound = assets.load_sound('DGI_lose_music.ogg')

    def increase_difficulty(self, key, data):
        if self.good + self.data.step.good >= self.data.min.good:
            self.good += self.data.step.good
        if self.velocity + self.data.step.velocity <= self.data.max.velocity:
            self.velocity += self.data.step.velocity
        if self.interval + self.data.step.interval >= self.data.min.interval:
            self.interval += self.data.step.interval
            self.stop_timer(1)
            self.start_timer(1, self.interval, self.create_invader)

    def create_invader(self, key, data):
        lst = [(True, self.good), (False, 1 - self.good)]
        good = w_choice(lst)
        if good:
            index = random.randint(0, len(self.data.invaders.good) - 1)
            invader = self.data.invaders.good[index]
        else:
            index = random.randint(0, len(self.data.invaders.bad) - 1)
            invader = self.data.invaders.bad[index]
        src = invader.src
        points = invader.points
        collision = invader.collision
        min = invader.min
        max = invader.max
        velocity = invader.velocity
        invader = Invader(0, 0, min, max, velocity, good, src, points,
                          collision)
        left = random.randint(
            0, SCREEN_WIDTH - invader.item.get_image().get_width())
        invader.set_left(left)
        top = -invader.item.get_image().get_height()
        invader.item.set_top(top)
        self.invaders.append(invader)

        self.main_layer.add(invader.item)
        if DEBUG:
            self.main_layer.add(invader.debug_item)

    def move_invaders(self, key, data):
        for item in self.text_indicators:
            item.set_top(item.get_top() - 2)

        for invader in self.invaders:
            invader.move(self.MOVE_INTERVAL, self.velocity)
            if (invader.item.get_top() > SCREEN_HEIGHT):
                self.remove_invader(invader)
            else:
                left = self.character.get_left() + self.data.collision.left
                top = self.character.get_top() + self.data.collision.top
                width = self.character.get_width(
                ) - self.data.collision.left - self.data.collision.right
                height = self.character.get_height(
                ) - self.data.collision.top - self.data.collision.bottom
                character = Rect(left, top, width, height)
                item = Rect(invader.get_left(), invader.get_top(),
                            invader.get_width(), invader.get_height())
                k = character.collidelist([item])
                if k != -1:
                    if invader.good:
                        self.character_animation.footsteps_concrete_sound.stop(
                        )
                        self.item_found_sound.play()
                        self.character_animation.first_walking = True

                        self.score += invader.points
                        self.score_board.value.set_text(str(self.score))
                        self.top_layer.add(self.good_indicator)
                        item = ItemText(invader.get_left(),
                                        invader.get_top(),
                                        self.font,
                                        0,
                                        "+" + str(invader.points),
                                        h_align=2,
                                        v_align=2)
                        self.text_indicators.append(item)
                        self.top_layer.add(item)
                        fade_out_item(item, True, self.GOOD_INDICATOR_INTERVAL)
                        self.start_timer(3, self.GOOD_INDICATOR_INTERVAL,
                                         self.remove_good_indicator)
                    else:
                        self.stop_timer(1)
                        self.stop_timer(2)
                        self.game_over()
                        return
                    self.remove_invader(invader)

    def remove_invader(self, invader):
        self.invaders.remove(invader)
        self.main_layer.remove(invader.item)
        invader.exit()
        if DEBUG:
            self.main_layer.remove(invader.debug_item)

    def remove_good_indicator(self, key, data):
        self.stop_timer(3)
        self.top_layer.remove(self.good_indicator)

    def prepare(self):
        self.show_board()
        self.key = None
        dialog = Intro(self, self.data.intro, self.start_game)
        dialog.start()

    def start_game(self):
        self.start_timer(1, self.interval, self.create_invader)
        self.start_timer(2, self.MOVE_INTERVAL, self.move_invaders)
        self.start_timer(4, self.DIFFICULTY_INTERVAL, self.increase_difficulty)
        self.start_timer(0, 30, self.manage_key)

    def show_board(self):
        self.main_layer.add(self.character)
        if DEBUG:
            self.main_layer.add(self.debug_character)
        self.add_layer(self.main_layer)
        self.add_layer(self.top_layer)

    def handle_event(self, e):
        if e.type == KEYDOWN:
            self.key = e.key
        if e.type == KEYUP:
            self.key = None

    def manage_key(self, key, data):
        delta = 0
        if self.key == K_LEFT:
            delta = -8
        if self.key == K_RIGHT:
            delta = 8
        left = self.character.get_left() + delta
        if 0 <= left and left <= SCREEN_WIDTH - self.character.get_width():
            self.character.set_left(left)
            if DEBUG:
                self.debug_character.set_left(left + self.data.collision.left)
            self.character_animation.update(self.MOVE_INTERVAL,
                                            delta_left=delta)

    def game_over(self):
        self.good_indicator.set_visible(False)
        self.character_animation.footsteps_concrete_sound.stop()
        self.lose_hit_sound.play()
        self.lose_music_sound.play()

        self.stop_timer(0)
        self.stop_timer(1)
        self.stop_timer(2)
        self.stop_timer(3)
        self.stop_timer(4)
        self.top_layer.remove(self.good_indicator)
        self.add_layer(self.game_over_layer)
        self.start_timer("go_back_timer", self.GO_BACK_TIME, self.go_back)

    def exit(self, other_stage):
        GameStage.exit(self, other_stage)
        self.good_indicator.exit()
        self.good_indicator = None
        self.character_animation.exit()
        self.character_animation = None
        for invader in self.invaders:
            invader.exit()
        self.invaders = None

    def go_back(self, *args, **kwargs):
        from game.stages.map import Map
        self.game.set_stage(Map(self.game))
예제 #16
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