Rebecca Jiang
Published

Raining Wealth" on UNIHIKER K10

# Interactive Digital Art: "Raining Wealth" on UNIHIKER K10

BeginnerFull instructions provided2 hours24

Things used in this project

Hardware components

DFRobot UNIHIKER K10 AI Coding Board
×1
USB Cable, USB Type C Plug
USB Cable, USB Type C Plug
×1

Software apps and online services

VS Code
Microsoft VS Code
PlatformIO IDE
PlatformIO IDE

Story

Read more

Code

Interactive Digital Art: "Raining Wealth" on UNIHIKER K10

C/C++
#include <Arduino.h>
#include "unihiker_k10.h"

// 
UNIHIKER_K10 k10;
AHT20 aht20;

// 
const int SCREEN_W = 240;
const int SCREEN_H = 320;

// 
// 
const uint32_t COLOR_BG = 0xB00000;       
//  ()
const uint32_t COLOR_COIN_1 = 0xFFD700;       // 
const uint32_t COLOR_COIN_2 = 0xDAA520;       //  (GoldenRod)
const uint32_t COLOR_COIN_OUTLINE = 0xB8860B; //  (DarkGoldenRod)

// 
struct Coin {
    int x;
    float y;
    int r;
    uint32_t color; 
    bool is_falling;
    float speed;
};

// 
const int MAX_COINS = 80; // +
Coin coins[MAX_COINS];
int coin_count = 0;

// 
float base_temp = 0.0;
float next_trigger_temp = 0.0;
bool first_reading = true;

// ---------------------------------------------------------
//  ()
// ---------------------------------------------------------

void drawCoin(const Coin& item) {
    // 
    if (item.r < 3 || item.y > SCREEN_H + item.r + 10) return;

    int x = item.x;
    int y = (int)item.y;
    int r = item.r;
    
    // 1.  ()
    // x, y, r, , , 
    // 
    k10.canvas->canvasCircle(x, y, r, item.color, item.color, true);
    
    // 2.  ()
    k10.canvas->canvasCircle(x, y, r, COLOR_COIN_OUTLINE, 0, false);
    
    // 3.  ()
    //  0.5  0.6 
    int hole_size = r * 0.6;
    int half_hole = hole_size / 2;
    
    // 
    k10.canvas->canvasRectangle(x - half_hole, y - half_hole, hole_size, hole_size, COLOR_BG, COLOR_BG, true);
    
    // 4.  ()
    // k10.canvas->canvasRectangle(x - half_hole, y - half_hole, hole_size, hole_size, COLOR_COIN_OUTLINE, 0, false);
}

// 
void addCoin(int x, int y, int r, uint32_t color) {
    if (coin_count >= MAX_COINS) return;
    
    coins[coin_count].x = x;
    coins[coin_count].y = y;
    coins[coin_count].r = r;
    coins[coin_count].color = color;
    coins[coin_count].is_falling = false;
    coins[coin_count].speed = random(6, 12); 
    
    coin_count++;
}

// ---------------------------------------------------------
//  (/)
// ---------------------------------------------------------

void generateLayout() {
    coin_count = 0; 
    
    // 1
    for (int i = 0; i < 35; i++) {
        int x = random(0, SCREEN_W);
        int y = random(0, SCREEN_H);
        int size = random(6, 12); 
        uint32_t color = (random(0, 2) == 0) ? COLOR_COIN_2 : COLOR_COIN_1;
        addCoin(x, y, size, color);
    }

    // 2 ()
    int grid_size = 55;
    for (int y = 25; y < SCREEN_H + 20; y += grid_size) {
        for (int x = 25; x < SCREEN_W + 20; x += grid_size) {
            // 
            int pos_x = x + random(-12, 12);
            int pos_y = y + random(-12, 12);
            
            // 
            int size = random(16, 26); 
            uint32_t color = (random(0, 2) == 0) ? COLOR_COIN_1 : COLOR_COIN_2;
            
            if (pos_x > -20 && pos_x < SCREEN_W + 20 && pos_y > -20 && pos_y < SCREEN_H + 20) {
                 addCoin(pos_x, pos_y, size, color);
            }
        }
    }

    // 3
    for (int i = 0; i < 3; i++) {
        int x = random(40, SCREEN_W - 40);
        int y = random(40, SCREEN_H - 40);
        int size = random(32, 42); 
        addCoin(x, y, size, COLOR_COIN_1);
    }
}

// ---------------------------------------------------------
// 
// ---------------------------------------------------------

void setup() {
    k10.begin();
    k10.initScreen(2); 
    k10.creatCanvas();
    
    generateLayout();
    
    // 
    k10.canvas->canvasRectangle(0, 0, SCREEN_W, SCREEN_H, COLOR_BG, COLOR_BG, true);
    for(int i=0; i<coin_count; i++) drawCoin(coins[i]);
    k10.canvas->updateCanvas();
}

// ---------------------------------------------------------
// 
// ---------------------------------------------------------

void loop() {
    //  A 
    if (k10.buttonA->isPressed()) {
        generateLayout(); 
        k10.canvas->canvasRectangle(0, 0, SCREEN_W, SCREEN_H, COLOR_BG, COLOR_BG, true);
        for(int i=0; i<coin_count; i++) drawCoin(coins[i]);
        k10.canvas->updateCanvas();
        delay(200); 
        return; 
    }

    // 
    float current_temp = aht20.getData(AHT20::eAHT20TempC);
    
    if (first_reading && current_temp > 0) {
        base_temp = current_temp;
        next_trigger_temp = base_temp + 0.02; 
        first_reading = false;
    }

    int drop_needed = 0;

    // 
    if (!first_reading) {
        int safety = 0;
        while (current_temp >= next_trigger_temp && safety < 5) {
            drop_needed++;
            next_trigger_temp += 0.02;
            safety++;
        }
        if (current_temp < next_trigger_temp - 0.05) {
             next_trigger_temp = current_temp + 0.02;
        }
    }

    //  ()
    static uint32_t last_shake_time = 0;
    //  (10001g)
    int strength = k10.getStrength();
    
    // 1500delay(30)
    //  1200 (1.2g)
    // 800 (0.8g)
    bool is_shaking = (strength > 1250) || (strength < 800);

    if (is_shaking && (millis() - last_shake_time > 800)) { // 
        // 
        for(int i=0; i<coin_count; i++) {
            coins[i].is_falling = true;
            // 
            if (coins[i].speed < 20) { // 
                coins[i].speed *= 2.0; 
            }
        }
        last_shake_time = millis();
    }

    // 
    if (drop_needed > 0) {
        int found = 0;
        int attempts = 0;
        while (found < drop_needed && attempts < 50) {
            int idx = random(0, coin_count);
            if (!coins[idx].is_falling) {
                coins[idx].is_falling = true;
                found++;
            }
            attempts++;
        }
    }

    bool animation_active = false;
    for (int i = 0; i < coin_count; i++) {
        if (coins[i].is_falling) {
            coins[i].y += coins[i].speed;
            animation_active = true;
        }
    }

    //  ()
    if (animation_active) {
        k10.canvas->canvasRectangle(0, 0, SCREEN_W, SCREEN_H, COLOR_BG, COLOR_BG, true);
        
        for (int i = 0; i < coin_count; i++) {
             drawCoin(coins[i]);
        }
        
        k10.canvas->updateCanvas();
    }
    
    delay(30);
}

Credits

Rebecca Jiang
4 projects โ€ข 5 followers
Mushroom Cloud Maker Space Operation Manager

Comments