#!/usr/bin/env python3 """ WS2812B 更多趣味LED特效 包含物理效果、游戏效果和节日主题特效 """ import time import random import math import RPi.GPIO as GPIO from rpi_ws281x import Color, PixelStrip class WS2812B_WS281X: def __init__(self, led_count=10, brightness=100): self.led_count = led_count self.brightness = brightness # WS2812B配置 LED_PIN = 10 # GPIO引脚(SPI模式) LED_FREQ_HZ = 800000 # LED信号频率 LED_DMA = 10 # DMA通道 LED_INVERT = False # 是否反转信号 LED_CHANNEL = 0 # PWM通道 # 创建PixelStrip对象 self.strip = PixelStrip(led_count, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, brightness, LED_CHANNEL) self.strip.begin() # 初始化后清空 time.sleep(0.1) for i in range(led_count): self.strip.setPixelColor(i, Color(0, 0, 0)) self.strip.show() time.sleep(0.1) def show(self, colors): """显示颜色""" for i, (r, g, b) in enumerate(colors): self.strip.setPixelColor(i, Color(int(r), int(g), int(b))) self.strip.show() def cleanup(self): """清理资源""" # 清空所有LED for i in range(self.led_count): self.strip.setPixelColor(i, Color(0, 0, 0)) self.strip.show() # ===== 物理效果类特效 ===== def gravity_bounce(ws, ball_color=(255, 100, 0), cycles=5): """重力弹跳效果""" print("重力弹跳效果开始...") for cycle in range(cycles): print(f" 弹跳 {cycle + 1}/{cycles}") # 模拟重力弹跳 height = 0 velocity = 0 gravity = 0.5 bounce_damping = 0.8 for _ in range(50): velocity += gravity height += velocity # 检查是否触底 if height >= ws.led_count - 1: height = ws.led_count - 1 velocity = -velocity * bounce_damping # 显示球的位置 colors = [(0, 0, 0)] * ws.led_count ball_pos = int(height) if 0 <= ball_pos < ws.led_count: colors[ball_pos] = ball_color # 添加影子效果 if ball_pos > 0: shadow_intensity = max(0, int(50 - abs(height - ball_pos) * 20)) colors[ball_pos - 1] = (shadow_intensity, shadow_intensity // 2, 0) ws.show(colors) time.sleep(0.05) ws.show([(0, 0, 0)] * ws.led_count) print("重力弹跳效果完成!") def wave_ripple(ws, center_color=(0, 100, 255), cycles=8): """波纹扩散效果""" print("波纹扩散效果开始...") for cycle in range(cycles): print(f" 波纹 {cycle + 1}/{cycles}") for i in range(ws.led_count): colors = [(0, 0, 0)] * ws.led_count # 从中心向两边扩散 center = ws.led_count // 2 distance = abs(i - center) # 在两边对称的位置显示波纹 if center - distance >= 0: intensity = max(0, 255 - distance * 50) colors[center - distance] = ( int(center_color[0] * intensity / 255), int(center_color[1] * intensity / 255), int(center_color[2] * intensity / 255) ) if center + distance < ws.led_count and distance > 0: intensity = max(0, 255 - distance * 50) colors[center + distance] = ( int(center_color[0] * intensity / 255), int(center_color[1] * intensity / 255), int(center_color[2] * intensity / 255) ) ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("波纹扩散效果完成!") def magnet_effect(ws, metal_color=(150, 150, 150), magnet_color=(255, 0, 0), cycles=6): """磁铁吸引效果""" print("磁铁吸引效果开始...") for cycle in range(cycles): print(f" 磁铁循环 {cycle + 1}/{cycles}") # 磁铁位置(左右两端) magnet_positions = [0, ws.led_count - 1] for frame in range(30): colors = [(0, 0, 0)] * ws.led_count # 显示磁铁 for pos in magnet_positions: colors[pos] = magnet_color # 计算金属粒子位置 for i in range(3): # 3个金属粒子 particle_pos = int(4 + 2 * math.sin(frame * 0.3 + i * 2)) if 0 < particle_pos < ws.led_count - 1: colors[particle_pos] = metal_color ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("磁铁吸引效果完成!") def pendulum_swing(ws, pendulum_color=(255, 255, 0), cycles=10): """钟摆摆动效果""" print("钟摆摆动效果开始...") for cycle in range(cycles): print(f" 钟摆循环 {cycle + 1}/{cycles}") # 模拟钟摆运动 for angle in range(-60, 61, 5): colors = [(0, 0, 0)] * ws.led_count # 计算钟摆位置 center = ws.led_count // 2 position = int(center + angle / 15) if 0 <= position < ws.led_count: colors[position] = pendulum_color # 添加运动模糊效果 if angle > -60 and position > 0: colors[position - 1] = (pendulum_color[0] // 3, pendulum_color[1] // 3, pendulum_color[2] // 3) ws.show(colors) time.sleep(0.08) # 反向摆动 for angle in range(60, -61, -5): colors = [(0, 0, 0)] * ws.led_count center = ws.led_count // 2 position = int(center + angle / 15) if 0 <= position < ws.led_count: colors[position] = pendulum_color if angle < 60 and position < ws.led_count - 1: colors[position + 1] = (pendulum_color[0] // 3, pendulum_color[1] // 3, pendulum_color[2] // 3) ws.show(colors) time.sleep(0.08) ws.show([(0, 0, 0)] * ws.led_count) print("钟摆摆动效果完成!") # ===== 游戏效果类特效 ===== def snake_game(ws, cycles=3): """贪吃蛇游戏效果""" print("贪吃蛇游戏效果开始...") snake_color = (0, 255, 0) food_color = (255, 0, 0) for cycle in range(cycles): print(f" 贪吃蛇 {cycle + 1}/{cycles}") # 初始化蛇的位置 snake = [(0, 0), (0, 1), (0, 2)] # 简化为线性移动 food = random.randint(3, ws.led_count - 1) for step in range(20): colors = [(0, 0, 0)] * ws.led_count # 移动蛇 if step < 15: new_head = (snake[-1][0] + 1) % ws.led_count snake.append((new_head, snake[-1][1] + 1)) snake.pop(0) # 显示蛇 for i, (pos, _) in enumerate(snake): if i == len(snake) - 1: # 蛇头 colors[pos % ws.led_count] = (0, 150, 0) else: # 蛇身 colors[pos % ws.led_count] = snake_color # 显示食物 colors[food] = food_color ws.show(colors) time.sleep(0.2) ws.show([(0, 0, 0)] * ws.led_count) print("贪吃蛇游戏效果完成!") def space_invaders(ws, cycles=5): """太空侵略者效果""" print("太空侵略者效果开始...") alien_color = (0, 255, 0) bullet_color = (255, 255, 0) for cycle in range(cycles): print(f" 入侵者 {cycle + 1}/{cycles}") # 外星人移动 for direction in [1, -1]: for step in range(ws.led_count - 2): colors = [(0, 0, 0)] * ws.led_count # 显示外星人 alien_pos = 3 + step * direction if 0 <= alien_pos < ws.led_count: colors[alien_pos] = alien_color # 随机子弹 if random.random() < 0.3: bullet_pos = random.randint(0, ws.led_count - 1) colors[bullet_pos] = bullet_color ws.show(colors) time.sleep(0.15) ws.show([(0, 0, 0)] * ws.led_count) print("太空侵略者效果完成!") def pong_game(ws, cycles=10): """乒乓球游戏效果""" print("乒乓球游戏效果开始...") paddle_color = (255, 255, 255) ball_color = (255, 100, 100) for cycle in range(cycles): print(f" 乒乓球 {cycle + 1}/{cycles}") # 球的初始位置和速度 ball_pos = ws.led_count // 2 ball_velocity = 1 for _ in range(30): colors = [(0, 0, 0)] * ws.led_count # 显示球拍 colors[0] = paddle_color colors[ws.led_count - 1] = paddle_color # 显示球 if 0 <= ball_pos < ws.led_count: colors[ball_pos] = ball_color # 移动球 ball_pos += ball_velocity # 碰撞检测 if ball_pos <= 0 or ball_pos >= ws.led_count - 1: ball_velocity = -ball_velocity ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("乒乓球游戏效果完成!") def matrix_rain(ws, cycles=8): """黑客帝国数字雨效果""" print("黑客帝国数字雨效果开始...") for cycle in range(cycles): print(f" 数字雨 {cycle + 1}/{cycles}") for frame in range(20): colors = [(0, 0, 0)] * ws.led_count # 随机生成数字雨 for i in range(ws.led_count): if random.random() < 0.3: intensity = random.randint(100, 255) colors[i] = (0, intensity, 0) elif random.random() < 0.1: # 更亮的"头部" colors[i] = (100, 255, 100) ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("黑客帝国数字雨效果完成!") # ===== 节日主题特效 ===== def christmas_lights(ws, cycles=8): """圣诞彩灯效果""" print("圣诞彩灯效果开始...") colors_list = [ (255, 0, 0), # 红 (0, 255, 0), # 绿 (255, 255, 255), # 白 (255, 215, 0), # 金 (0, 0, 255), # 蓝 ] for cycle in range(cycles): print(f" 圣诞彩灯 {cycle + 1}/{cycles}") # 随机闪烁 for i in range(15): colors = [(0, 0, 0)] * ws.led_count # 随机点亮一些LED for j in range(ws.led_count): if random.random() < 0.4: colors[j] = random.choice(colors_list) ws.show(colors) time.sleep(0.2) ws.show([(0, 0, 0)] * ws.led_count) print("圣诞彩灯效果完成!") def fireworks(ws, cycles=6): """烟花爆炸效果""" print("烟花爆炸效果开始...") for cycle in range(cycles): print(f" 烟花 {cycle + 1}/{cycles}") # 烟花上升 for i in range(ws.led_count): colors = [(0, 0, 0)] * ws.led_count colors[i] = (255, 255, 0) # 黄色上升轨迹 ws.show(colors) time.sleep(0.05) # 爆炸效果 explosion_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255)] for frame in range(15): colors = [(0, 0, 0)] * ws.led_count # 随机爆炸粒子 for _ in range(random.randint(3, 6)): pos = random.randint(0, ws.led_count - 1) colors[pos] = random.choice(explosion_colors) ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("烟花爆炸效果完成!") def valentine_heart(ws, cycles=5): """情人节心跳效果""" print("情人节心跳效果开始...") for cycle in range(cycles): print(f" 心跳 {cycle + 1}/{cycles}") # 心跳模式 for beat in range(3): colors = [(255, 0, 100)] * ws.led_count # 粉红色 ws.show(colors) time.sleep(0.1) colors = [(150, 0, 50)] * ws.led_count # 暗粉色 ws.show(colors) time.sleep(0.1) # 暂停 colors = [(0, 0, 0)] * ws.led_count ws.show(colors) time.sleep(0.5) ws.show([(0, 0, 0)] * ws.led_count) print("情人节心跳效果完成!") def halloween_pumpkin(ws, cycles=8): """万圣节南瓜灯效果""" print("万圣节南瓜灯效果开始...") for cycle in range(cycles): print(f" 南瓜灯 {cycle + 1}/{cycles}") # 摇曳的橙色光 for i in range(20): colors = [(0, 0, 0)] * ws.led_count for j in range(ws.led_count): # 随机亮度变化模拟摇曳 intensity = random.randint(100, 255) colors[j] = (intensity, intensity // 2, 0) # 橙色 ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("万圣节南瓜灯效果完成!") def new_year_countdown(ws, cycles=3): """新年倒计时效果""" print("新年倒计时效果开始...") for cycle in range(cycles): print(f" 倒计时 {cycle + 1}/{cycles}") # 倒计时数字效果 for countdown in [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]: colors = [(255, 215, 0)] * countdown + [(0, 0, 0)] * (ws.led_count - countdown) ws.show(colors) time.sleep(0.5) # 新年庆祝 for i in range(10): colors = [] for j in range(ws.led_count): if random.random() < 0.5: colors.append((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))) else: colors.append((0, 0, 0)) ws.show(colors) time.sleep(0.1) ws.show([(0, 0, 0)] * ws.led_count) print("新年倒计时效果完成!") # ===== 主展示函数 ===== def show_fun_effects(): """展示所有趣味LED特效""" ws = WS2812B_WS281X(led_count=10, brightness=100) try: print("🎮 趣味LED特效展示开始!") print("=" * 50) # 特效列表 effects = [ ("物理效果 - 重力弹跳", lambda: gravity_bounce(ws, cycles=3)), ("物理效果 - 波纹扩散", lambda: wave_ripple(ws, cycles=6)), ("物理效果 - 磁铁吸引", lambda: magnet_effect(ws, cycles=4)), ("物理效果 - 钟摆摆动", lambda: pendulum_swing(ws, cycles=6)), ("游戏效果 - 贪吃蛇", lambda: snake_game(ws, cycles=2)), ("游戏效果 - 太空侵略者", lambda: space_invaders(ws, cycles=3)), ("游戏效果 - 乒乓球", lambda: pong_game(ws, cycles=6)), ("游戏效果 - 黑客帝国", lambda: matrix_rain(ws, cycles=5)), ("节日效果 - 圣诞彩灯", lambda: christmas_lights(ws, cycles=6)), ("节日效果 - 烟花爆炸", lambda: fireworks(ws, cycles=4)), ("节日效果 - 情人心跳", lambda: valentine_heart(ws, cycles=4)), ("节日效果 - 万圣南瓜", lambda: halloween_pumpkin(ws, cycles=6)), ("节日效果 - 新年倒计时", lambda: new_year_countdown(ws, cycles=2)), ] # 按顺序播放每个特效 for i, (name, effect_func) in enumerate(effects): print(f"\n🎭 特效 {i+1}/{len(effects)}: {name}") print("-" * 30) effect_func() # 特效之间短暂停顿 time.sleep(1) print("\n🎉 所有趣味特效播放完成!") print("=" * 50) except KeyboardInterrupt: print("\n⏹️ 用户中断,停止播放...") ws.show([(0, 0, 0)] * ws.led_count) except Exception as e: print(f"\n❌ 播放出错: {e}") ws.show([(0, 0, 0)] * ws.led_count) finally: ws.cleanup() print("🧹 清理完成") if __name__ == "__main__": show_fun_effects()