There are some nice demos that come with Pimoroni Unicorn HAT HD library but if you want something more fun you can have interactive applications.
How about GAMES ?
I stumbled over a thread Unicorn HAT Demo Ideas where someone was asking foe ideas of demos for the standard Unicorn HAT.
Two of the best demos delivered there by two users (Thank you guys !!!):
evilunix: CPU vs CPU game of pong with rainbow colours
Timcw (Tim Mulford): Battleships !!!
I ended up adapting them for the bigger matrix of the Unicorn HAT HD
CPU vs CPU game of pong with rainbow colours
Duble-Click to get the whole code.
# Adapted to Unicorn HD by George Voina # blog.voina.org import unicornhathd as UH import time import random import colorsys as col #UH.brightness(1) # max brightness :D SPEED = 0.1 # convert hex to rgb tuple def hex_to_rgb(value): value = value.lstrip('#') lv = len(value) return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)) class Player: def __init__(self, hue): self.hue = hue direction_x = 0 # 1 = up, 2 = down y = 0 # position of topmost pixel def spawn(self): self.y = random.randint(0,13) def think(self, ball): # change colour if self.hue < 360: self.hue = self.hue + 1 else: self.hue = 0 rand = random.randint(0,19) if(rand == 13): derp = 1 else: derp = 0 if ball.y > self.y + 1 and self.y < 13: # ball is below player center - move down if derp == 0: self.y = self.y + 1 if ball.y < self.y + 1 and self.y > 0: # ball is above player center - move up if derp == 0: self.y = self.y - 1 class Ball: direction_x = 0 # 1 = up, 2 = down direction_y = 0 # 1 = left, 2 = right x = 0 y = 0 colour = hex_to_rgb('ffffff') def spawn(self): print 'spawning ball...' # ball starting directions self.direction_x = random.randint(1,2) self.direction_y = random.randint(1,2) # ball starting position self.x = random.randint(3,4) self.y = random.randint(3,4) player1 = Player(0) player2 = Player(90) ball = Ball() def update(): global ball, player1, player2 player1.think(ball) player2.think(ball) # check if ball hit upper or lower wall if ball.y == 0: #change direction ball.direction_y = 2 # down if ball.y == 15: # change direction ball.direction_y = 1 # up if ball.direction_y == 2: # down # move 1 cell down ball.y = ball.y + 1 elif ball.direction_y == 1: #up # move 1 cell up ball.y = ball.y - 1 if ball.direction_x == 1: # moving left ball.x = ball.x - 1 if ball.x == 0: # check for collision if ball.y >= player1.y and ball.y <= player1.y + 3: print 'SAVE!' #change direction ball.direction_x = 2 ball.x = ball.x + 1 else: # GOAL! print 'GOAL!' goal() ball.spawn() if ball.direction_x == 2: # moving right ball.x = ball.x + 1 if ball.x == 15: # check for collision if ball.y >= player2.y and ball.y <= player2.y + 3: print 'SAVE!' # change direction ball.direction_x = 1 ball.x = ball.x - 2 else: # GOAL! goal() print 'GOAL!' ball.spawn() def goal(): global ball draw() time.sleep(SPEED) set_pixel(ball.x, ball.y, hex_to_rgb('000000')) UH.show() time.sleep(SPEED) set_pixel(ball.x, ball.y, ball.colour) UH.show() time.sleep(SPEED) set_pixel(ball.x, ball.y, hex_to_rgb('000000')) UH.show() time.sleep(SPEED) set_pixel(ball.x, ball.y, ball.colour) UH.show() time.sleep(SPEED) def set_pixel(x, y, colour): UH.set_pixel(x, y, colour[0], colour[1], colour[2]) def fill_hex(colour): rgb = hex_to_rgb(colour) for x in range(0, 16): for y in range(0, 16): set_pixel(x, y, rgb) UH.show() def set_pixel_hue(x, y, h): hfloat = h / 255.0 rgb = col.hsv_to_rgb(hfloat, 0.5, 1.0) r = int(rgb[0] * 255) g = int(rgb[1] * 255) b = int(rgb[2] * 255) UH.set_pixel(x, y, r, g, b) def draw(): global ball, player1, player2, BG_COLOUR UH.off() #fill_hex(BG_COLOUR) # draw ball set_pixel(ball.x, ball.y, ball.colour) # draw player1 set_pixel_hue(0, player1.y, player1.hue) set_pixel_hue(0, player1.y + 1, player1.hue) set_pixel_hue(0, player1.y + 2, player1.hue) # draw player2 set_pixel_hue(15, player2.y, player2.hue) set_pixel_hue(15, player2.y + 1, player2.hue) set_pixel_hue(15, player2.y + 2, player2.hue) UH.show() player1.spawn() player2.spawn() ball.spawn() draw() while True: time.sleep(SPEED) update() draw()
Battleships:
Duble-Click to get the whole code.
# Battleships Unicorn Hat display # Author: Tim Mulford # Date: 28/08/2015 # Version: 0.5 # Changes: # I have update the code to make the game area a class with methods for the game. # Adapted to Unicorn HD by George Voina # blog.voina.org import unicornhathd as unicorn import time, random # initialise Unicornhat board # Unless you are using a difusser keep brightness low #unicorn.brightness(0.1) unicorn.rotation(180) # ocean stores the information about the game area and the methods required to # interact with it class ocean: ships = 0 ammo = 0 water = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] # Reset the game board def reset(self): self.water = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] # Display the current board state on the Unicorn hat def display_water(self): for y in range(16): for x in range(16): if self.water[y][x] == 0 or self.water[y][x] == 1: unicorn.set_pixel(x,y,79,106,226) elif self.water[y][x] == 2: unicorn.set_pixel(x,y,0,0,0) elif self.water[y][x] == 3: unicorn.set_pixel(x,y,255,0,0) unicorn.show() # Set every light on the board to the set colour def flood_colour(self,red,green,blue): for x in range(16): for y in range(16): unicorn.set_pixel(x,y,red,green,blue) unicorn.show() # Animation for when a shot is a hit def hit_flash(self,count): for repeat in range(count): self.flood_colour(255,0,0) time.sleep(0.2) self.flood_colour(255,255,0) time.sleep(0.2) self.flood_colour(0,0,255) time.sleep(0.5) # Animation for when a shot is a miss def miss_flash(self): self.flood_colour(255,255,255) time.sleep(0.3) for a in range(0,255,10): self.flood_colour(0,0,a) # Animation for targetting using passed co-ordinates def target_flash(self,x,y): for a in range(16): unicorn.set_pixel(x,a,0,200,0) unicorn.show() time.sleep(0.05) for a in range(16): unicorn.set_pixel(a,y,0,200,0) unicorn.show() time.sleep(0.05) time.sleep(1) for a in range(0,255,10): unicorn.set_pixel(x,y,a,a,a) unicorn.show() time.sleep(0.01) for a in range(0,255,10): unicorn.set_pixel(x,y,255-a,255-a,255-a) unicorn.show() time.sleep(0.01) # Animation for when the game is lost def defeated(self): for fade in range(0,255): for y in range(16): for x in range(16): unicorn.set_pixel(x,y,255,255-fade,255-fade) unicorn.show() time.sleep(0.01) # Animation for when the game is won def victory(self): for fade in range(0,255): for y in range(16): for x in range(16): unicorn.set_pixel(x,y,255-fade,255,255-fade) unicorn.show() time.sleep(0.01) # Place a boat of the passed size on the game board # There is no limit to the number of boats placed though # if too many boats are placed it might not be possible to # place more and the program will get stuck in an infinite loop # A "1" is placed in the water 2D array for each part of the boat # The ships variable is updated to reflect the number of boat parts # on the game area in total after the boat it placed. def boat(self, size): boat_mask = [] for a in range(size): boat_mask.append(0) orientation = random.choice(["horizontal","vertical"]) if orientation == "horizontal": x = random.randint(0,16-size) y = random.randint(0,15) placement = [] for a in range(size): placement.append(self.water[y][x+a]) while placement != boat_mask: x = random.randint(0,16-size) y = random.randint(0,15) placement = [] for a in range(size): placement.append(self.water[y][x+a]) for a in range(size): self.water[y][x+a] = 1 else: x = random.randint(0,15) y = random.randint(0,16-size) placement = [] for a in range(size): placement.append(self.water[y+a][x]) while placement != boat_mask: x = random.randint(0,16-size) y = random.randint(0,15) placement = [] for a in range(size): placement.append(self.water[y+a][x]) for a in range(size): self.water[y+a][x]=1 self.ships += size # Process a shot using the passed co-ordinates on the game area # determine if the shot is a hit, miss or an already hit area. # The game area is then updated and the updated game area is displayed # on the unicorn hat. def shot(self,x,y): if self.water[y][x] == 1: print("Hit") self.water[y][x] = 3 self.hit_flash(3) self.ships -= 1 elif self.water[y][x] == 2: print("You have already hit this area.") else: print("Miss") self.water[y][x] = 2 self.miss_flash() self.ammo -= 1 self.display_water() # Enter and validate a co-ordinate def enter_coord(direction): valid = False while valid != True: try: co_ord = int(input("Enter the "+direction+"-cordinate for your shot: ")) if co_ord in range(1,17): valid = True else: print("Must be a number between 1 and 16.") except: print("Must be an number between 1 and 16.") if direction == "x": co_ord = co_ord - 1 else: co_ord = 16 - co_ord return co_ord # Main Program # Declare an instance of the game area ocean = ocean() # Main program loop while True: # Initialise the game area ocean.reset() ocean.boat(5) ocean.boat(3) ocean.boat(3) ocean.boat(2) ocean.boat(2) ocean.ammo = 20 game_over = False # Display the initial game area to the Unicornhat ocean.display_water() # Loop until game over conditions are met while game_over == False: # Display current game stats to the screen print("\nYou have",ocean.ammo,"shots left") print("There are",ocean.ships,"targets in our waters.") print("") # Get x and y co-ordinates of the shot x = enter_coord("x") y = enter_coord("y") # Targetting animation ocean.target_flash(x,y) # Process the shot ocean.shot(x,y) # Check if the game over conditions are met if ocean.ships == 0 or ocean.ammo == 0: game_over = True # If the game is over because it is lost display game over if ocean.ammo == 0: print("\nOur fleet is defeated.") ocean.defeated() # Else if it is over because the game is won display victory elif ocean.ships == 0: print("\nOur fleet is victorious.") ocean.victory() # Ask if the player wants another game repeat = input("\nDo you want a rematch? ").lower() # If the player doesn't want to play again quit the program if repeat in ["no","n"]: print("Thanks for playing") break
Have fun !!!
Contribute to this site maintenance !
This is a self hosted site, on own hardware and Internet connection. The old, down to earth way 🙂. If you think that you found something useful here please contribute. Choose the form below (default 1 EUR) or donate using Bitcoin (default 0.0001 BTC) using the QR code. Thank you !
€1.00