arduino Xiao ESP32C3 oled0.96 下雪花

文章介绍了如何使用XiaoESP32C3开发板配合OLED0.96显示屏实现雪花下落效果,通过随机生成半径和位置,以及处理碰撞边界来模拟雪花动态。
摘要由CSDN通过智能技术生成

Xiao ESP32C3使用oled 0.96实现下雪的功能

在这里插入图片描述

    1. 雪花下落的时候, 随机生成半径和位置 sandR和sandX,sandY
    1. 保存雪花下落位置的时候, 将其周边一圈设置为-1, 标记为有雪花
    1. 其他雪花下落的时候, 其他雪花的一圈如果遇到-1, 则停止下落, 并重复2
#include "oled.h"
void setup() {
  // 串口初始化
  Serial.begin(115200);
  oled_init();
  randomSeed(micros());
  print_vulnerability_init();
}
void run900msTasks() {
  oled.clearDisplay();
  playSnowing();
  oled.display(); // 这放到最后
}
// oled.h
#ifndef __OLED_H_
#define __OLED_H_
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64



static Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
void oled_init() {
  // oled初始化
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  Serial.println(F("SSD1306 allocation success!!!"));
  oled.display();
  delay(500); 
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  oled.setRotation(0);
  oled.clearDisplay();
  delay(1000);
}

void oled_println(int16_t x, int16_t y, const char *msg) {
    oled.setCursor(x, y);
    oled.println(msg);
}



struct snow {
  // 定义落点个数
  int numPoints = 10;
  int snows[SCREEN_WIDTH][SCREEN_HEIGHT];
  int sandX = 0;
  int sandY = 0; 
  int sandR = 1; // 半径

void init() {
  for (int i=0; i<SCREEN_WIDTH; i++) {
    for(int j=0; j<SCREEN_HEIGHT; j++) {
      snows[i][j] = 0;
    }
  }
  random_snow_pos();
}
  /**
   * 设置当前的雪花位置
  */
  void setSnow(int x, int y, int r) {
    sandX = x;
    sandY = y;
    sandR = r;
  }

  /**
   * 初始化随机点
  */
  void random_snow_pos() {
    setSnow(0, random(0, SCREEN_HEIGHT), random(2, 5));
  }

  /**
   * 将下落的雪花放到数组中
  */ 
  void snowToSnows() {
    snows[sandX][sandY] = sandR;
  }

  /**
   * 向右移动
  */
  void move(int distance) {
    sandX+=distance;
  }

  /**
  * 计算雪花点的周围一圈是否有雪花
  */
  bool collideBorder() {
    if(sandX >= SCREEN_WIDTH || sandY >= SCREEN_HEIGHT) return true;
    for (int i = 0; i < numPoints; i++) {
      float theta = (float)i / numPoints * 2 * PI;
      int x = sandX + sandR * cos(theta);
      int y = sandY + sandR * sin(theta);
      // 不管是-1还是其他, 都算是触底了
      if(x>=0 && y>=0 && snows[x][y] != 0) return true;
    }
    return false;
  }

  /**
   * 设置雪花周边都为-1
  */
  void setSnowEdge() {
    for (int i = 0; i < numPoints; i++) {
      float theta = (float)i / numPoints * 2 * PI;
      int x = sandX + sandR * cos(theta);
      int y = sandY + sandR * sin(theta);
      snows[x][y] = -1;
    }
  }

} snow;

void print_vulnerability_init() {
  for(int i=0; i<SCREEN_HEIGHT; i++) {
    snow.snows[SCREEN_WIDTH-1][i] = 1;
  }

  snow.snows[60][10] = 1;
  snow.random_snow_pos();
}

/**
 * 根据128*64的数组里面为1的点绘制○
*/
void print_snow() {
  for (int i=0; i<SCREEN_WIDTH; i++) {
    for(int j=0; j<SCREEN_HEIGHT; j++) {
      if(snow.snows[i][j] <= 0) {
        continue;
      } else {
        oled.fillCircle(i, j, snow.snows[i][j], WHITE);
      } 
    }
  }
}



/**
 * 模拟漏斗
*/
void playSnowing() {
  int while_i = 0;
  Serial.print(",");
  Serial.print(snow.sandX);
  Serial.print(",");
  Serial.println(snow.sandY);
  
  while(snow.collideBorder()) {
    snow.snowToSnows();
    snow.setSnowEdge();
    snow.random_snow_pos();
    while_i ++ ;
    if(while_i == 100) {
      snow.init();
      break;
    }
    
  }
  // 绘制沙子的点
  oled.fillCircle(snow.sandX, snow.sandY, snow.sandR, WHITE);
  // 沙子移动
  snow.move(1);
  print_snow();
}

/**
 * 1. 雪花下落的时候, 随机生成半径和位置 sandR和sandX,sandY
 * 2. 保存雪花下落位置的时候, 将其周边一圈设置为-1, 标记为有雪花
 * 3. 其他雪花下落的时候, 其他雪花的一圈如果遇到-1, 则停止下落, 并重复2
 */ 

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落子无悔!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>