Tufty2040: MicroPython examples.

Co-authored-by: Phil Howard <phil@pimoroni.com>
pull/373/head
thirdr 2022-06-17 14:09:02 +01:00 zatwierdzone przez Phil Howard
rodzic 0258247b4b
commit ef1bdff2bd
6 zmienionych plików z 599 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,151 @@
import time
import machine
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
rtc = machine.RTC()
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
# Tufty constants.
A = 7
B = 8
C = 15
UP = 22
DOWN = 6
LED = 25
WIDTH, HEIGHT = display.get_bounds()
display.set_backlight(1.0)
# Buttons
button_a = machine.Pin(A, machine.Pin.IN)
button_b = machine.Pin(B, machine.Pin.IN)
button_c = machine.Pin(C, machine.Pin.IN)
button_up = machine.Pin(UP, machine.Pin.IN)
button_down = machine.Pin(DOWN, machine.Pin.IN)
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
PINK = display.create_pen(214, 28, 78)
ORANGE_1 = display.create_pen(247, 126, 33)
ORANGE_2 = display.create_pen(250, 194, 19)
cursors = ["hour", "minute"]
set_clock = False
cursor = 0
last = 0
def days_in_month(month, year):
if month == 2 and ((year % 4 == 0 and year % 100 != 0) or year % 400 == 0):
return 29
return (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[month - 1]
# Button handling function
def button(pin):
global last, set_clock, cursor, year, month, day, hour, minute
time.sleep(0.01)
if not pin.value():
return
if button_a.value() and button_c.value():
machine.reset()
adjust = 0
changed = False
if pin == button_b:
set_clock = not set_clock
changed = True
if not set_clock:
rtc.datetime((year, month, day, 0, hour, minute, second, 0))
if set_clock:
if pin == button_c:
cursor += 1
cursor %= len(cursors)
if pin == button_a:
cursor -= 1
cursor %= len(cursors)
if pin == button_up:
adjust = 1
if pin == button_down:
adjust = -1
if cursors[cursor] == "hour":
hour += adjust
hour %= 24
if cursors[cursor] == "minute":
minute += adjust
minute %= 60
if set_clock or changed:
draw_clock()
# Register the button handling function with the buttons
button_down.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_up.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_a.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_b.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_c.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
def draw_clock():
display.set_pen(WHITE)
display.clear()
hr = "{:02}".format(hour)
min = "{:02}".format(minute)
sec = "{:02}".format(second)
hr_width = display.measure_text(hr, 1)
hr_offset = 15
minute_width = display.measure_text(min, 1)
minute_offset = 15
second_width = display.measure_text(sec, 1)
second_offset = 5
display.set_pen(PINK)
display.rectangle(10, 10, (hour * 13), 60)
display.set_pen(ORANGE_1)
display.rectangle(10, 85, (minute * 5), 60)
display.set_pen(ORANGE_2)
display.rectangle(10, 160, (second * 5), 60)
display.set_pen(WHITE)
display.text(hr, (hour * 13) - hr_width - hr_offset, 45, 10, 3)
display.text(min, (minute * 5) - minute_width - minute_offset, 120, 10, 3)
display.text(sec, (second * 5) - second_width - second_offset, 202, 10, 2)
display.set_pen(BLACK)
if set_clock:
if cursors[cursor] == "hour":
display.line(5, 10, 5, 70)
if cursors[cursor] == "minute":
display.line(5, 85, 5, 145)
display.update()
year, month, day, wd, hour, minute, second, _ = rtc.datetime()
last_second = second
while True:
if not set_clock:
year, month, day, wd, hour, minute, second, _ = rtc.datetime()
if second != last_second:
draw_clock()
last_second = second
time.sleep(0.01)

Wyświetl plik

@ -0,0 +1,197 @@
import time
import random
from pimoroni import Button
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
WIDTH, HEIGHT = display.get_bounds()
# Load the spritsheets so we can flip between them
tilemap = bytearray(128 * 128)
open("s4m_ur4i-pirate-tilemap.rgb332", "rb").readinto(tilemap)
character = bytearray(128 * 128)
open("s4m_ur4i-pirate-characters.rgb332", "rb").readinto(character)
display.set_spritesheet(character)
# Buttons
button_a = Button(7, invert=False)
button_b = Button(8, invert=False)
button_c = Button(9, invert=False)
button_up = Button(22, invert=False)
button_down = Button(6, invert=False)
display.set_backlight(1.0)
display.set_pen(255)
display.clear()
class Player():
def __init__(self):
self.reset()
def reset(self):
self.x = 150
self.y = 180
self.w = 15
self.h = 30
self.speed = 10
self.is_alive = True
self.lives = 3
self.score = 0
self.moving = 0
def move(self, x, y):
if self.x + x > 0 - self.w and self.x + x < WIDTH - self.w:
self.x += x
self.y += y
def sprite(self):
display.set_spritesheet(character)
display.sprite(1, 1 if self.moving else 0, self.x, self.y, 4, 0)
class Treasure():
def __init__(self):
self.w = 16
self.h = 16
self.randomize()
def sprite(self):
if not self.enabled:
return
display.set_spritesheet(tilemap)
display.sprite(4, 2, self.x, self.y, 3, 0)
def randomize(self):
self.enabled = True
self.x = random.randint(15, WIDTH - 60)
self.y = HEIGHT - 50
class Block():
def __init__(self):
self.w = 16
self.h = 16
self.is_alive = True
self.randomize()
def move(self):
self.y += self.speed
def sprite(self):
display.set_spritesheet(character)
display.sprite(10, 8, self.x, self.y, 4, 0)
def randomize(self):
self.last_update = time.time()
self.x = random.randint(10, WIDTH - self.w - 10)
self.y = -self.h
self.speed = random.randint(4, 12)
class Game():
def __init__(self):
self.player = Player()
self.block = []
self.last_new_block = 0
self.treasure = Treasure()
self.last_treasure = 0
self.SKY = display.create_pen(72, 180, 224)
for i in range(5):
self.block.append(Block())
def reset(self):
for block in self.block:
block.randomize()
self.treasure.randomize()
self.player.reset()
def get_input(self):
if button_c.read():
self.player.move(self.player.speed, 0)
self.player.moving = 0
if button_a.read():
self.player.move(-self.player.speed, 0)
self.player.moving = 1
def background(self):
display.set_spritesheet(tilemap)
display.set_pen(self.SKY)
display.clear()
for i in range(WIDTH / 32):
display.sprite(1, 2, i * 32, 210, 4, 0)
def draw(self):
self.background()
for block in self.block:
block.sprite()
display.set_pen(255)
display.text("Score: " + str(self.player.score), 10, 10, 320, 2)
self.treasure.sprite()
display.set_pen(0)
self.player.sprite()
display.update()
time.sleep(0.01)
def check_collision(self, a, b):
return a.x + a.w >= b.x and a.x <= b.x + b.w and a.y + a.h >= b.y and a.y <= b.y + b.h
def update(self):
for block in self.block:
block.move()
if block.y > HEIGHT:
block.randomize()
if block.y + block.h >= self.player.y and self.check_collision(self.player, block):
block.randomize()
self.player.is_alive = False
if self.treasure.enabled:
if self.check_collision(self.player, self.treasure):
self.player.score += 1
self.treasure.enabled = False
self.last_treasure = time.time()
if time.time() - self.last_treasure > 2:
if not self.treasure.enabled:
self.treasure.randomize()
if self.player.lives == 0:
self.player.is_alive = False
game = Game()
while True:
game.background()
display.set_pen(255)
display.text("ARGH!", 40, 35, 200, 10)
display.text("Press B to Start", 80, 150, 180, 2)
display.update()
while not button_b.read():
pass
while game.player.is_alive:
game.get_input()
game.update()
game.draw()
game.background()
display.set_pen(255)
display.text("OOPS!", 40, 35, 200, 10)
display.text("Your score: " + str(game.player.score), 50, 150, 180, 2)
display.update()
while not button_b.read():
pass
game.reset()

Wyświetl plik

@ -0,0 +1,68 @@
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
WIDTH, HEIGHT = display.get_bounds()
display.set_backlight(1.0)
# Tufty constants
A = 7
B = 8
C = 15
UP = 22
DOWN = 6
LED = 25
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
RED = display.create_pen(200, 0, 0)
# Read name from file
try:
file = open("badge.txt", "r")
name = file.readline()
file.close()
except OSError:
name = "open name.txt in thonny to edit badge :)"
text_size = 12
text_x = 0
text_y = 100
# Clear the screen
display.set_pen(WHITE)
display.clear()
display.update()
# Draws a blank badge
def draw_badge():
display.set_pen(RED)
display.rectangle(0, 0, WIDTH, 60)
display.rectangle(0, HEIGHT - 20, WIDTH, 50)
display.set_pen(WHITE)
display.text("HELLO", 125, 5, 0, 3)
display.text("My name is:", 110, 35, 320, 2)
display.update()
def calculate_text_size():
global text_size
name_width = display.measure_text(name, text_size)
# Calculate the width of the text in pixels, adjusts according to the screen width
while name_width > 290:
text_size -= 1
name_width = display.measure_text(name, text_size)
# Calculate the margin to be applied on X
margin_x = (WIDTH - name_width) / 2
return int(margin_x)
draw_badge()
text_x = calculate_text_size()
display.set_pen(BLACK)
display.text(name, text_x, text_y, 300, text_size)
display.update()

Wyświetl plik

@ -0,0 +1,46 @@
import time
import math
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
display.set_backlight(1.0)
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
# Reads name from file, and then closes the file.
try:
file = open("message.txt", "r")
message = file.readline()
file.close()
except OSError:
message = "CREATE MESSAGE.TXT IN THONNY :)"
message_length = display.measure_text(message, 10)
while True:
t = 0 # counter
x = 320 # Starting position of message, begins just off screen.
offset = 10
# How many loops it will take to scroll the whole message plus a little extra margin.
scroll = (message_length / offset) + 30
while t < scroll:
step = t + t
y = int(80 + math.sin(step / 5) * 30)
h = 100 + math.sin(step / 5) * 100
x -= offset
display.set_pen(WHITE)
display.clear()
display.set_pen(BLACK)
display.text(message, x, y, message_length, 10)
display.update()
time.sleep(0.02)
t += 1

Wyświetl plik

@ -0,0 +1,89 @@
import time
from pimoroni import Button
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
# Tufty constants
A = 7
B = 8
C = 15
UP = 22
DOWN = 6
LED = 25
WIDTH, HEIGHT = display.get_bounds()
display.set_backlight(1.0)
# Buttons
button_a = Button(7, invert=False)
button_b = Button(8, invert=False)
button_c = Button(9, invert=False)
button_up = Button(22, invert=False)
button_down = Button(6, invert=False)
# Pens
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
RED = display.create_pen(200, 0, 0)
YELLOW = display.create_pen(255, 215, 0)
def draw_area():
display.set_pen(RED)
display.clear()
display.set_pen(YELLOW)
display.text("Sketchy-Sketch", 90, 5, 0, 2)
display.set_pen(WHITE)
display.circle(55, 215, 15)
display.circle(260, 215, 15)
display.rectangle(10, 25, 300, 170)
display.update()
position_x = 15
position_y = 30
last_x = 15
last_y = 30
draw_area()
while True:
display.set_pen(0)
if button_c.raw():
if position_x < 308:
last_x = position_x
last_y = position_y
position_x += 2
if button_a.raw():
if position_x > 12:
last_x = position_x
last_y = position_y
position_x -= 2
if button_up.raw():
if position_y > 26:
last_x = position_x
last_y = position_y
position_y -= 2
if button_down.raw():
if position_y < 193:
last_x = position_x
last_y = position_y
position_y += 2
if button_b.raw():
draw_area()
position_x = 15
position_y = 30
last_x = 15
last_y = 30
display.line(last_x, last_y, position_x, position_y)
display.update()
time.sleep(0.01)

Wyświetl plik

@ -0,0 +1,48 @@
import math
import time
from picographics import PicoGraphics, DISPLAY_TUFTY_2040
display = PicoGraphics(display=DISPLAY_TUFTY_2040)
WIDTH, HEIGHT = 320, 240
display.set_backlight(1.0)
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
display.set_pen(WHITE)
display.clear()
display.update()
message = "HELLO WORLD!"
def calculate_text_size(text):
size = 20
width = display.measure_text(text, size)
while width > 280 and size > 1:
size -= 1
width = display.measure_text(text, size)
return size
size = calculate_text_size(message)
length = len(message)
while True:
display.set_pen(WHITE)
display.clear()
display.set_pen(BLACK)
t = time.ticks_ms() / 10 / size
left = int((WIDTH - ((length - 1) * size * 6)) / 2)
top = 120 - int((size * 6) / 2)
for i in range(length):
step = t + i
y = top - math.sin(step / length * math.pi) * 10
display.text(message[i], left + (i * size * 6), int(y), 0, size)
display.update()