def __init__(self, map_model, parent=None): Context.__init__(self, parent) self.map_model = map_model self.map_model.controller = self self.map_model.initialize(self.map_model.local_state, self.map_model.global_state) self.map_view = MapView(self.map_model) self.map_music = MapMusic(self.map_model) self.__moving_sync = False self.message_queue = MessageQueue(self) self.do_cancel = False self.do_action = False
class MapController(Context): # Read-Only Attributes: # map_view - MapView (View component of MVC) # map_model - MapModel (Model component of MVC) def __init__(self, map_model, parent=None): Context.__init__(self, parent) self.map_model = map_model self.map_model.controller = self self.map_model.initialize(self.map_model.local_state, self.map_model.global_state) self.map_view = MapView(self.map_model) self.map_music = MapMusic(self.map_model) self.__moving_sync = False self.message_queue = MessageQueue(self) self.do_cancel = False self.do_action = False def initialize(self): map_model = self.map_model self.__map_view_draw = self.map_view.draw self.party_avatar = map_model.party_avatar # Initialize contexts context_stack = get_context_stack() context_stack.stack_context(self.message_queue) for context in map_model.contexts: context_stack.stack_context(context) def update(self): if self.map_model.pause_delay > 0: self.map_model.pause_delay -= 1 return False if self.__moving_sync: sync_stopped = self.__sync_movement_step() if not sync_stopped: return False if not self.message_queue.is_busy(): self.__flow_object_movement() self.__update_objects() self.__update_input() return False def __update_input(self): for key in game_config.key_cancel: if Input.was_pressed(key) is not None: self.do_cancel = True return for key in game_config.key_action: if Input.was_pressed(key) is not None: self.do_action = True return if self.party_avatar.scheduled_movement \ or self.party_avatar.movement_phase \ or self.message_queue.is_busy(): return if self.do_cancel: self.do_cancel = False get_context_stack().stop() return if self.do_action: self.do_action = False self.map_model.party_action() return for key in game_config.key_up: if Input.motion(key): self.party_avatar.schedule_movement(Step(UP)) return for key in game_config.key_down: if Input.motion(key): self.party_avatar.schedule_movement(Step(DOWN)) return for key in game_config.key_left: if Input.motion(key): self.party_avatar.schedule_movement(Step(LEFT)) return for key in game_config.key_right: if Input.motion(key): self.party_avatar.schedule_movement(Step(RIGHT)) return if game_config.map_mouse_enabled: evt = Input.was_pressed(M_1) if evt is not None: if not self.party_avatar.scheduled_movement: self.__mouse_movement(evt.pos) return def draw(self): self.__map_view_draw() self.map_music.update() def __flow_object_movement(self): party_avatar = self.map_model.party_avatar for o in self.map_model.objects: if o is not party_avatar: o.flow() party_avatar.flow() self.__trigger_collisions() def __trigger_collisions(self): avatar = self.map_model.party_avatar if avatar.just_completed_movement: avatar.just_completed_movement = False coming_from_direction = determine_facing(avatar.position, avatar.prev_position) # Trigger below objects' collide_with_party() for obj in self.map_model.object_layer[avatar.position].below: obj.collide_with_party(avatar, coming_from_direction) # Trigger above objects' collide_with_party() for obj in self.map_model.object_layer[avatar.position].above: obj.collide_with_party(avatar, coming_from_direction) # Trigger areas' party_entered and party_moved() for area in self.map_model.area_layer[avatar.position]: if area not in avatar.prev_areas: coming_from_outside = True area.party_entered(avatar, avatar.position) else: coming_from_outside = False area.party_moved(avatar, avatar.prev_position, avatar.position, coming_from_outside) def sync_movement(self, objects): self.__sync_objects = objects self.__moving_sync = True def __sync_movement_step(self): if all([not o.scheduled_movement for o in self.__sync_objects]): self.__moving_sync = False return True for o in self.__sync_objects: o.flow() return False def __update_objects(self): for o in self.map_model.updatable_objects: o.update() def gameover(self): get_context_stack().stop() def __mouse_movement(self, pos): target_x, target_y = self.map_view.calc_pos_from_mouse(pos) if self.map_model.terrain_layer.valid((target_x, target_y)): movement = PathMovement(self.map_model, self.map_model.party_avatar, Position(target_x, target_y)) self.map_model.party_avatar.schedule_movement(movement)