注釈
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
参加する理由は?
エキスパートサポート:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
学び&共有:ヒントやチュートリアルを交換してスキルを向上させましょう。
独占的なプレビュー:新製品の発表や先行プレビューに早期アクセスしましょう。
特別割引:最新製品の独占割引をお楽しみください。
祭りのプロモーションとギフト:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[ ここ]をクリックして今すぐ参加しましょう!
ゲーム - スネーク
この例では、R4 Wifiボードを使用して8x12のLEDマトリックス上でクラシックなスネークゲームを実装しています。 プレイヤーは二軸ジョイスティックを使ってスネークの方向を制御します。
必要なコンポーネント
このプロジェクトでは、以下のコンポーネントが必要です。
一式を購入するのが便利です。こちらがリンクです:
名称 |
このキットのアイテム数 |
リンク |
|---|---|---|
Elite Explorer Kit |
300+ |
以下のリンクから個別に購入することもできます。
コンポーネント紹介 |
購入リンク |
|---|---|
- |
|
配線図
回路図
コード
注釈
ファイル
13_snake.inooは、パスelite-explorer-kit-main\fun_project\13_snakeoで直接開けます。または、このコードをArduino IDEにコピーしてください。
1/*
2 This code implements a simple Snake game using an Arduino Uno R4 and a
3 Joystick Module. The Snake moves based on joystick input, and the
4 objective is to eat randomly generated food without colliding with
5 the snake's body. The game ends if the snake collides with itself.
6
7 Board: Arduino Uno R4
8 Component: Joystick Module
9*/
10
11
12#include "Arduino_LED_Matrix.h"
13
14ArduinoLEDMatrix matrix;
15byte frame[8][12];
16byte flatFrame[8 * 12]; // Flattened frame for matrix.loadPixels()
17
18// Snake variables
19struct Point {
20 byte x;
21 byte y;
22};
23
24Point snake[100];
25int snakeLength = 3;
26Point food;
27int direction = 0; // 0=up, 1=right, 2=down, 3=left
28
29void setup() {
30 pinMode(A0, INPUT); // joystick X-axis
31 pinMode(A1, INPUT); // joystick Y-axis
32
33 // Initialize LED matrix
34 matrix.begin();
35
36 // Initialize snake at middle of screen
37 snake[0] = { 6, 4 };
38 snake[1] = { 6, 5 };
39 snake[2] = { 6, 6 };
40
41 // Generate initial food
42 generateFood();
43}
44
45void loop() {
46 // Read joystick input
47 int x = analogRead(A0);
48 int y = analogRead(A1);
49
50 // Determine new direction based on joystick
51 if (x > 600 && direction != 3) direction = 1;
52 else if (x < 400 && direction != 1) direction = 3;
53 else if (y > 600 && direction != 0) direction = 2;
54 else if (y < 400 && direction != 2) direction = 0;
55
56 // Move snake
57 moveSnake();
58
59 // Check for collision with food
60 if (snake[0].x == food.x && snake[0].y == food.y) {
61 snake[snakeLength] = snake[snakeLength - 1]; // Initialize the new segment
62 snakeLength++;
63 generateFood();
64 }
65
66 // Check for collision with self
67 for (int i = 1; i < snakeLength; i++) {
68 if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
69 // Reset game (or end game)
70 snakeLength = 3;
71 snake[0] = { 6, 4 };
72 snake[1] = { 6, 5 };
73 snake[2] = { 6, 6 };
74 direction = 0;
75 generateFood();
76 }
77 }
78
79 // Draw to LED matrix
80 drawFrame();
81
82 // Delay to control speed
83 delay(200);
84}
85
86void moveSnake() {
87 for (int i = snakeLength - 1; i > 0; i--) {
88 snake[i] = snake[i - 1];
89 }
90
91 // Move the head of the snake based on the direction
92 switch (direction) {
93 case 0:
94 snake[0].y = (snake[0].y - 1 + 8) % 8; // Wrap around at the top and bottom edges
95 break;
96 case 1:
97 snake[0].x = (snake[0].x + 1) % 12; // Wrap around at the right and left edges
98 break;
99 case 2:
100 snake[0].y = (snake[0].y + 1) % 8; // Wrap around at the bottom and top edges
101 break;
102 case 3:
103 snake[0].x = (snake[0].x - 1 + 12) % 12; // Wrap around at the left and right edges
104 break;
105 }
106}
107
108void generateFood() {
109 Point possibleLocations[8 * 12];
110 int idx = 0;
111
112 // Generate all possible locations for the food
113 for (int y = 0; y < 8; y++) {
114 for (int x = 0; x < 12; x++) {
115 bool overlap = false;
116
117 // Check for overlap with the snake
118 for (int i = 0; i < snakeLength; i++) {
119 if (snake[i].x == x && snake[i].y == y) {
120 overlap = true;
121 break;
122 }
123 }
124
125 if (!overlap) {
126 possibleLocations[idx++] = { x, y };
127 }
128 }
129 }
130
131 // Randomly choose a location for the food from the possible locations
132 int choice = random(0, idx);
133 food = possibleLocations[choice];
134}
135
136void drawFrame() {
137 // Clear frame
138 for (int y = 0; y < 8; y++) {
139 for (int x = 0; x < 12; x++) {
140 frame[y][x] = 0;
141 }
142 }
143
144 // Draw snake
145 for (int i = 0; i < snakeLength; i++) {
146 frame[snake[i].y][snake[i].x] = 1;
147 }
148
149 // Draw food
150 frame[food.y][food.x] = 1;
151
152 // Flatten frame array and load into LED matrix
153 int idx = 0;
154 for (int y = 0; y < 8; y++) {
155 for (int x = 0; x < 12; x++) {
156 flatFrame[idx++] = frame[y][x];
157 }
158 }
159 matrix.loadPixels(flatFrame, 8 * 12);
160 matrix.renderFrame(0);
161}
どのように動作するのか?
コードの詳細な説明はこちらです:
変数の定義と初期化
LEDマトリックス操作のための
Arduino_LED_Matrixライブラリをインポートします。 matrixはLEDマトリックスのインスタンスです。frameとflatFrameは、画面上のピクセル情報を格納・処理するための配列です。 スネークは、各ポイントがx座標とy座標を持つPoint構造体の配列として表されます。 foodは食べ物の位置を表します。directionはスネークの現在の移動方向です。setup()ジョイスティックのX軸とY軸を入力として初期化します。 LEDマトリックスを起動します。 スネークの開始位置を画面の中央で初期化します。 食べ物の初期位置をランダムに生成します。
loop()ジョイスティックからの読み取りに基づいてスネークの方向を決定します。 スネークを移動させます。 スネークの頭が食べ物に衝突するかどうかを確認します。 衝突した場合、スネークは成長し、新しい位置に新しい食べ物が生成されます。 スネークが自分自身と衝突するかどうかを確認します。衝突した場合、ゲームをリセットします。 LEDマトリックス上に現在のゲーム状態(スネークと食べ物の位置)を描きます。 ゲームの速度を制御するために遅延を加えます。
moveSnake()尾から頭にかけて、スネークの各部分を前の部分の位置に移動させます。 その方向に基づいてスネークの頭を移動させます。
generateFood()可能なすべての食べ物の位置を生成します。 各位置がスネークのいずれかの部分と重なっていないかを確認します。重なっていない場合、その位置は可能な食べ物の位置とみなされます。 可能な食べ物の位置をランダムに選択します。
drawFrame()現在のフレームをクリアします。 スネークと食べ物をフレーム上に描きます。 2次元のフレーム配列を1次元の配列(flatFrame)に平坦化し、LEDマトリックスにロードします。