概述
啊,經典的雪球。那個充滿神秘液體的透明球體,某種鱗片狀的材料,通常是一個描繪某個場景的西洋鏡。搖一搖,看著雪落。
在本指南中,我們將向您展示如何使用Circuit Playground Bluefruit和TFT Gizmo創建數字版本的雪球。我們將在TFT上顯示可自定義的雪花玻璃球。您將能夠設置自定義背景,創建自定義雪花,當然還可以搖晃以清除雪球并重新開始。
所有代碼均由CircuitPython編寫。
讓我們開始吧。
由于內存限制,該項目只能在
Circuit Playground Bluefruit-低功耗藍牙
產品ID:4333
電路游樂場Bluefruit是我們在電路游樂場系列中的第三塊板,朝著完美介紹電子學和編程邁出了一步。我們已經。..。..
缺貨
缺貨
產品ID:4367
擴展并用TFT Gizmo上的螺栓擴展Circuit Playground項目,使您以堅固可靠的方式添加漂亮的彩色顯示屏。該PCB看起來像一個圓形。..
缺貨
缺貨
DIY裝飾套件-直徑6厘米-非常適合電路游樂場
產品ID:4036
您是否忍受了主流的,低調的,低技術含量的樹木裝飾品?這個季節為什么不用冬青樹的代碼裝飾大廳呢?這個DIY裝飾品。..
$ 1.95
有貨
添加到購物車
雪球球主要由三個部分組成:
背景圖片
薄片
地面上的雪
像這樣的東西:
讓我們談談每個。
背景
這很簡單。它只是圖像或純色。除了坐在那里,實際上沒有什么可做的。因此,除了加載和顯示它之外,沒有更多的代碼與之相關。
我們將只執行此處描述的內容,然后再將其保留。
薄片
這些是掉下來的漂亮的小雪花天空。我們將使用小的位圖來賦予它們形狀。我們還將允許幾種不同的下降速度,因此它們的下降速度并不相同。要做的另一件事是檢查它們是否已經降落到地面上—當前的雪水平。
要真正使薄片運動,只需更改y它們關聯的TileGrid的值。這是CircuitPython displayio的功能。有關更多信息,請參見此處和此處。因此,基本上,每個薄片將是一個單獨的TileGrid,我們將更改每個薄片的y值以使其掉落。
雪
這是地面上的雪。剛開始時,地面上沒有積雪。當薄片落下并撞擊地面時,會在薄片撞擊的整個區域中增加積雪。因此,隨著越來越多的薄片落下,該級別將增加。
我們將使用displayio位圖表示積雪。位圖大小將與屏幕大小相同。它將開始為空-完全透明。要“添加雪”,我們只需將單個像素設置為雪的顏色。
簡單的Snow Globe
讓我們從簡單的snowglobe版本開始。此版本不需要任何其他位圖文件。您可以根據需要設置背景圖像。但是,如果您沒有一個,只是想啟動并運行,就不要管它,它將使用純色。
下面是代碼:
下載:項目Zip 或 snowglobe_simple.py | 在Github上查看
復制代碼
from random import randrange
import board
import busio
import displayio
from adafruit_gizmo import tft_gizmo
import adafruit_imageload
import adafruit_lis3dh
#---| User Config |---------------
BACKGROUND = 0xAA0000 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
# Accelerometer setup
accelo_i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
accelo = adafruit_lis3dh.LIS3DH_I2C(accelo_i2c, address=0x19)
# Create the TFT Gizmo display
display = tft_gizmo.TFT_Gizmo()
# Load background image
try:
bg_bitmap, bg_palette = adafruit_imageload.load(BACKGROUND,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# Or just use solid color
except (OSError, TypeError):
BACKGROUND = BACKGROUND if isinstance(BACKGROUND, int) else 0x000000
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
# Shared palette for snow bitmaps
palette = displayio.Palette(2)
palette[0] = 0xADAF00 # transparent color
palette[1] = SNOW_COLOR # snow color
palette.make_transparent(0)
# Snowflake setup
FLAKES = (
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
)
flake_sheet = displayio.Bitmap(12, 4, len(palette))
for i, value in enumerate(FLAKES):
flake_sheet[i] = value
flake_pos = [0.0] * NUM_FLAKES
flakes = displayio.Group(max_size=NUM_FLAKES)
for _ in range(NUM_FLAKES):
flakes.append(displayio.TileGrid(flake_sheet, pixel_shader=palette,
width = 1,
height = 1,
tile_width = 4,
tile_height = 4 ) )
# Snowfield setup
snow_depth = [display.height] * display.width
snow_bmp = displayio.Bitmap(display.width, display.height, len(palette))
snow = displayio.TileGrid(snow_bmp, pixel_shader=palette)
# Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash)
def clear_the_snow():
#pylint: disable=global-statement, redefined-outer-name
global flakes, flake_pos, snow_depth
display.auto_refresh = False
for flake in flakes:
# set to a random sprite
flake[0] = randrange(0, 3)
# set to a random x location
flake.x = randrange(0, display.width)
# set random y locations, off screen to start
flake_pos = [-1.0*randrange(0, display.height) for _ in range(NUM_FLAKES)]
# reset snow level
snow_depth = [display.height] * display.width
# and snow bitmap
for i in range(display.width * display.height):
snow_bmp[i] = 0
display.auto_refresh = True
def add_snow(index, amount, steepness=2):
location = []
# local steepness check
for x in range(index - amount, index + amount):
add = False
if x == 0:
# check depth to right
if snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
elif x == display.width - 1:
# check depth to left
if snow_depth[x-1] - snow_depth[x] 《 steepness:
add = True
elif 0 《 x 《 display.width - 1:
# check depth to left AND right
if snow_depth[x-1] - snow_depth[x] 《 steepness and
snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
if add:
location.append(x)
# add where snow is not too steep
for x in location:
new_level = snow_depth[x] - 1
if new_level 》= 0:
snow_depth[x] = new_level
snow_bmp[x, new_level] = 1
while True:
clear_the_snow()
# loop until globe is full of snow
while snow_depth.count(0) 《 display.width:
# check for shake
if accelo.shake(SHAKE_THRESHOLD, 5, 0):
break
# update snowflakes
for i, flake in enumerate(flakes):
# speed based on sprite index
flake_pos[i] += 1 - flake[0] / 3
# check if snowflake has hit the ground
if int(flake_pos[i]) 》= snow_depth[flake.x]:
# add snow where it fell
add_snow(flake.x, flake[0] + 2)
# reset flake to top
flake_pos[i] = 0
# at a new x location
flake.x = randrange(0, display.width)
flake.y = int(flake_pos[i])
display.refresh()
from random import randrange
import board
import busio
import displayio
from adafruit_gizmo import tft_gizmo
import adafruit_imageload
import adafruit_lis3dh
#---| User Config |---------------
BACKGROUND = 0xAA0000 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
# Accelerometer setup
accelo_i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
accelo = adafruit_lis3dh.LIS3DH_I2C(accelo_i2c, address=0x19)
# Create the TFT Gizmo display
display = tft_gizmo.TFT_Gizmo()
# Load background image
try:
bg_bitmap, bg_palette = adafruit_imageload.load(BACKGROUND,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# Or just use solid color
except (OSError, TypeError):
BACKGROUND = BACKGROUND if isinstance(BACKGROUND, int) else 0x000000
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
# Shared palette for snow bitmaps
palette = displayio.Palette(2)
palette[0] = 0xADAF00 # transparent color
palette[1] = SNOW_COLOR # snow color
palette.make_transparent(0)
# Snowflake setup
FLAKES = (
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
)
flake_sheet = displayio.Bitmap(12, 4, len(palette))
for i, value in enumerate(FLAKES):
flake_sheet[i] = value
flake_pos = [0.0] * NUM_FLAKES
flakes = displayio.Group(max_size=NUM_FLAKES)
for _ in range(NUM_FLAKES):
flakes.append(displayio.TileGrid(flake_sheet, pixel_shader=palette,
width = 1,
height = 1,
tile_width = 4,
tile_height = 4 ) )
# Snowfield setup
snow_depth = [display.height] * display.width
snow_bmp = displayio.Bitmap(display.width, display.height, len(palette))
snow = displayio.TileGrid(snow_bmp, pixel_shader=palette)
# Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash)
def clear_the_snow():
#pylint: disable=global-statement, redefined-outer-name
global flakes, flake_pos, snow_depth
display.auto_refresh = False
for flake in flakes:
# set to a random sprite
flake[0] = randrange(0, 3)
# set to a random x location
flake.x = randrange(0, display.width)
# set random y locations, off screen to start
flake_pos = [-1.0*randrange(0, display.height) for _ in range(NUM_FLAKES)]
# reset snow level
snow_depth = [display.height] * display.width
# and snow bitmap
for i in range(display.width * display.height):
snow_bmp[i] = 0
display.auto_refresh = True
def add_snow(index, amount, steepness=2):
location = []
# local steepness check
for x in range(index - amount, index + amount):
add = False
if x == 0:
# check depth to right
if snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
elif x == display.width - 1:
# check depth to left
if snow_depth[x-1] - snow_depth[x] 《 steepness:
add = True
elif 0 《 x 《 display.width - 1:
# check depth to left AND right
if snow_depth[x-1] - snow_depth[x] 《 steepness and
snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
if add:
location.append(x)
# add where snow is not too steep
for x in location:
new_level = snow_depth[x] - 1
if new_level 》= 0:
snow_depth[x] = new_level
snow_bmp[x, new_level] = 1
while True:
clear_the_snow()
# loop until globe is full of snow
while snow_depth.count(0) 《 display.width:
# check for shake
if accelo.shake(SHAKE_THRESHOLD, 5, 0):
break
# update snowflakes
for i, flake in enumerate(flakes):
# speed based on sprite index
flake_pos[i] += 1 - flake[0] / 3
# check if snowflake has hit the ground
if int(flake_pos[i]) 》= snow_depth[flake.x]:
# add snow where it fell
add_snow(flake.x, flake[0] + 2)
# reset flake to top
flake_pos[i] = 0
# at a new x location
flake.x = randrange(0, display.width)
flake.y = int(flake_pos[i])
display.refresh()
您可以自定義的功能分組在代碼的頂部:
下載:文件
復制代碼
#---| User Config |---------------
BACKGROUND = 0xAA0000 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |--------------- #---| User Config |---------------
BACKGROUND = 0xAA0000 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
代碼注釋描述了它們的作用。以下是摘要:
BACKGROUND-背景顏色 OR 圖像文件名
NUM_FLAKES-總數薄片顯示
SNOW_COLOR-雪的顏色
SHAKE_THRESHOLD-清晰可見的振動
現在,只需繼續嘗試使用默認值按原樣運行即可。您應該在紅色背景上得到一些漂亮的白雪。
更改顏色
現在嘗試更改BACKGROUND和SNOW_COLOR值。將這些行更改為以下內容:
下載:文件
復制代碼
BACKGROUND = 0x00FF00 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFF00FF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive BACKGROUND = 0x00FF00 # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
SNOW_COLOR = 0xFF00FF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
嘿!黃雪!
更改背景
如果您為BACKGROUND指定位圖文件而不是顏色,則將加載并使用該文件。對于TFT Gizmo,文件必須是大小為240x240的索引BMP文件。您可以使用以下示例進行嘗試:
blinka_dark.bmp
下載該文件并將其復制到您的 CIRCUITPY 夾。然后將背景設置行更改為:
下載:文件
復制代碼
BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file
,然后將雪色更改回白色:
下載:文件
復制代碼
SNOW_COLOR = 0xFFFFFF # snow color SNOW_COLOR = 0xFFFFFF # snow color
運行該程序,最后應該使雪落在Blinka背景上。
更改薄片 》
您可以進行少量的薄片形狀定制。接下來,我們將提供更高級的代碼版本,使您真正做到這一點。但是,如果您愿意,可以使用以下代碼行:
下載:文件
復制代碼
FLAKES = (
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
) FLAKES = (
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
)
看看如何有3個單獨的4x4網格?這些是鱗片,每個鱗片寬4像素,高4像素。 0最終是透明的。 1最終為雪色。因此,如果您想更改薄片形狀,則可以對其進行編輯。但是只有4x4像素可以使用,因此自定義設置非常簡單。
搖晃清除
別忘了還要嘗試搖動木板以“清除”積雪球。這將清除所有積雪,并將所有雪花重置回頂部。繼續-像寶麗來一樣搖動它!
奇特的雪花玻璃球
好的,讓我們開始喜歡那些雪花。如此處所討論的,允許自定義薄片是創建“ sprite薄板”來容納薄片形狀的完美用法。
這是以要求您實際創建此sprite薄板為代價的。您還需要修改幾行代碼以提供有關Sprite Sheet布局的一些信息。但是有了此功能,再加上可設置的背景圖像,您可以真正自定義雪球了。我們將提供一些示例來幫助您入門。
這是雪花玻璃球代碼的漂亮版本:
下載:Project Zip 或 snowglobe_fancy.py | 查看Github
復制代碼
from random import randrange
import board
import busio
import displayio
from adafruit_gizmo import tft_gizmo
import adafruit_imageload
import adafruit_lis3dh
#---| User Config |---------------
BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
FLAKE_SHEET = “/flakes_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
# Accelerometer setup
accelo_i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
accelo = adafruit_lis3dh.LIS3DH_I2C(accelo_i2c, address=0x19)
# Create the TFT Gizmo display
display = tft_gizmo.TFT_Gizmo()
# Load background image
try:
bg_bitmap, bg_palette = adafruit_imageload.load(BACKGROUND,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# Or just use solid color
except (OSError, TypeError):
BACKGROUND = BACKGROUND if isinstance(BACKGROUND, int) else 0x000000
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
# Snowflake setup
flake_bitmap, flake_palette = adafruit_imageload.load(FLAKE_SHEET,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
if FLAKE_TRAN_COLOR is not None:
for i, color in enumerate(flake_palette):
if color == FLAKE_TRAN_COLOR:
flake_palette.make_transparent(i)
break
NUM_SPRITES = flake_bitmap.width // FLAKE_WIDTH * flake_bitmap.height // FLAKE_HEIGHT
flake_pos = [0.0] * NUM_FLAKES
flakes = displayio.Group(max_size=NUM_FLAKES)
for _ in range(NUM_FLAKES):
flakes.append(displayio.TileGrid(flake_bitmap, pixel_shader=flake_palette,
width = 1,
height = 1,
tile_width = FLAKE_WIDTH,
tile_height = FLAKE_HEIGHT,
x = randrange(0, display.width),
default_tile=randrange(0, NUM_SPRITES)))
# Snowfield setup
snow_depth = [display.height] * display.width
snow_palette = displayio.Palette(2)
snow_palette[0] = 0xADAF00 # transparent color
snow_palette[1] = SNOW_COLOR # snow color
snow_palette.make_transparent(0)
snow_bitmap = displayio.Bitmap(display.width, display.height, len(snow_palette))
snow = displayio.TileGrid(snow_bitmap, pixel_shader=snow_palette)
# Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash)
def clear_the_snow():
#pylint: disable=global-statement, redefined-outer-name
global flakes, flake_pos, snow_depth
display.auto_refresh = False
for flake in flakes:
# set to a random sprite
flake[0] = randrange(0, NUM_SPRITES)
# set to a random x location
flake.x = randrange(0, display.width)
# set random y locations, off screen to start
flake_pos = [-1.0*randrange(0, display.height) for _ in range(NUM_FLAKES)]
# reset snow level
snow_depth = [display.height] * display.width
# and snow bitmap
for i in range(display.width*display.height):
snow_bitmap[i] = 0
display.auto_refresh = True
def add_snow(index, amount, steepness=2):
location = []
# local steepness check
for x in range(index - amount, index + amount):
add = False
if x == 0:
# check depth to right
if snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
elif x == display.width - 1:
# check depth to left
if snow_depth[x-1] - snow_depth[x] 《 steepness:
add = True
elif 0 《 x 《 display.width - 1:
# check depth to left AND right
if snow_depth[x-1] - snow_depth[x] 《 steepness and
snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
if add:
location.append(x)
# add where snow is not too steep
for x in location:
new_level = snow_depth[x] - 1
if new_level 》= 0:
snow_depth[x] = new_level
snow_bitmap[x, new_level] = 1
while True:
clear_the_snow()
# loop until globe is full of snow
while snow_depth.count(0) 《 display.width:
# check for shake
if accelo.shake(SHAKE_THRESHOLD, 5, 0):
break
# update snowflakes
for i, flake in enumerate(flakes):
# speed based on sprite index
flake_pos[i] += 1 - flake[0] / NUM_SPRITES
# check if snowflake has hit the ground
if flake_pos[i] 》= snow_depth[flake.x]:
# add snow where it fell
add_snow(flake.x, FLAKE_WIDTH)
# reset flake to top
flake_pos[i] = 0
# at a new x location
flake.x = randrange(0, display.width)
flake.y = int(flake_pos[i])
display.refresh()
from random import randrange
import board
import busio
import displayio
from adafruit_gizmo import tft_gizmo
import adafruit_imageload
import adafruit_lis3dh
#---| User Config |---------------
BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
FLAKE_SHEET = “/flakes_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
# Accelerometer setup
accelo_i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
accelo = adafruit_lis3dh.LIS3DH_I2C(accelo_i2c, address=0x19)
# Create the TFT Gizmo display
display = tft_gizmo.TFT_Gizmo()
# Load background image
try:
bg_bitmap, bg_palette = adafruit_imageload.load(BACKGROUND,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# Or just use solid color
except (OSError, TypeError):
BACKGROUND = BACKGROUND if isinstance(BACKGROUND, int) else 0x000000
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = BACKGROUND
background = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette)
# Snowflake setup
flake_bitmap, flake_palette = adafruit_imageload.load(FLAKE_SHEET,
bitmap=displayio.Bitmap,
palette=displayio.Palette)
if FLAKE_TRAN_COLOR is not None:
for i, color in enumerate(flake_palette):
if color == FLAKE_TRAN_COLOR:
flake_palette.make_transparent(i)
break
NUM_SPRITES = flake_bitmap.width // FLAKE_WIDTH * flake_bitmap.height // FLAKE_HEIGHT
flake_pos = [0.0] * NUM_FLAKES
flakes = displayio.Group(max_size=NUM_FLAKES)
for _ in range(NUM_FLAKES):
flakes.append(displayio.TileGrid(flake_bitmap, pixel_shader=flake_palette,
width = 1,
height = 1,
tile_width = FLAKE_WIDTH,
tile_height = FLAKE_HEIGHT,
x = randrange(0, display.width),
default_tile=randrange(0, NUM_SPRITES)))
# Snowfield setup
snow_depth = [display.height] * display.width
snow_palette = displayio.Palette(2)
snow_palette[0] = 0xADAF00 # transparent color
snow_palette[1] = SNOW_COLOR # snow color
snow_palette.make_transparent(0)
snow_bitmap = displayio.Bitmap(display.width, display.height, len(snow_palette))
snow = displayio.TileGrid(snow_bitmap, pixel_shader=snow_palette)
# Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash)
def clear_the_snow():
#pylint: disable=global-statement, redefined-outer-name
global flakes, flake_pos, snow_depth
display.auto_refresh = False
for flake in flakes:
# set to a random sprite
flake[0] = randrange(0, NUM_SPRITES)
# set to a random x location
flake.x = randrange(0, display.width)
# set random y locations, off screen to start
flake_pos = [-1.0*randrange(0, display.height) for _ in range(NUM_FLAKES)]
# reset snow level
snow_depth = [display.height] * display.width
# and snow bitmap
for i in range(display.width*display.height):
snow_bitmap[i] = 0
display.auto_refresh = True
def add_snow(index, amount, steepness=2):
location = []
# local steepness check
for x in range(index - amount, index + amount):
add = False
if x == 0:
# check depth to right
if snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
elif x == display.width - 1:
# check depth to left
if snow_depth[x-1] - snow_depth[x] 《 steepness:
add = True
elif 0 《 x 《 display.width - 1:
# check depth to left AND right
if snow_depth[x-1] - snow_depth[x] 《 steepness and
snow_depth[x+1] - snow_depth[x] 《 steepness:
add = True
if add:
location.append(x)
# add where snow is not too steep
for x in location:
new_level = snow_depth[x] - 1
if new_level 》= 0:
snow_depth[x] = new_level
snow_bitmap[x, new_level] = 1
while True:
clear_the_snow()
# loop until globe is full of snow
while snow_depth.count(0) 《 display.width:
# check for shake
if accelo.shake(SHAKE_THRESHOLD, 5, 0):
break
# update snowflakes
for i, flake in enumerate(flakes):
# speed based on sprite index
flake_pos[i] += 1 - flake[0] / NUM_SPRITES
# check if snowflake has hit the ground
if flake_pos[i] 》= snow_depth[flake.x]:
# add snow where it fell
add_snow(flake.x, FLAKE_WIDTH)
# reset flake to top
flake_pos[i] = 0
# at a new x location
flake.x = randrange(0, display.width)
flake.y = int(flake_pos[i])
display.refresh()
如您所見,定制部分中還有更多項目:
下載:文件
復制代碼
#---| User Config |---------------
BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
FLAKE_SHEET = “/flakes_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |--------------- #---| User Config |---------------
BACKGROUND = “/blinka_dark.bmp” # specify color or background BMP file
NUM_FLAKES = 50 # total number of snowflakes
FLAKE_SHEET = “/flakes_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFFFFFF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
其中大多數與上一節中的簡單版本相同。新的用于指定片狀Sprite表。它們是:
FLAKE_SHEET-包含片狀精靈的BMP文件
FLAKE_WIDTH-每個精靈的寬度
FLAKE_HEIGHT-每個精靈的高度
FLAKE_TRAN_COLOR-用作透明度的顏色
FLAKE_TRAN_COLOR,最好在創建精靈表位圖時選擇簡單的內容。不要使用薄片本身中的一種顏色,因為那樣以后就不會顯示出來。
最容易混淆的兩種顏色是FLAKE_WIDTH和FLAKE_HEIGHT。您可以將它們視為每個薄片的寬度和高度。每個薄片的這些應該相同。這不是薄片的總寬度和高度,而是精靈本身。有關更深入的討論,請參見此處和此處。
背景圖片
首先,代碼將重用指南上一部分中的背景圖片。從那里的鏈接下載。確保在 CIRCUITPY 文件夾中保存文件 blinka_dark.bmp 。
簡單的Snowglobe Redux
讓我們從簡單地重新創建與上一節相同的薄片開始,但是這次使用sprite片。這是文件:
flakes_sheet.bmp
下載該文件并將其復制到您的 CIRCUITPY 文件夾中。
如果在圖像查看器中將其打開,則由于體積太小,您將看不到太多內容。但放大后,它看起來像這樣:
已添加邊框和網格以供參考。它們不是實際文件的一部分。您可以看到如何有3種不同的4x4位圖。我們需要告訴代碼,這是這些行的作用:
下載:file
復制代碼
FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height FLAKE_WIDTH = 4 # sprite width
FLAKE_HEIGHT = 4 # sprite height
帶有背景( blinka_dark.bmp )和片狀精靈工作表( flake_sheet.bmp )文件復制到您的 CIRCUITPY 文件夾中,您可以嘗試運行上面的代碼。您應該獲得與以前相同的效果-帶有簡單白色雪花的Blinka背景。
現在讓我們嘗試一些不同的事情。
誰觀看。..烏賊?
此示例更好地顯示了如何自定義雪花玻璃球。嗯我們還能從天上掉下來。魷魚呢?當然。并且背景與參考相匹配。抓取這兩個文件:
watchmen_bg.bmp
squid_sheet_16.bmp
并保存到您的 CIRCUITPY 文件夾。
然后,將自定義設置更改為此:
下載:文件
復制代碼
#---| User Config |---------------
BACKGROUND = “/watchmen_bg.bmp” # specify color or background BMP file
NUM_FLAKES = 20 # total number of snowflakes
FLAKE_SHEET = “/squid_sheet_16.bmp” # flake sprite sheet
FLAKE_WIDTH = 16 # sprite width
FLAKE_HEIGHT = 16 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0x279ED5 # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |--------------- #---| User Config |---------------
BACKGROUND = “/watchmen_bg.bmp” # specify color or background BMP file
NUM_FLAKES = 20 # total number of snowflakes
FLAKE_SHEET = “/squid_sheet_16.bmp” # flake sprite sheet
FLAKE_WIDTH = 16 # sprite width
FLAKE_HEIGHT = 16 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0x279ED5 # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
背景圖像只是另一個BMP文件。除此之外,沒有什么新內容。
sprite表單卻大不相同。薄片較大-16 x16。它們還包含多種顏色。放大,看起來像這樣:
薄片總數有所減少,因為它們是較大的薄片。為了使雪與魷魚匹配,將其設置為藍色。
在復制所有內容并進行其他更改之后,再次運行代碼,您應該得到:
魷魚!
玩得開心!
通過薄片自定義功能獲得樂趣。好像有貓和狗的薄片嗎?也許是青蛙?墮落的心可能很好。或者只是更奇特的雪花。由您決定。
還有什么可以從天上掉下來?這里還有一個給您。但是您必須加載這些文件才能查看。..
wg_bg.bmp
wg_sheet.bmp
下載:文件
復制代碼
#---| User Config |---------------
BACKGROUND = “/wg_bg.bmp” # specify color or background BMP file
NUM_FLAKES = 20 # total number of snowflakes
FLAKE_SHEET = “/wg_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 20 # sprite width
FLAKE_HEIGHT = 20 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFF00FF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |--------------- #---| User Config |---------------
BACKGROUND = “/wg_bg.bmp” # specify color or background BMP file
NUM_FLAKES = 20 # total number of snowflakes
FLAKE_SHEET = “/wg_sheet.bmp” # flake sprite sheet
FLAKE_WIDTH = 20 # sprite width
FLAKE_HEIGHT = 20 # sprite height
FLAKE_TRAN_COLOR = 0x000000 # transparency color
SNOW_COLOR = 0xFF00FF # snow color
SHAKE_THRESHOLD = 27 # shake sensitivity, lower=more sensitive
#---| User Config |---------------
更多詳細信息
制作精靈表格
主鍵是將文件另存為索引位圖圖像文件。然后可以使用CircuitPython圖像加載庫加載它們。確切的操作方式取決于所使用的軟件。本指南中的精靈表是使用GIMP創建的。總體過程如下:
創建新的圖像寬x高像素
使用1像素鉛筆工具繪制精靈
另存為.xcf文件以供將來編輯
準備導出時:
圖像-》模式-》索引
文件-》導出為。..
使用.bmp擴展名指定文件名
類似的導出方法可用于背景圖像。
薄片落下速度
那么如何實現不同的薄片落下速度?好吧,很簡單。速度基于薄片指數。歸結為這一行代碼(從高級版本開始):
下載:文件
復制代碼
flake_pos[i] += 1 - flake[0] / NUM_SPRITES flake_pos[i] += 1 - flake[0] / NUM_SPRITES
第一個薄片掉落最快。最后一片雪花落得最慢。這就是為什么各種薄片示例將薄片從最小到最大排列的原因。
由于y位置是整數值,因此使用單獨的float值進行浮點數學運算。那就是存儲在flake_pos中的內容。設置薄片位置時,只需將其更改為整數即可:
下載:文件
復制代碼
flake.y = int(flake_pos[i]) flake.y = int(flake_pos[i])
一種更簡單的方法是允許設置自定義下降速度每片。但這將需要額外的存儲機制,并需要為每個片狀Sprite表格手動設置更多的工作。
另一個想法可能是以某種方式“稱量”片狀Sprite,例如它要多少個非透明像素。包含。然后以此為基礎降低速度。
動畫片?
確定。為什么不?那實在是太酷了。可以做到的。可能是將來的版本。
積雪
很容易知道薄片何時落在地面上。但是那又怎樣呢?我們如何將雪“添加”到當前累積的雪中。最簡單的方法是在薄片掉落的地方盲目添加一些像素。但是,這可能會導致下雪的“ spikey”配置文件,這看起來并不自然。
當前代碼版本試圖以一種非常簡單的方式來處理此問題。它根據周圍的雪進行局部陡度檢查,并且僅在當前不太陡峭時才添加像素。這在大多數情況下都有效,但是確實會導致看起來有些不自然的邊緣效果。
如果這樣更出色,那就太好了。另一個未來的mod。可能是雪崩模擬器嗎?
該項目是一個很好的示例,說明了如何使用多個TileGrids和Groups來創建分層的效果和動畫。背景圖像和地面上的積雪只是單個TileGrid,它填充了整個顯示。薄片更有趣。每個薄片都是TileGrid,并且僅與薄片本身一樣大。這些都添加到相同的Group中。然后將所有這三個元素,背景(TileGrid),雪(TileGrid)和薄片(Group中的TileGrid)添加到主Group在顯示屏上顯示。因此,排序在以下代碼行中很重要:
下載:文件
復制代碼
# Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash) # Add everything to display
splash = displayio.Group()
splash.append(background)
splash.append(flakes)
splash.append(snow)
display.show(splash)
責任編輯:wv
-
pcb
+關注
關注
4333文章
23210瀏覽量
401435
發布評論請先 登錄
相關推薦
開源項目!基于ESP32的圓形顯示屏互動式圣誕雪球
Intel的AI Playground入門級人工智能工具亮相
使用CJSON創建數字是一直是顯示0,為什么?
Allegro X 23.11 版本更新 I 原理圖設計:變體及 function 的創建與管理

英特爾發布AI創作應用AI Playground,將于今夏正式上線!

評論