Skip to content

Instantly share code, notes, and snippets.

@deviceplususer
Created August 27, 2019 10:13
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/d2e60c32a9079357e1bd47e82d7a8e69 to your computer and use it in GitHub Desktop.
Save deviceplususer/d2e60c32a9079357e1bd47e82d7a8e69 to your computer and use it in GitHub Desktop.
1. #define WIDTH 5//LEDの横の数
2. #define HEIGHT 5//LEDの縦の数
3. #define LED_PIN 6//LEDテープの信号線
4. #define INTERVAL 750//画面切り替えのインターバル
5. #define MAX_BRIGHTNESS 32//動植物の最大の明るさ
6. #define ANIMAL_MAX_NUM 10//動物の最大数
7. #define ANIMAL_DECREASE 1//動物の体力減少
8. #define GRASS_GROWTH_NUM 3//同時に草が成長する箇所
9. #define GRASS_GROWTH_POTENTIAL 2//草が成長するスピード
10. #define KNOCK_THRESHOLD 5000//ノックと判断する閾値
11.
12. #include <MsTimer2.h>
13. #include <Adafruit_NeoPixel.h>
14. #include <Wire.h>
15. #include <Adafruit_LIS3DH.h>
16. #include <Adafruit_Sensor.h>
17.
18. struct RGB
19. {
20. int r;
21. int g;
22. int b;
23. };
24.
25. struct Animal
26. {
27. float x;
28. float y;
29. int life;
30. bool isDead;
31. RGB color;
32. };
33.
34. // LED
35. Adafruit_NeoPixel pixels;//LEDをコントロールするオブジェクト
36. int ledMatrix[WIDTH][HEIGHT];//LEDの配置と番号を記録する2次元配列
37. int grassMatrix[WIDTH][HEIGHT];//草の育成を保持する2次元配列
38. Animal animals[ANIMAL_MAX_NUM];//動物の情報を保持する配列
39.
40. //加速度センサー
41. Adafruit_LIS3DH lis = Adafruit_LIS3DH();//加速度センサーをコントロールするオブジェクト
42. long px, py, pz;//1フレーム前の加速度
43. boolean bornFlag;//次のフレームで生物が誕生するかのフラグ
44.
45.
46. void setup()
47. {
48. Serial.begin( 9600 );
49. randomSeed( analogRead(0) );
50.
51. // TIMER -------------------------
52. MsTimer2::set(INTERVAL, update);//関数updateを一定間隔ごとに呼び出すタイマー
53. MsTimer2::start();
54.
55. // NEOPIXEL --------------------
56. pixels = Adafruit_NeoPixel(WIDTH * HEIGHT, LED_PIN, NEO_GRB + NEO_KHZ800);//NeoPixelオブジェクトを生成
57. pixels.begin();
58.
59. // ACC SENSOR ------------------------
60. if (! lis.begin(0x18)) {
61. while (1);
62. }
63. lis.setRange(LIS3DH_RANGE_2_G);//加速度センサーの感度を設定。2, 4, 8, 16G
64.
65. // LED MATRIX -------------------------
66. //0~24番のLEDをX, Yの座標に置き換える
67.
68. ledMatrix[0][0] = 0;//0番のLEDは、x=0, y=0
69. ledMatrix[1][0] = 9;//9番のLEDは、x=1, y=0
70. ledMatrix[2][0] = 10;
71. ledMatrix[3][0] = 19;
72. ledMatrix[4][0] = 20;
73.
74. ledMatrix[0][1] = 1;
75. ledMatrix[1][1] = 8;
76. ledMatrix[2][1] = 11;
77. ledMatrix[3][1] = 18;
78. ledMatrix[4][1] = 21;
79.
80. ledMatrix[0][2] = 2;
81. ledMatrix[1][2] = 7;
82. ledMatrix[2][2] = 12;
83. ledMatrix[3][2] = 17;
84. ledMatrix[4][2] = 22;
85.
86. ledMatrix[0][3] = 3;
87. ledMatrix[1][3] = 6;
88. ledMatrix[2][3] = 13;
89. ledMatrix[3][3] = 16;
90. ledMatrix[4][3] = 23;
91.
92. ledMatrix[0][4] = 4;
93. ledMatrix[1][4] = 5;
94. ledMatrix[2][4] = 14;
95. ledMatrix[3][4] = 15;
96. ledMatrix[4][4] = 24;
97.
98. reset();
99. }
100.
101.
102. void loop()
103. {
104. checkKnock();//ノックされたかどうか判断する
105. delay(1);
106. }
107.
108.
109. void update()
110. {
111. // GRASS ----------------------------------------
112. grawGrass();//草が育つ
113.
114. // ANIMAL ----------------------------------------
115. for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
116. {
117. if ( !animals[i].isDead )
118. {
119. moveMaxGrass(i);//一番大きな草に向かって移動
120.
121. //現在地の草を食べて体力回復
122. animals[i].life += grassMatrix[int(animals[i].x)][int(animals[i].y)];
123. grassMatrix[int(animals[i].x)][int(animals[i].y)] = 0;
124.
125. //体力減少
126. animals[i].life -= ANIMAL_DECREASE;
127.
128. //体力が0になったら死亡
129. if ( animals[i].life <= 0 )
130. {
131. animals[i].life = 0;
132. animals[i].isDead = true;
133. }
134.
135. //体力が上限になったら増える
136. if ( animals[i].life > MAX_BRIGHTNESS )
137. {
138. animals[i].life = MAX_BRIGHTNESS / 2;
139. bornAnimal(i);
140. }
141. }
142. }
143.
144. // KNOCK ----------------------------------------
145. // 加速度センサーが反応していれば、動物を増やす
146. if ( bornFlag )
147. {
148. bornFlag = false;
149. bornAnimal(-1);
150. }
151.
152. // OUTPUT ----------------------------------------
153. setLed();//LEDに値をセットし、光らせる
154. }
155.
156.
157. void reset()
158. {
159. // ANIMAL -------------------------------------
160. for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
161. {
162. animals[i].x = random(WIDTH);
163. animals[i].y = random(HEIGHT);
164. animals[i].life = 10;
165. animals[i].color.r = random(0, 10);
166. animals[i].color.g = random(0, 10);
167. animals[i].color.b = random(0, 10);
168. animals[i].isDead = true;
169. }
170.
171. // GRASS -------------------------------------
172. for ( int y = 0; y < HEIGHT; y++)
173. {
174. for ( int x = 0; x < WIDTH; x++)
175. {
176. grassMatrix[x][y] = 0;
177. }
178. }
179.
180. // LED -------------------------------------
181. pixels.clear();
182. pixels.show();
183. }
184.
185.
186. void grawGrass()
187. {
188. for ( int i = 0; i < GRASS_GROWTH_NUM; i++)
189. {
190. int rndX = random(WIDTH);
191. int rndY = random(HEIGHT);
192. grassMatrix[rndX][rndY] += random(GRASS_GROWTH_POTENTIAL + 1); //ランダムな場所の草が成長する
193. if ( grassMatrix[rndX][rndY] > MAX_BRIGHTNESS ) grassMatrix[rndX][rndY] = MAX_BRIGHTNESS;
194. }
195. }
196.
197.
198. void moveMaxGrass( int _id )
199. {
200. // 最も成長している草の位置を調べる
201. int maxGrass = 0;
202. int maxGrassX = 0;
203. int maxGrassY = 0;
204. for ( int y = 0; y < HEIGHT; y++)
205. {
206. for ( int x = 0; x < WIDTH; x++)
207. {
208. if ( grassMatrix[x][y] > maxGrass )
209. {
210. maxGrass = grassMatrix[x][y];
211. maxGrassX = x;
212. maxGrassY = y;
213. }
214. }
215. }
216.
217. // 目標と比較して近づく
218. int nX = animals[_id].x;
219. int nY = animals[_id].y;
220. if ( (maxGrassX - animals[_id].x) > 0 )
221. {
222. nX += 1;
223. } else if ( (maxGrassX - animals[_id].x) < 0 )
224. {
225. nX -= 1;
226. }
227.
228. if ( (maxGrassY - animals[_id].y) > 0 )
229. {
230. nY += 1;
231. } else if ( (maxGrassY - animals[_id].y) < 0 )
232. {
233. nY -= 1;
234. }
235.
236. //移動先に生きている動物がいたら、移動しない
237. for ( int i = 0; i < ANIMAL_MAX_NUM; i++ )
238. {
239. if ( animals[i].x == nX && animals[i].y == nY )//XY両方とも一致している
240. {
241. if ( !animals[i].isDead )//生存している
242. {
243. if ( i != _id) //自分自身ではない
244. {
245. return;//関数を終わる
246. }
247. }
248. }
249. }
250.
251. animals[_id].x = nX;
252. animals[_id].y = nY;
253. }
254.
255.
256. void bornAnimal(int _parent)
257. {
258. int x;
259. int y;
260. int r;
261. int g;
262. int b;
263.
264. //枠の空きを探す
265. for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
266. {
267. if ( animals[i].isDead )
268. {
269.
270. if ( _parent < 0 )//振動で生まれた場合
271. {
272. x = WIDTH / 2;
273. y = HEIGHT / 2;
274. r = random(0, 15);
275. g = random(0, 15);
276. b = random(0, 15);
277.
278. } else {//親がいる場合
279. x = animals[ _parent ].x;
280. y = animals[ _parent ].y;
281. r = animals[ _parent ].color.r;
282. g = animals[ _parent ].color.g;
283. b = animals[ _parent ].color.b;
284. }
285.
286. animals[i].x = x;
287. animals[i].y = y;
288. animals[i].life = 10;
289. animals[i].color.r = r;
290. animals[i].color.g = g;
291. animals[i].color.b = b;
292. animals[i].isDead = false;
293. break;//ループを抜ける
294. }
295. }
296. }
297.
298.
299. void checkKnock() {
300. lis.read();//センサーの値を読み取り
301. long delta = abs(px - lis.x) + abs(py - lis.y) + abs(pz - lis.z);//各軸の変化量の合計
302.
303. if ( delta > KNOCK_THRESHOLD )//変化量が大きければ
304. {
305. bornFlag = true;
306. }
307.
308. px = lis.x;
309. py = lis.y;
310. pz = lis.z;
311. }
312.
313.
314. void setLed()
315. {
316. RGB rgbMatrix[WIDTH][HEIGHT];
317.
318. // GRASS --------------------------------------
319. for ( int y = 0; y < HEIGHT; y++)
320. {
321. for ( int x = 0; x < WIDTH; x++)
322. {
323. //rgbMatrixの初期化
324. rgbMatrix[x][y].r = 0;
325. rgbMatrix[x][y].g = 0;
326. rgbMatrix[x][y].b = 0;
327.
328. rgbMatrix[x][y].g += grassMatrix[x][y];//草の色を追加
329. }
330. }
331.
332. // ANIMAL --------------------------------------
333. for ( int i = 0; i < ANIMAL_MAX_NUM; i++)
334. {
335. if ( !animals[i].isDead )
336. {
337. //動物の色を追加
338. rgbMatrix[int(animals[i].x)][int(animals[i].y)].r += animals[i].color.r;
339. rgbMatrix[int(animals[i].x)][int(animals[i].y)].g += animals[i].color.g;
340. rgbMatrix[int(animals[i].x)][int(animals[i].y)].b += animals[i].color.b;
341. }
342. }
343.
344. // SET DATA ------------------------------------
345. for ( int y = 0; y < HEIGHT; y++)
346. {
347. for ( int x = 0; x < WIDTH; x++)
348. {
349. //rgbMatrixの色をLEDににセットする
350. pixels.setPixelColor( ledMatrix[x][y], pixels.Color(rgbMatrix[x][y].r, rgbMatrix[x][y].g, rgbMatrix[x][y].b ) );
351. }
352. }
353.
354. pixels.show();
355. }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment