0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[M5StickS3入門] 画面描画を試す:ボタンで速度変更できるランダム図形デモ

0
Posted at

M5StickS3 で「表示を触る」練習として、ランダムに図形を描くスケッチを作ります。
この版では、描画に加えてボタン入力で動作を変えられるようにします。

この記事でやることは次の3つです。

  • Aボタン: 描画を速くする
  • Bボタン: 描画を遅くする
  • A+B同時押し: 画面をクリアする

描画API、ボタン入力、ループ更新の関係を1つのスケッチでまとめて確認できます。


完成コード

#include "M5Unified.h"

// 描画の待ち時間(ms)。Aで速く、Bで遅くする。
static int delayMs = 1000;
static constexpr int DELAY_MIN = 100;
static constexpr int DELAY_MAX = 2000;
static constexpr int DELAY_STEP = 100;

// 現在の操作方法と速度を上部に表示する。
static void drawStatusBar() {
    M5.Display.fillRect(0, 0, M5.Display.width(), 22, TFT_WHITE);
    M5.Display.setCursor(4, 4);
    M5.Display.setTextColor(TFT_BLACK, TFT_WHITE);
    M5.Display.printf("A: Faster  B: Slower\n%d ms", delayMs);
}

// 描画先を引数で受け取り、ランダムな四角形を描く関数。
// LovyanGFX* にしておくと、将来オフスクリーンバッファにも流用しやすい。
void draw_function(LovyanGFX* gfx)
{
    // 画面範囲内のランダム座標を作る
    int x      = rand() % gfx->width();
    int y      = rand() % gfx->height();
    // 画面幅に連動したサイズ(width / 16 + 2)
    int r      = (gfx->width() >> 4) + 2;
    // 16bitカラー値をランダム生成
    uint16_t c = rand();

    // (x, y) を中心とした四角形を描画
    gfx->fillRect(x - r, y - r, r * 2, r * 2, c);
}

void setup()
{
    // M5本体(画面・電源管理など)を初期化
    auto cfg = M5.config();
    M5.begin(cfg);

    // 文字サイズを小さめに固定(1が基本最小)
    M5.Display.setTextSize(1);

    // 毎回違う乱数列になるようシードを設定
    randomSeed(micros());

    // 背景を白で初期化
    M5.Display.clear(TFT_WHITE);
    drawStatusBar();
}

void loop()
{
    // ボタン状態更新。押下イベントを読む前に毎回呼ぶ。
    M5.update();

    // A+B同時押し: 描画領域をクリアして描き直しを開始
    if (M5.BtnA.isPressed() && M5.BtnB.isPressed()) {
        M5.Display.clear(TFT_WHITE);
        drawStatusBar();
        delay(150);
        return;
    }

    // A: 速くする / B: 遅くする
    if (M5.BtnA.wasPressed()) {
        delayMs -= DELAY_STEP;
        if (delayMs < DELAY_MIN) delayMs = DELAY_MIN;
        drawStatusBar();
    }
    if (M5.BtnB.wasPressed()) {
        delayMs += DELAY_STEP;
        if (delayMs > DELAY_MAX) delayMs = DELAY_MAX;
        drawStatusBar();
    }

    // ランダムな円を描くための座標・サイズ・色を作る
    int x      = rand() % M5.Display.width();
    int y      = rand() % M5.Display.height();
    int r      = (M5.Display.width() >> 4) + 2;
    uint16_t c = rand();

    // ランダム円を描画
    M5.Display.fillCircle(x, y, r, c);
    // ランダム四角を描画(関数経由)
    draw_function(&M5.Display);

    // ボタンで変更した速度で次の図形を追加
    delay(delayMs);
}

コードの見どころ

1. M5.update() が入力処理の起点

M5.BtnA.wasPressed()M5.BtnB.wasPressed() を正しく使うには、
ループ内で M5.update() を継続的に呼ぶ必要があります。

2. 速度調整は「状態変数」を持つ

delayMs を状態として持っておくことで、
ボタン操作で挙動が変わるUIをシンプルに作れます。

3. 描画処理を関数に分離

draw_function(LovyanGFX* gfx) のように描画処理を関数化すると、
将来バッファ描画や別画面への展開がしやすくなります。

4. 文字の改行

printf の文字列に \n を入れると改行できます。

M5.Display.printf("A: Faster  B: Slower\n%d ms", delayMs);

つまずきやすいポイント

  • 乱数を使うときに randomSeed(...) を入れないと、再起動ごとに似たパターンになりやすい
  • A+B 同時押し判定は wasPressed() より isPressed() のほうが扱いやすい場面が多い
  • delay() を長くしすぎるとボタン反応が鈍く感じる

次に拡張するなら

  • Aボタン長押しで超高速モード
  • Bボタン長押しで一時停止
  • 画面右上に描画カウント表示
  • ボタンで図形タイプ(円/四角/三角)を切り替え

描画と入力の基本が1つのスケッチで確認できるので、
この後のUIやセンサー可視化の開発にもつなげやすいです。


M5StickS3入門シリーズ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?