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 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 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 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
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)
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
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)
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)
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)
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()
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))
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
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()
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))
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))
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