def start_resize(item_image, image, from_size, to_size, duration, origin_type = 1, callback = None): """ Start a resize animation on the specified ItemImage. - item: ItemImage to resize. - image: Image that is resized an assigned to the ItemImage. - from_size: Initial size specified as (width, height). - to_size: Final size specified as (width, height). - origin_type: Origin. Possible values: 0 - Left X, Left Y. 1 - Center X, Center Y. - callback: Function that is invoked with parameter item when the animation is completed. None there is no callback function. """ stage = __get_item_stage(item_image) # If a move timer is already started for the item, stop it key = (item_image, "resize") milliseconds = 20 stage.stop_timer(key) # Set the initial size resized_image = assets.Image(pygame.transform.smoothscale(image.surface, (int(from_size[0]), int(from_size[1])))) item_image.set_image(resized_image) if origin_type == 1: orgin_pos = (item_image.get_left() + item_image.get_width() / 2, item_image.get_top() + item_image.get_height() / 2) else: orgin_pos = None # Start the timer data = [None, image, duration, origin_type, orgin_pos, from_size, to_size, callback, stage] stage.start_timer(key, milliseconds, __timer_resize, data, True, True)
def start_move(item, left, top, duration, acceleration = None, move_marks = None, callback = None): """ Starts an animation that moves the specified item in a straight line to the specified position. - item: Item. - left: Target left. - top: Target top. - duration: Duration in milliseconds of the move animation. - acceleration: Acceleration. It use a sinusoidal function to calculate the displacement as time pass. A pair with (maxvel_t, maxvel_dist, tension) should be passed in this parameter to control the movement, where: * maxvel_t: Value between 0 and 1 that indicate the percentage of the time of the point with the higher velocity. If you indicate 0.5 the maximum velocity will be reached in the middle of the movement. * maxvel_dist: Value between 0 and 1 that indicate the percentage of the distance that is traveled at maxvel_t. * tension: Indicate how curved is the movement, it is power that is applied to the sine function. If it is 1 the movement is a sinusoidal function. Values less than 1 indicate a movement more closer to an uniform movement, and values greater that 1 indicates a more accelerated displacement. Use None to generate a uniform move. - move_marks: An instance of MoveMarks. Define an image that is repeated to mark the path traveled. None to don't print move marks. - callback: Function that is invoked with parameter item when the animation is completed. None there is no callback function. """ stage = __get_item_stage(item) # If a move timer is already started for the item, stop it key = (item, "move") milliseconds = 20 stage.stop_timer(key) item_left = item.get_left() item_top = item.get_top() # Initialize the move marks data if move_marks == None: move_marks_data = None else: angle = math.atan2(top - item_top, left - item_left) dx_per_mark = math.cos(angle) * move_marks.separation dy_per_mark = math.sin(angle) * move_marks.separation if abs(dx_per_mark) < 1 and abs(dy_per_mark) < 1: move_marks_data = None else: mark_image_dx = item.get_width() / 2 - move_marks.mark_image.get_width() / 2 mark_image_dy = item.get_height() / 2 - move_marks.mark_image.get_height() / 2 move_marks_data = [item_left - dx_per_mark, item_top - dy_per_mark, dx_per_mark, dy_per_mark, mark_image_dx, mark_image_dy] # Start the timer data = [None, duration, item_left, item_top, left, top, acceleration, move_marks, move_marks_data, callback, stage] stage.start_timer(key, milliseconds, __timer_move, data, True, True)
def wait(stage, milliseconds, callback): """ Waits the specified time and invoke the callback. - stage: Stage. - milliseconds: Number of milliseconds to wait. - callback: Function to invoke (without parameters). Return the wait's timer key. It can be used to cancel the wait using the cancel_wait function. """ key = ("wait", animations.WAIT_ORDINAL) stage.start_timer(key, milliseconds, __timer_wait, (stage, callback)) animations.WAIT_ORDINAL += 1 if animations.WAIT_ORDINAL == 99999: animations.WAIT_ORDINAL = 1 return key
def fade_out_layer(layer, duration = 500, callback = None): """ Perform a fade out animation to hide the items of a layer. - layer: Layer. - duration: Duration in milliseconds of the fade in animation. - callback: Function that is invoked with parameter layer when the animation is completed. None there is no callback function. """ stage = __get_layer_stage(layer) key = (layer, "fade") milliseconds = 20 # If a fade timer was already started for the item, stop it stage.stop_timer(key) # Start the timer data = [pygame.time.get_ticks(), None, duration, callback, stage] stage.start_timer(key, milliseconds, __timer_fade_out_layer, data, True, True)
def wait_locked(stage, milliseconds, callback): """ Waits the specified time and invoke the callback. While the game waits for the specified time the interface is locked and cannot receive mouse or other events. - stage: Stage. - milliseconds: Number of milliseconds to wait. - callback: Function to invoke (without parameters). Return the wait's timer key. It can be used to cancel the wait using the cancel_wait function. """ stage.lock_ui() key = ("wait_locked", animations.WAIT_ORDINAL) stage.start_timer(key, milliseconds, __timer_wait_locked, (stage, callback)) animations.WAIT_ORDINAL += 1 if animations.WAIT_ORDINAL == 99999: animations.WAIT_ORDINAL = 1 return key
def start_image_sequence(item_image, images, fps, loops = 0, callback = None): """ Starts an animation showing a sequence of images through an ItemImage. - item_image: An instance of ItemImage, the images are assigned to this item. - images: Images (must be instances of assets.Image) - fps: Frames per seconds. Define the speed of the animation. - loops: Number of times that the sequence is repeated (0 to show the sequence only once). -1 to repeat the image sequences indefinitely. - callback: Function that is invoked with parameter item_image when the animation is completed. None there is no callback function. If there is already an image sequence started over the item it is stopped before start this animation. """ stage = __get_item_stage(item_image) # If a image sequence timer was already started for the item, stop it key = (item_image, "image_sequence") stage.stop_timer(key) # Start the timer milliseconds = 1000 / fps stage.start_timer(key, milliseconds, __timer_image_sequence, [0, images, loops, callback, stage])
def fade_out_item(item, remove, duration = 500, callback = None): """ Perform a fade out animation to hide an item. - item: Item. - remove: True if the item will be removed at the end of the fade-out. False otherwise. - duration: Duration in milliseconds of the fade in animation. - callback: Function that is invoked with parameter item when the animation is completed. None there is no callback function. """ stage = __get_item_stage(item) key = (item, "fade") milliseconds = 20 # If a fade timer was already started for the item, stop it stage.stop_timer(key) # Hide the rollover if there is a rollover over the item item.hide_rollover() # Start the timer data = [pygame.time.get_ticks(), None, duration, remove, callback, stage] stage.start_timer(key, milliseconds, __timer_fade_out_item, data, True, True)
def fade_in_item(item, duration = 500, callback = None, to_alpha = 255): """ Perform a fade in animation to show an item. - item: Item. - duration: Duration in milliseconds of the fade in animation. - callback: Function that is invoked with parameter item when the animation is completed. None there is no callback function. - to_alpha: Final alpha value for the fade. """ stage = __get_item_stage(item) key = (item, "fade") milliseconds = 20 if item.get_alpha() == 255: item.set_alpha(0) # If a fade timer was already started for the item, stop it stage.stop_timer(key) # Start the timer data = [pygame.time.get_ticks(), None, duration, to_alpha, callback, stage] stage.start_timer(key, milliseconds, __timer_fade_in_item, data, True, True)
def blind_layer(layer, direction, area, duration = 450, callback = None, lock_ui = True): """ Apply a blind effect to show or hide the specified layer. - layer: Layer. - direction: A value of BlindDirection that indicate the direction of the blind effect. - area: Area where the blind effect is applied. None to cross the entire screen. A smaller rectangle indicate the the blind only must cross the zone defined in the rectangle. - duration: Duration in milliseconds of the blind effect to cross the full screen. If you specify an area the duration could be smaller, because it could not cross the full screen. This behavior is defined to give consistency with the default time if you apply the effect over areas with different sizes. - callback: Function to invoke with parameter Layer when the blind effect ends. None if there is no callback function. - lock_ui: Indicates if must lock the UI while performing the effect """ stage = __get_layer_stage(layer) key = (layer, "blind") milliseconds = 20 # Create the effect data, if there is a blind effect in progress stop # the effect and apply this effect from the previous position data = stage.stop_timer(key) window_width, window_height = stage.game.get_window_size() dy_factor = float(window_height) / duration if data != None and data[9]: # There was an effect that was locking the UI, unlock it stage.unlock_ui() if data != None and data[1] == direction and data[0] != None: # There is already an effect applied over the layer with # the same direction. Replace the callback and continue # with the effect data[7] = callback else: if direction == BlindDirection.SHOW_UP or \ direction == BlindDirection.SHOW_DOWN: if direction == BlindDirection.SHOW_DOWN: if area == None: current_top = 0 else: current_top = area.top else: if area == None: current_top = window_height else: current_top = area.top + area.height current_height = 0 layer.set_clip(pygame.Rect(0, current_top, window_width, 0)) elif direction == BlindDirection.HIDE_UP or \ direction == BlindDirection.HIDE_DOWN: hidden = False if not layer.get_visible(): hidden = True else: clip = layer.get_clip() if clip != None and (clip.width == 0 or clip.height == 0): hidden = True if hidden: # It is already hidden, don't apply the effect if callback != None: callback(layer) return else: if area == None: current_top = 0 current_height = window_height else: current_top = area.top current_height = area.height layer.set_clip(None) data = [None, direction, dy_factor, window_width, window_height, current_top, current_height, callback, stage, lock_ui] if lock_ui: # Lock the UI while performing the effect stage.lock_ui() # Start the timer stage.start_timer(key, milliseconds, __timer_blind_layer, data, True, True)