Skip to content

PacMan animation #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions adafruit_led_animation/animation/blink.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,15 @@ class Blink(ColorCycle):
:param pixel_object: The initialised LED object.
:param float speed: Animation speed in seconds, e.g. ``0.1``.
:param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format.
:param background_color: Background color in ``(r, g, b)`` tuple, or ``0x000000``
hex format. Defaults to BLACK.
:param name: A human-readable name for the Animation. Used by the string function.
"""

def __init__(self, pixel_object, speed, color, name=None):
super().__init__(pixel_object, speed, [color, BLACK], name=name)
# pylint: disable=too-many-arguments
def __init__(self, pixel_object, speed, color, background_color=BLACK, name=None):
self._background_color = background_color
super().__init__(pixel_object, speed, [color, background_color], name=name)

def _set_color(self, color):
self.colors = [color, BLACK]
self.colors = [color, self._background_color]
126 changes: 126 additions & 0 deletions adafruit_led_animation/animation/pacman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# SPDX-FileCopyrightText: 2025 Bob Loeffler
# SPDX-FileCopyrightText: 2025 Jose D. Montoya
#
# SPDX-License-Identifier: MIT

"""
`adafruit_led_animation.animation.pacman`
================================================================================

PacMan Animation for CircuitPython helper library for LED animations.
PACMAN ANIMATION Adapted from https://github.com/wled-dev/WLED/pull/4536 # by BobLoeffler68

* Author(s): Bob Loeffler, Jose D. Montoya

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
https://circuitpython.org/downloads


"""

import time
from adafruit_led_animation.animation import Animation
from adafruit_led_animation.color import (
BLACK,
YELLOW,
RED,
PURPLE,
CYAN,
ORANGE,
BLUE,
WHITE,
)

ORANGEYELLOW = (255, 136, 0)


class Pacman(Animation):
"""
Simulate the Pacman game in a single led strip.

:param pixel_object: The initialised LED object.
:param float speed: Animation speed rate in seconds, e.g. ``0.1``.
"""

# pylint: disable=too-many-arguments, too-many-branches
def __init__(
self,
pixel_object,
speed,
color=WHITE,
name=None,
):
self.num_leds = len(pixel_object)
self.pacman = [YELLOW, 10]
self.ghosts_original = [[RED, 6], [PURPLE, 4], [CYAN, 2], [ORANGE, 0]]
self.ghosts = [[RED, 6], [PURPLE, 4], [CYAN, 2], [ORANGE, 0]]
self.direction = 1
self.black_dir = -1
self.flag = "beep"
self.power_pellet = [ORANGEYELLOW, self.num_leds]
self.ghost_timer = time.monotonic()
if self.num_leds > 150:
self.start_blinking_ghosts = self.num_leds // 4
else:
self.start_blinking_ghosts = self.num_leds // 3

super().__init__(pixel_object, speed, color, name=name)

on_cycle_complete_supported = True

def draw(self):
"""
Draw the Pacman animation.
:param led_object: led object
:param neopixel_list: list of neopixel colors
:param int num_leds: number of leds.
:param int duration: duration in seconds. Default is 15 seconds
"""
pixel_list = self.pixel_object
pixel_list[-1] = self.power_pellet[0]

delta = time.monotonic() - self.ghost_timer
if delta > 1:
if self.power_pellet[0] == ORANGEYELLOW:
self.power_pellet[0] = BLACK
else:
self.power_pellet[0] = ORANGEYELLOW
pixel_list[self.power_pellet[1] - 1] = self.power_pellet[0]

self.ghost_timer = time.monotonic()

if self.pacman[1] >= self.num_leds - 2:
self.direction = self.direction * -1
self.black_dir = self.black_dir * -1
for ghost in self.ghosts:
ghost[0] = BLUE

pixel_list[self.pacman[1]] = self.pacman[0]
pixel_list[self.pacman[1] + self.black_dir] = BLACK
self.pacman[1] += self.direction

if self.ghosts[3][1] <= self.start_blinking_ghosts and self.direction == -1:
if self.flag == "beep":
for i, ghost in enumerate(self.ghosts):
ghost[0] = BLACK
self.flag = "bop"
else:
for i, ghost in enumerate(self.ghosts):
ghost[0] = self.ghosts_original[i][0]
self.flag = "beep"

for i, ghost in enumerate(self.ghosts):
pixel_list[ghost[1]] = ghost[0]
pixel_list[ghost[1] + self.black_dir] = BLACK
ghost[1] += self.direction

if self.ghosts[3][1] <= 0:
self.direction = self.direction * -1
self.black_dir = self.black_dir * -1
for i, ghost in enumerate(self.ghosts):
ghost[0] = self.ghosts_original[i][0]
17 changes: 15 additions & 2 deletions adafruit_led_animation/animation/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ class Volume(Animation):

# pylint: disable=too-many-arguments
def __init__(
self, pixel_object, speed, brightest_color, decoder, max_volume=500, name=None
self,
pixel_object,
speed,
brightest_color,
decoder,
max_volume=500,
name=None,
):
self._decoder = decoder
self._num_pixels = len(pixel_object)
Expand Down Expand Up @@ -89,8 +95,15 @@ def draw(self):
)

lit_pixels = int(
map_range(self._decoder.rms_level, 0, self._max_volume, 0, self._num_pixels)
map_range(
self._decoder.rms_level,
0,
self._max_volume,
0,
self._num_pixels,
)
)
# pylint: disable=consider-using-min-builtin
if lit_pixels > self._num_pixels:
lit_pixels = self._num_pixels

Expand Down
2 changes: 1 addition & 1 deletion adafruit_led_animation/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class AnimationSequence:
animations.animate()
"""

# pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-instance-attributes, too-many-arguments
def __init__(
self,
*members,
Expand Down
17 changes: 17 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ Demonstrates the blink animation.
:caption: examples/led_animation_blink.py
:linenos:

Blink with a selcted background color
----------------------------------------
Demonstrates the blink animation with an user defined background color.

.. literalinclude:: ../examples/led_animation_blink_with_background.py
:caption: examples/led_animation_blink_with_background.py
:linenos:

Comet
-----

Expand Down Expand Up @@ -96,3 +104,12 @@ Demonstrates the sparkle animations.
.. literalinclude:: ../examples/led_animation_sparkle_animations.py
:caption: examples/led_animation_sparkle_animations.py
:linenos:

Pacman
------

Demonstrates the pacman animation.

.. literalinclude:: ../examples/led_animation_pacman.py
:caption: examples/led_animation_pacman.py
:linenos:
29 changes: 29 additions & 0 deletions examples/led_animation_blink_with_background.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2025 Jose D. Montoya
# SPDX-License-Identifier: MIT

"""
This example blinks the LEDs purple with a yellow background at a 0.5 second interval.

For QT Py Haxpress and a NeoPixel strip. Update pixel_pin and pixel_num to match your wiring if
using a different board or form of NeoPixels.

This example will run on SAMD21 (M0) Express boards (such as Circuit Playground Express or QT Py
Haxpress), but not on SAMD21 non-Express boards (such as QT Py or Trinket).
"""
import board
import neopixel

from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.color import PURPLE, YELLOW

# Update to match the pin connected to your NeoPixels
pixel_pin = board.A3
# Update to match the number of NeoPixels you have connected
pixel_num = 30

pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.5, auto_write=False)

blink = Blink(pixels, speed=0.5, color=PURPLE, background_color=YELLOW)

while True:
blink.animate()
32 changes: 32 additions & 0 deletions examples/led_animation_pacman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2025 Jose D. Montoya
# SPDX-License-Identifier: MIT

"""
This example animates a Pacman on a NeoPixel strip.
"""
import board
import neopixel
from adafruit_led_animation.animation.pacman import Pacman
from adafruit_led_animation.color import WHITE

# Update to match the pin connected to your NeoPixels
pixel_pin = board.D6
# Update to match the number of NeoPixels you have connected
num_pixels = 50

# Create the NeoPixel object
ORDER = neopixel.GRB
pixels = neopixel.NeoPixel(
pixel_pin,
num_pixels,
brightness=0.5,
auto_write=False,
pixel_order=ORDER,
)

# Create the Pacman animation object
pacman = Pacman(pixels, speed=0.1, color=WHITE)

# Main loop
while True:
pacman.animate()