0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Circuit Playground Bluefruit和TFT Gizmo创建数字版本的雪球

454398 来源:网络整理 作者:网络整理 2019-12-03 09:39 次阅读

概述

啊,经典的雪球。那个充满神秘液体的透明球体,某种鳞片状的材料,通常是一个描绘某个场景的西洋镜。摇一摇,看着雪落。

在本指南中,我们将向您展示如何使用Circuit Playground Bluefruit和TFT Gizmo创建数字版本的雪球。我们将在TFT上显示可自定义的雪花玻璃球。您将能够设置自定义背景,创建自定义雪花,当然还可以摇晃以清除雪球并重新开始。

所有代码均由CircuitPython编写。

让我们开始吧。

由于内存限制,该项目只能在

Circuit Playground Bluefruit-低功耗蓝牙

产品ID:4333

电路游乐场Bluefruit是我们在电路游乐场系列中的第三块板,朝着完美介绍电子学和编程迈出了一步。我们已经。..。..

缺货

缺货

电路游乐场TFT Gizmo-螺栓固定显示器+音频放大器

产品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
    pcb
    +关注

    关注

    4329

    文章

    23188

    浏览量

    400574
收藏 人收藏

    评论

    相关推荐

    开源项目!基于ESP32的圆形显示屏互动式圣诞雪球

    定制背景:轻松添加自己的 PNG 图像,对雪球进行个性化设置。 你将学到的内容: 如何将矽递科技圆形显示屏与xiao ESP32S3 开发板配合使用。 利用 TFT_eSPI 库实现双缓冲以呈现流畅动画
    发表于 12-16 14:24

    1.3 TFT+4按键资料分享

    1.3 TFT+4按键-资料
    发表于 11-24 15:45 3次下载

    2.0寸TFT焊接12pin-ST7789技术

    2.0寸TFT焊接12pin-ST7789技术
    发表于 11-22 16:35 0次下载

    0.96 TFT测试程序(完善版)

    电子发烧友网站提供《0.96 TFT测试程序(完善版).rar》资料免费下载
    发表于 11-21 16:18 0次下载

    Intel的AI Playground入门级人工智能工具亮相

    在今年的台北电脑展上,Intel惊艳亮相了一套面向初学者的AI探索平台——AI Playground,旨在让用户轻松体验前沿的人工智能技术与功能。近日,该平台已开放Beta版下载,集成了AI图形创作、图像增强技术及智能聊天机器人套件,但需配备至少拥有8GB显存的Intel Arc系列独立显卡方可运行。
    的头像 发表于 07-24 12:32 754次阅读

    使用CJSON创建数字是一直是显示0,为什么?

    在使用CJSON创建字符没有问题,但是创建数字是一直是显示0,代码如下: /* * Create a json format data */ root = cJSON_CreateObject
    发表于 07-22 07:02

    请问esp32_C3 click circuit电路作用是什么?

    请问下,下图中click circuit的作用是什么?
    发表于 07-01 08:02

    Allegro X 23.11 版本更新 I 原理图设计:变体及 function 的创建与管理

    基于最新的AllegroX23.11版本更新,我们将通过实例讲解、视频演示让您深入了解AllegroXSystemCapture、AllegroXPCBEditor、AllegroXPulse产品
    的头像 发表于 06-22 08:12 1197次阅读
    Allegro X 23.11 <b class='flag-5'>版本</b>更新 I 原理图设计:变体及 function 的<b class='flag-5'>创建</b>与管理

    英特尔发布AI创作应用AI Playground,将于今夏正式上线!

    的AI PC入门应用程序AI Playground,让广大用户在本地即可快速实现AI个性化创作。 英特尔Xe2 GPU架构,带来50%的性能提升 英特尔Xe2架构将被应用于Lunar Lake CPU
    的头像 发表于 06-14 09:44 569次阅读
    英特尔发布AI创作应用AI <b class='flag-5'>Playground</b>,将于今夏正式上线!

    Kill MDK如何创建Debug版本和Release版本

    如何已经有的工程,如何转换成Debug版本和Release版本
    发表于 05-11 09:06

    鸿蒙OpenHarmony【创建工程并获取源码】

    在通过DevEco Device Tool创建OpenHarmony工程时,可自动下载相应版本的OpenHarmony源码。
    的头像 发表于 04-19 21:40 445次阅读
    鸿蒙OpenHarmony【<b class='flag-5'>创建</b>工程并获取源码】

    10.1寸TFT液晶屏的尺寸、技术与应用的全面解析

    TFT液晶屏作为现代电子产品的核心部件之一,其尺寸和技术特点备受关注。在众多尺寸中,10.1寸TFT液晶屏凭借着出色的表现和广泛的应用领域,成为市场热门。
    的头像 发表于 03-26 09:34 2967次阅读

    TFT-LCD面板制作流程

    电子发烧友网站提供《TFT-LCD面板制作流程.pdf》资料免费下载
    发表于 03-24 09:32 14次下载

    TFT彩色液晶屏的基础知识详情!

    TFT(Thin-Film Transistor)彩色液晶屏是一种常见的液晶显示技术,具有以下基础知识、原理、优势和应用领域; 一 、彩色液晶屏基础知识 1、结构:TFT液晶屏由液晶层
    的头像 发表于 03-08 15:18 1464次阅读

    MotorControl Workbench 5.4.8和哪个版本的STM32CubeMX可以配合使用?

    我的MotorControl Workbench一直不能创建代码,版本是V5.4.8,cubemx版本是最新的,代码老是generation failed,请推荐一个合适的cubemx版本
    发表于 03-08 07:22