注釈

こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。

参加する理由は?

  • エキスパートサポート:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。

  • 学び&共有:ヒントやチュートリアルを交換してスキルを向上させましょう。

  • 独占的なプレビュー:新製品の発表や先行プレビューに早期アクセスしましょう。

  • 特別割引:最新製品の独占割引をお楽しみください。

  • 祭りのプロモーションとギフト:ギフトや祝日のプロモーションに参加しましょう。

👉 私たちと一緒に探索し、創造する準備はできていますか?[ ここ]をクリックして今すぐ参加しましょう!

ゲーム - スネーク

この例では、R4 Wifiボードを使用して8x12のLEDマトリックス上でクラシックなスネークゲームを実装しています。 プレイヤーは二軸ジョイスティックを使ってスネークの方向を制御します。

必要なコンポーネント

このプロジェクトでは、以下のコンポーネントが必要です。

一式を購入するのが便利です。こちらがリンクです:

名称

このキットのアイテム数

リンク

Elite Explorer Kit

300+

Elite Explorer Kit

以下のリンクから個別に購入することもできます。

コンポーネント紹介

購入リンク

Arduino Uno R4 WiFi

-

ジャンパーワイヤー

購入

ジョイスティックモジュール

購入

配線図

../_images/13_snake_bb.png

回路図

../_images/13_snake_schematic.png

コード

注釈

  • ファイル 13_snake.inoo は、パス elite-explorer-kit-main\fun_project\13_snakeo で直接開けます。

  • または、このコードをArduino IDEにコピーしてください。

13_snake.ino
  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}

どのように動作するのか?

コードの詳細な説明はこちらです:

  1. 変数の定義と初期化

    LEDマトリックス操作のための Arduino_LED_Matrix ライブラリをインポートします。 matrixはLEDマトリックスのインスタンスです。 frameflatFrame は、画面上のピクセル情報を格納・処理するための配列です。 スネークは、各ポイントがx座標とy座標を持つ Point 構造体の配列として表されます。 foodは食べ物の位置を表します。 direction はスネークの現在の移動方向です。

  2. setup()

    ジョイスティックのX軸とY軸を入力として初期化します。 LEDマトリックスを起動します。 スネークの開始位置を画面の中央で初期化します。 食べ物の初期位置をランダムに生成します。

  3. loop()

    ジョイスティックからの読み取りに基づいてスネークの方向を決定します。 スネークを移動させます。 スネークの頭が食べ物に衝突するかどうかを確認します。 衝突した場合、スネークは成長し、新しい位置に新しい食べ物が生成されます。 スネークが自分自身と衝突するかどうかを確認します。衝突した場合、ゲームをリセットします。 LEDマトリックス上に現在のゲーム状態(スネークと食べ物の位置)を描きます。 ゲームの速度を制御するために遅延を加えます。

  4. moveSnake()

    尾から頭にかけて、スネークの各部分を前の部分の位置に移動させます。 その方向に基づいてスネークの頭を移動させます。

  5. generateFood()

    可能なすべての食べ物の位置を生成します。 各位置がスネークのいずれかの部分と重なっていないかを確認します。重なっていない場合、その位置は可能な食べ物の位置とみなされます。 可能な食べ物の位置をランダムに選択します。

  6. drawFrame()

    現在のフレームをクリアします。 スネークと食べ物をフレーム上に描きます。 2次元のフレーム配列を1次元の配列(flatFrame)に平坦化し、LEDマトリックスにロードします。