Skip to content

Instantly share code, notes, and snippets.

@deviceplususer
Created August 27, 2019 10:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deviceplususer/59c4b0c2e73ba07a39e3a863fcb4ca36 to your computer and use it in GitHub Desktop.
Save deviceplususer/59c4b0c2e73ba07a39e3a863fcb4ca36 to your computer and use it in GitHub Desktop.
#define WIDTH 5//LEDの横の数
#define HEIGHT 5//LEDの縦の数
#define LED_PIN 6//LEDテープの信号線
#define INTERVAL 750//画面切り替えのインターバル
#define MAX_BRIGHTNESS 32//動植物の最大の明るさ
#define ANIMAL_MAX_NUM 10//動物の最大数
#define ANIMAL_DECREASE 1//動物の体力減少
#define GRASS_GROWTH_NUM 3//同時に草が成長する箇所
#define GRASS_GROWTH_POTENTIAL 2//草が成長するスピード
#define KNOCK_THRESHOLD 5000//ノックと判断する閾値
#include <MsTimer2.h>
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
struct RGB
{
int r;
int g;
int b;
};
struct Animal
{
float x;
float y;
int life;
bool isDead;
RGB color;
};
// LED
Adafruit_NeoPixel pixels;//LEDをコントロールするオブジェクト
int ledMatrix[WIDTH][HEIGHT];//LEDの配置と番号を記録する2次元配列
int grassMatrix[WIDTH][HEIGHT];//草の育成を保持する2次元配列
Animal animals[ANIMAL_MAX_NUM];//動物の情報を保持する配列
//加速度センサー
Adafruit_LIS3DH lis = Adafruit_LIS3DH();//加速度センサーをコントロールするオブジェクト
long px, py, pz;//1フレーム前の加速度
boolean bornFlag;//次のフレームで生物が誕生するかのフラグ
void setup()
{
Serial.begin( 9600 );
randomSeed( analogRead(0) );
// TIMER -------------------------
MsTimer2::set(INTERVAL, update);//関数updateを一定間隔ごとに呼び出すタイマー
MsTimer2::start();
// NEOPIXEL --------------------
pixels = Adafruit_NeoPixel(WIDTH * HEIGHT, LED_PIN, NEO_GRB + NEO_KHZ800);//NeoPixelオブジェクトを生成
pixels.begin();
// ACC SENSOR ------------------------
if (! lis.begin(0x18)) {
while (1);
}
lis.setRange(LIS3DH_RANGE_2_G);//加速度センサーの感度を設定。2, 4, 8, 16G
// LED MATRIX -------------------------
//0~24番のLEDをX, Yの座標に置き換える
ledMatrix[0][0] = 0;//0番のLEDは、x=0, y=0
ledMatrix[1][0] = 9;//9番のLEDは、x=1, y=0
ledMatrix[2][0] = 10;
ledMatrix[3][0] = 19;
ledMatrix[4][0] = 20;
ledMatrix[0][1] = 1;
ledMatrix[1][1] = 8;
ledMatrix[2][1] = 11;
ledMatrix[3][1] = 18;
ledMatrix[4][1] = 21;
ledMatrix[0][2] = 2;
ledMatrix[1][2] = 7;
ledMatrix[2][2] = 12;
ledMatrix[3][2] = 17;
ledMatrix[4][2] = 22;
ledMatrix[0][3] = 3;
ledMatrix[1][3] = 6;
ledMatrix[2][3] = 13;
ledMatrix[3][3] = 16;
ledMatrix[4][3] = 23;
ledMatrix[0][4] = 4;
ledMatrix[1][4] = 5;
ledMatrix[2][4] = 14;
ledMatrix[3][4] = 15;
ledMatrix[4][4] = 24;
reset();
}
void loop()
{
checkKnock();//ノックされたかどうか判断する
delay(1);
}
void update()
{
// GRASS ----------------------------------------
grawGrass();//草が育つ
// ANIMAL ----------------------------------------
for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
{
if ( !animals[i].isDead )
{
moveMaxGrass(i);//一番大きな草に向かって移動
//現在地の草を食べて体力回復
animals[i].life += grassMatrix[int(animals[i].x)][int(animals[i].y)];
grassMatrix[int(animals[i].x)][int(animals[i].y)] = 0;
//体力減少
animals[i].life -= ANIMAL_DECREASE;
//体力が0になったら死亡
if ( animals[i].life <= 0 )
{
animals[i].life = 0;
animals[i].isDead = true;
}
//体力が上限になったら増える
if ( animals[i].life > MAX_BRIGHTNESS )
{
animals[i].life = MAX_BRIGHTNESS / 2;
bornAnimal(i);
}
}
}
// KNOCK ----------------------------------------
// 加速度センサーが反応していれば、動物を増やす
if ( bornFlag )
{
bornFlag = false;
bornAnimal(-1);
}
// OUTPUT ----------------------------------------
setLed();//LEDに値をセットし、光らせる
}
void reset()
{
// ANIMAL -------------------------------------
for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
{
animals[i].x = random(WIDTH);
animals[i].y = random(HEIGHT);
animals[i].life = 10;
animals[i].color.r = random(0, 10);
animals[i].color.g = random(0, 10);
animals[i].color.b = random(0, 10);
animals[i].isDead = true;
}
// GRASS -------------------------------------
for ( int y = 0; y < HEIGHT; y++)
{
for ( int x = 0; x < WIDTH; x++)
{
grassMatrix[x][y] = 0;
}
}
// LED -------------------------------------
pixels.clear();
pixels.show();
}
void grawGrass()
{
for ( int i = 0; i < GRASS_GROWTH_NUM; i++)
{
int rndX = random(WIDTH);
int rndY = random(HEIGHT);
grassMatrix[rndX][rndY] += random(GRASS_GROWTH_POTENTIAL + 1); //ランダムな場所の草が成長する
if ( grassMatrix[rndX][rndY] > MAX_BRIGHTNESS ) grassMatrix[rndX][rndY] = MAX_BRIGHTNESS;
}
}
void moveMaxGrass( int _id )
{
// 最も成長している草の位置を調べる
int maxGrass = 0;
int maxGrassX = 0;
int maxGrassY = 0;
for ( int y = 0; y < HEIGHT; y++)
{
for ( int x = 0; x < WIDTH; x++)
{
if ( grassMatrix[x][y] > maxGrass )
{
maxGrass = grassMatrix[x][y];
maxGrassX = x;
maxGrassY = y;
}
}
}
// 目標と比較して近づく
int nX = animals[_id].x;
int nY = animals[_id].y;
if ( (maxGrassX - animals[_id].x) > 0 )
{
nX += 1;
} else if ( (maxGrassX - animals[_id].x) < 0 )
{
nX -= 1;
}
if ( (maxGrassY - animals[_id].y) > 0 )
{
nY += 1;
} else if ( (maxGrassY - animals[_id].y) < 0 )
{
nY -= 1;
}
//移動先に生きている動物がいたら、移動しない
for ( int i = 0; i < ANIMAL_MAX_NUM; i++ )
{
if ( animals[i].x == nX && animals[i].y == nY )//XY両方とも一致している
{
if ( !animals[i].isDead )//生存している
{
if ( i != _id) //自分自身ではない
{
return;//関数を終わる
}
}
}
}
animals[_id].x = nX;
animals[_id].y = nY;
}
void bornAnimal(int _parent)
{
int x;
int y;
int r;
int g;
int b;
//枠の空きを探す
for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
{
if ( animals[i].isDead )
{
if ( _parent < 0 )//振動で生まれた場合
{
x = WIDTH / 2;
y = HEIGHT / 2;
r = random(0, 15);
g = random(0, 15);
b = random(0, 15);
} else {//親がいる場合
x = animals[ _parent ].x;
y = animals[ _parent ].y;
r = animals[ _parent ].color.r;
g = animals[ _parent ].color.g;
b = animals[ _parent ].color.b;
}
animals[i].x = x;
animals[i].y = y;
animals[i].life = 10;
animals[i].color.r = r;
animals[i].color.g = g;
animals[i].color.b = b;
animals[i].isDead = false;
break;//ループを抜ける
}
}
}
void checkKnock() {
lis.read();//センサーの値を読み取り
long delta = abs(px - lis.x) + abs(py - lis.y) + abs(pz - lis.z);//各軸の変化量の合計
if ( delta > KNOCK_THRESHOLD )//変化量が大きければ
{
bornFlag = true;
}
px = lis.x;
py = lis.y;
pz = lis.z;
}
void setLed()
{
RGB rgbMatrix[WIDTH][HEIGHT];
// GRASS --------------------------------------
for ( int y = 0; y < HEIGHT; y++)
{
for ( int x = 0; x < WIDTH; x++)
{
//rgbMatrixの初期化
rgbMatrix[x][y].r = 0;
rgbMatrix[x][y].g = 0;
rgbMatrix[x][y].b = 0;
rgbMatrix[x][y].g += grassMatrix[x][y];//草の色を追加
}
}
// ANIMAL --------------------------------------
for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
{
if ( !animals[i].isDead )
{
//動物の色を追加
rgbMatrix[int(animals[i].x)][int(animals[i].y)].r += animals[i].color.r;
rgbMatrix[int(animals[i].x)][int(animals[i].y)].g += animals[i].color.g;
rgbMatrix[int(animals[i].x)][int(animals[i].y)].b += animals[i].color.b;
}
}
// SET DATA ------------------------------------
for ( int y = 0; y < HEIGHT; y++)
{
for ( int x = 0; x < WIDTH; x++)
{
//rgbMatrixの色をLEDににセットする
pixels.setPixelColor( ledMatrix[x][y], pixels.Color(rgbMatrix[x][y].r, rgbMatrix[x][y].g, rgbMatrix[x][y].b ) );
}
}
pixels.show();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment