概述
啊,经典的雪球。那个充满神秘液体的透明球体,某种鳞片状的材料,通常是一个描绘某个场景的西洋镜。摇一摇,看着雪落。
在本指南中,我们将向您展示如何使用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
+关注
关注
4329文章
23188浏览量
400574
发布评论请先 登录
相关推荐
开源项目!基于ESP32的圆形显示屏互动式圣诞雪球
Intel的AI Playground入门级人工智能工具亮相
使用CJSON创建数字是一直是显示0,为什么?
Allegro X 23.11 版本更新 I 原理图设计:变体及 function 的创建与管理
![Allegro X 23.11 <b class='flag-5'>版本</b>更新 I 原理图设计:变体及 function 的<b class='flag-5'>创建</b>与管理](https://file.elecfans.com/web2/M00/27/37/poYBAGHBmA2AD7e7AAAahjWuYP4250.jpg)
英特尔发布AI创作应用AI Playground,将于今夏正式上线!
![英特尔发布AI创作应用AI <b class='flag-5'>Playground</b>,将于今夏正式上线!](https://file1.elecfans.com//web2/M00/EE/76/wKgaomZroIqAWiOAAAEJucb6ueg817.png)
评论