def draw_bot_hp(self, delta, loc, bot_color, alpha): x, y = self.renderer.grid_to_xy(loc) ox, oy = self.animation_offset tex_rgb = render_settings.text_color_bright \ if self.hp > settings.robot_hp / 4 \ else render_settings.text_color_dark tex_rgb = blend_colors(tex_rgb, bot_color, alpha) tex_hex = rgb_to_hex(*tex_rgb) val = int(self.hp * (1 - delta) + self.hp_next * delta) if self.text is None: self.text = self.renderer.draw_text(self.location, val, tex_hex) self.renderer._win.itemconfig(self.text, text=val, fill=tex_hex) self.renderer._win.coords( self.text, (x + ox + (self.renderer._blocksize - self.renderer.cell_border_width) / 2, y + oy + (self.renderer._blocksize - self.renderer.cell_border_width) / 2))
def animate(self, delta=0): """Animate this sprite. Delta is between 0 and 1. It tells us how far along to render (0.5 is halfway through animation). This allows animation logic to be separate from timing logic. """ # fix delta to between 0 and 1 delta = max(0, min(delta, 1)) bot_rgb_base = compute_color(self.id, self.hp, self.action) # default settings alpha_hack = 1 bot_rgb = bot_rgb_base # if spawn, fade in normal_color = render_settings.normal_color if render_settings.bot_die_animation: if self.action == 'spawn': alpha_hack = delta bot_rgb = blend_colors(bot_rgb_base, normal_color, alpha_hack) # if dying, fade out elif self.hp_next <= 0: alpha_hack = 1 - delta bot_rgb = blend_colors(bot_rgb_base, normal_color, alpha_hack) x, y = self.location bot_size = self.renderer._blocksize self.animation_offset = (0, 0) arrow_fill = None # move animations if self.action == 'move' and self.target is not None: if (self.renderer._animations and render_settings.bot_move_animation): # If normal move, start at bot location and move to next # location (note that first half of all move animations is the # same). if delta < 0.5 or self.location_next == self.target: x, y = self.location tx, ty = self.target # If we're halfway through this animation AND the movement # didn't succeed, reverse it (bounce back). else: # starting where we wanted to go x, y = self.target # and ending where we are now tx, ty = self.location dx = tx - x dy = ty - y off_x = dx * delta * self.renderer._blocksize off_y = dy * delta * self.renderer._blocksize self.animation_offset = (off_x, off_y) if render_settings.draw_movement_arrow: arrow_fill = 'lightblue' # attack animations elif self.action == 'attack' and self.target is not None: arrow_fill = 'orange' # guard animations elif self.action == 'guard': pass # suicide animations elif self.action == 'suicide': if (self.renderer._animations and render_settings.bot_suicide_animation): # explosion animation # expand size (up to 1.5x original size) bot_size = self.renderer._blocksize * (1 + delta // 2) # color fade to yellow bot_rgb = blend_colors(bot_rgb, (1, 1, 0), 1 - delta) # DRAW ARROWS AND BORDER AND CIRCLE if self.renderer.show_arrows.get(): if arrow_fill is not None and self.overlay is None: offset = (self.renderer._blocksize // 2, self.renderer._blocksize // 2) self.overlay = self.renderer.draw_line(self.location, self.target, layer=5, fill=arrow_fill, offset=offset, width=3.0, arrow=Tkinter.LAST) if self.action == 'guard' and self.border is None: self.border = self.renderer.draw_grid_object( self.location, shape=render_settings.bot_shape, layer=4, outline=rgb_tuple_to_hex( render_settings.color_guard_border), width=2) if self.action == 'suicide' and self.circle is None: self.circle = self.renderer.draw_grid_object(self.location, shape="circle", layer=4, outline="yellow", width=2) else: if self.overlay is not None: self.renderer.remove_object(self.overlay) self.overlay = None if self.border is not None: self.renderer.remove_object(self.border) self.border = None if self.circle is not None: self.renderer.remove_object(self.circle) self.circle = None # DRAW BOTS WITH HP bot_hex = rgb_to_hex(*bot_rgb) self.draw_bot((x, y), bot_hex, bot_size) if render_settings.bot_hp_animation: self.draw_bot_hp(delta, (x, y), bot_rgb, alpha_hack) else: self.draw_bot_hp(0, (x, y), bot_rgb, alpha_hack)
def animate(self, delta=0): """Animate this sprite. Delta is between 0 and 1. It tells us how far along to render (0.5 is halfway through animation). This allows animation logic to be separate from timing logic. """ # fix delta to between 0 and 1 delta = max(0, min(delta, 1)) bot_rgb_base = compute_color(self.id, self.hp, self.action) # default settings alpha_hack = 1 bot_rgb = bot_rgb_base # if spawn, fade in normal_color = render_settings.normal_color if render_settings.bot_die_animation: if self.action == 'spawn': alpha_hack = delta bot_rgb = blend_colors(bot_rgb_base, normal_color, alpha_hack) # if dying, fade out elif self.hp_next <= 0: alpha_hack = 1 - delta bot_rgb = blend_colors(bot_rgb_base, normal_color, alpha_hack) x, y = self.location bot_size = self.renderer._blocksize self.animation_offset = (0, 0) arrow_fill = None # move animations if self.action == 'move' and self.target is not None: if (self.renderer._animations and render_settings.bot_move_animation): # If normal move, start at bot location and move to next # location (note that first half of all move animations is the # same). if delta < 0.5 or self.location_next == self.target: x, y = self.location tx, ty = self.target # If we're halfway through this animation AND the movement # didn't succeed, reverse it (bounce back). else: # starting where we wanted to go x, y = self.target # and ending where we are now tx, ty = self.location dx = tx - x dy = ty - y off_x = dx * delta * self.renderer._blocksize off_y = dy * delta * self.renderer._blocksize self.animation_offset = (off_x, off_y) if render_settings.draw_movement_arrow: arrow_fill = 'lightblue' # attack animations elif self.action == 'attack' and self.target is not None: arrow_fill = 'orange' # guard animations elif self.action == 'guard': pass # suicide animations elif self.action == 'suicide': if (self.renderer._animations and render_settings.bot_suicide_animation): # explosion animation # expand size (up to 1.5x original size) bot_size = self.renderer._blocksize * (1 + delta / 2) # color fade to yellow bot_rgb = blend_colors(bot_rgb, (1, 1, 0), 1 - delta) # DRAW ARROWS AND BORDER AND CIRCLE if self.renderer.show_arrows.get(): if arrow_fill is not None and self.overlay is None: offset = (self.renderer._blocksize / 2, self.renderer._blocksize / 2) self.overlay = self.renderer.draw_line( self.location, self.target, layer=5, fill=arrow_fill, offset=offset, width=3.0, arrow=Tkinter.LAST) if self.action == 'guard' and self.border is None: self.border = self.renderer.draw_grid_object( self.location, shape=render_settings.bot_shape, layer=4, outline=rgb_tuple_to_hex( render_settings.color_guard_border), width=2) if self.action == 'suicide' and self.circle is None: self.circle = self.renderer.draw_grid_object( self.location, shape="circle", layer=4, outline="yellow", width=2) else: if self.overlay is not None: self.renderer.remove_object(self.overlay) self.overlay = None if self.border is not None: self.renderer.remove_object(self.border) self.border = None if self.circle is not None: self.renderer.remove_object(self.circle) self.circle = None # DRAW BOTS WITH HP bot_hex = rgb_to_hex(*bot_rgb) self.draw_bot((x, y), bot_hex, bot_size) if render_settings.bot_hp_animation: self.draw_bot_hp(delta, (x, y), bot_rgb, alpha_hack) else: self.draw_bot_hp(0, (x, y), bot_rgb, alpha_hack)
def get_mixed_color(self, color, loc): bot_color = self.get_bot_color(loc) if bot_color is not None: color = blend_colors(color, bot_color, 0.7) return rgb_to_hex(*color)