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
    +关注

    关注

    4391

    文章

    23742

    浏览量

    420756
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    3.5寸TFT屏规格书

    关于3.5寸TFT彩屏的参考资料
    发表于 10-24 16:01 1次下载

    Quartus Prime Pro 25.1版本的安装和使用

    如果用户开发板是基于Agilex 3、Agilex 5等高阶器件,则需要安装高版本的Quartus软件比如Quartus Prime Pro 25.1版本,这个版本在安装包和license获取(免费)等方面跟以往的Quartus
    的头像 发表于 10-07 13:06 2048次阅读
    Quartus Prime Pro 25.1<b class='flag-5'>版本</b>的安装和使用

    AppGallery Connect(HarmonyOS 5及以上) --公开测试创建并发布测试版本(三)

    。 当创建了多个测试版本时,“版本列表”页面会将各测试版本按VersionName归类展示。 未上传软件包的测试版本全部归类在“Versio
    发表于 09-29 17:38

    rtthread studio 创建不了工程怎么解决?

    安装最新studio,路径默认或自选,重新安装都会创建工程不成功,报错如图 实际上首次安装rtt studio ,且电脑上并未有相关rttsudio创建的相关工程 所有安装路径、创建工程路径均没有中文 studio
    发表于 09-29 06:49

    AppGallery Connect(HarmonyOS 5及以上) --公开测试创建并发布测试版本(一)

    )的公开测试版本会自动下架。 发布测试版本 首先,您需创建并发布测试版本。最多支持1个公开测试版本在架, 1.登录AppGallery Co
    发表于 09-26 17:24

    创建并发布测试版本(二)

    :测试版本审核驳回后,状态为“审核不通过”,状态旁会显示审核不通过的原因。 • 已失效:开发者手动停止测试、复测不通过、或者到达测试截止时间时,状态会变为“已失效”,状态旁会显示已失效的原因。 当创建了多个
    发表于 09-17 15:00

    创建并发布测试版本(一)

    创建并发布测试版本,并选择您要分发的测试群组。邀请测试最多允许100个版本同时在架,邀请测试和公开测试的总计版本数量不超过100个。 1.在左侧导航栏选择“应用测试>
    发表于 09-16 15:21

    解决博途新旧版本项目兼容问题:升级操作与风险提示

    前言: 当自己电脑安装的是博途 V17 或更高版本,而项目设备程序版本较低(如 V15 或更早的 V13/V14)时,能否直接用 V17 打开这些旧版本创建的项目? 答:不能直接打开,
    的头像 发表于 09-08 16:34 1957次阅读
    解决博途新旧<b class='flag-5'>版本</b>项目兼容问题:升级操作与风险提示

    TFT显示模组有什么功能

    在咱们的日常生活里,TFT 显示模组其实一点都不陌生,家里看的电视、办公用的电脑屏幕,还有每天揣在兜里的手机屏幕,背后都离不开它的支撑。不过大家虽说常和这些带 TFT 显示模组的设备打交道,可要
    的头像 发表于 08-27 10:59 467次阅读
    <b class='flag-5'>TFT</b>显示模组有什么功能

    TFT显示原理

    *附件:TFT_LCD 显示原理_20191026.pdf
    发表于 08-26 10:22

    浅谈TFT显示屏的供电方式

    作为现代电子设备的核心视觉载体,液晶屏 的显示效果与寿命,极大程度依赖于其供电系统的精准与稳定。尤其对于TFT(薄膜晶体管)类液晶模块,其内部构造精密,包含升压电路、数字逻辑、Gamma电压、TFT
    的头像 发表于 07-16 15:49 1222次阅读

    基于ESP32的圆形显示屏圣诞主题互动式雪球

    用一款以圣诞为主题的互动式雪球让节日氛围鲜活起来!项目使用矽递科技(SeeedStudio)圆形显示屏和(XIAO)ESP32S3开发板打造出极具视觉吸引力的雪景动画,包含动态飘落的雪花、风效以及
    的头像 发表于 04-15 11:48 1051次阅读
    基于ESP32的圆形显示屏圣诞主题互动式<b class='flag-5'>雪球</b>

    请问v9版本的lvgl不能创建颜色为24bit的RGB888吗?

    v9版本的lvgl不能创建颜色为24bit的RGB888吗?
    发表于 03-21 07:47

    终章:谁将问鼎Circuit Showdown?

    https://resources.mouser.com/explore-all/the-finale-who-will-be-crowned-circuit
    发表于 03-12 09:11 244次阅读
    终章:谁将问鼎<b class='flag-5'>Circuit</b> Showdown?

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

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