# Standalone MicroPython Voice Animation: Kid Companion Robot # Exposes run(text="", frames=...) and runs automatically if executed directly. import time import math try: import board_config display = getattr(board_config, 'display_instance', None) except Exception: board_config = None display = None def draw_center_text(d, msg, y, w, scale=1, c=1): char_w = 8 * scale x = max(0, (w - len(msg) * char_w) // 2) if hasattr(d, 'text_large') and scale > 1: try: d.text_large(msg, x, y, scale, c) return except Exception: pass d.text(msg, x, y, c) def run(text="", frames=100): if not display: print("board_config.display_instance is not available. Skipping animation.") return width = getattr(display, 'width', 400) height = getattr(display, 'height', 300) cx, cy = width // 2, height // 2 label = text if text else "HELLO BUDDY!" frame = 0 try: while True: if frames is not None and frames > 0 and frame >= frames: break display.clear(0) # Robot head main box head_y = cy - 15 display.rect(cx - 50, head_y - 40, 100, 80, 1) display.rect(cx - 49, head_y - 39, 98, 78, 1) # thicker # Neck display.fill_rect(cx - 10, head_y + 40, 20, 12, 1) # Ears wiggling dynamically using sin waves ear_offset = int(5 * math.sin(frame * 0.25)) # Left ear display.rect(cx - 62, head_y - 15 + ear_offset, 12, 30, 1) display.line(cx - 62, head_y + ear_offset, cx - 50, head_y, 1) # Right ear display.rect(cx + 50, head_y - 15 - ear_offset, 12, 30, 1) display.line(cx + 62, head_y - ear_offset, cx + 50, head_y, 1) # Antenna extending from head top display.line(cx, head_y - 40, cx, head_y - 58, 1) display.line(cx - 1, head_y - 40, cx - 1, head_y - 58, 1) # Antenna bulb winks (flashes) bulb_on = (frame // 4) % 2 == 0 if bulb_on: display.fill_rect(cx - 6, head_y - 69, 12, 12, 1) else: display.rect(cx - 6, head_y - 69, 12, 12, 1) # Eyes eye_y = head_y - 12 # Left Eye (always open, cute square with highlight) display.rect(cx - 32, eye_y - 8, 16, 16, 1) display.fill_rect(cx - 28, eye_y - 4, 8, 8, 1) display.fill_rect(cx - 26, eye_y - 2, 3, 3, 0) # highlight # Right Eye winks every 12 frames is_winking = (frame // 10) % 2 == 1 if is_winking: # Wink line (happy curved line) display.line(cx + 12, eye_y, cx + 20, eye_y + 4, 1) display.line(cx + 20, eye_y + 4, cx + 28, eye_y, 1) else: # Open right eye display.rect(cx + 16, eye_y - 8, 16, 16, 1) display.fill_rect(cx + 20, eye_y - 4, 8, 8, 1) display.fill_rect(cx + 22, eye_y - 2, 3, 3, 0) # highlight # Cute happy smile mouth display.line(cx - 16, head_y + 16, cx + 16, head_y + 16, 1) display.line(cx - 16, head_y + 16, cx - 20, head_y + 10, 1) display.line(cx + 16, head_y + 16, cx + 20, head_y + 10, 1) # Draw centered text label at the bottom draw_center_text(display, label, height - 30, width, scale=1, c=1) display.show() frame += 1 try: time.sleep_ms(60) except AttributeError: time.sleep(0.06) except KeyboardInterrupt: print("Animation interrupted by user.") if __name__ in ('__main__', '__name__'): run()