読者です 読者をやめる 読者になる 読者になる

プログラミング素人のArduino

技術屋の末端。プログラミングは専門外。 電気回路も専門外です。 コードに間違いなど見つけられたら、気軽にコメントください。 VC#始めました。

もぐらたたきゲーム

今日作ったのは、「もぐらたたき」ゲームです。

モグラに見立てたLEDが光ったときにスイッチを押すとポイントが加算されるというものです。

モグラは今回4匹つくりました。

必要な回路構成としては、モグラに見立てたLEDとそのLEDを光らせるための制限抵抗(300Ω)、タクトスイッチとプルアップ抵抗です。

実際にはこれを4つ作ります。

■仕様

もぐらは4匹

もぐらはNo.4~7pin

当たり判定はNo.10~13pin

もぐら出現(LED点灯)時間は徐々に短くなる

もぐら出現間隔は徐々に長くなる

ゲーム時間はもぐら出現時間が指定より短くなったところで終了とする

以下がモグラ出現とモグラ当たり判定

=============================

if (timeOn > 100) {  //モグラ出現時間が一定以下になったら終了させるのでその場合分け

randNum = random(4, 8); //もぐら出現はもぐらが接続された4~7pinにランダム

Serial.print("point= ");

Serial.println(point); //ポイントカウンターを表示

timeOn = timeOn * 0.90; //出現時間を徐々に短く

timeOff = timeOff * 1.1; //出現間隔を徐々に長く

for (c = 1; c < 11; c++) {

digitalWrite(randNum, HIGH); //もぐら出現

pin10 = digitalRead(10);

pin11 = digitalRead(11);

pin12 = digitalRead(12);

pin13 = digitalRead(13);

if (pin10 + pin11 + pin12 + pin13 == 1) { //当たり判定、ここでは4つをまとめて判定

point++; //ポイント加算

}

delay(timeOn);

}

digitalWrite(randNum, LOW); //もぐら退散

delay(timeOff);

}

=============================

ここで、このプログラムの要点はもぐら出現と当たり判定です。

==========================

digitalWrite(randNum, HIGH);

pin10 = digitalRead(10);

pin11 = digitalRead(11);

pin12 = digitalRead(12);

pin13 = digitalRead(13);

if (pin10 + pin11 + pin12 + pin13 == 1) {

point++;

}

delay(timeOn);

}

digitalWrite(randNum, LOW);

delay(timeOff);

==========================

はじめはこのようにすればよいと考えましたが、

モグラ出現 → たたく→ ポイントが加算されない???

という状況になりました。

おそらくプレイヤーがLEDが光ったのを見てスイッチを押すと、

このときにはすでにプログラムは

delay(timeOn);

に入っているので、if () のところでカウントされないようです。

ためしに、先にスイッチを押して待機しているとカウントされました。

なので、

for (c = 1; c < 11; c++)

によって、モグラ出現期間中に10回、見に行くようにしてみると上手くいきました。

ですから、delay(timeOn);はモグラ出現時間の10分の1にしてあります。

また、もぐら4匹分を

pin10 or pin11 or pin12 or pin13 == 1

のようなイメージでいずれかがHIGHであるときとするために

交換可能条件である

(pin10 + pin11 + pin12 + pin13 == 1)

としました。

=============================

if (timeOn < 100) {

=============================

は、ゲーム終了条件とゲーム終了時の動作

ゲームスタートとリスタートの動作として以下のように設定しました。

============================

Serial.begin(9600);

if (Serial.available() > 0) { //シリアル入力待機

incomingByte = Serial.read();; //シリアル入力文字格納

Serial.println("GAME START!! ");

delay(1000);

timeOn = timeOn_Const; //ゲームリセット

timeOff = timeOff_Const; //ゲームリセット

============================

これまで、

Serial.printは使ってきましたが、シリアルモニタ上に入力できそうな窓があるのが気になっていました。

ここで、

if (Serial.available() > 0)

このように、Serial入力を受け付けることができます。

ここでは、

int incomingByte = 0; 

incomingByte = Serial.read();;

として、整数だけを受けるような設定にしています。

ここでは、最低限の機能にしていますが、Serial入出力を組み合わせれば

アニメーションを表示させたり、難易度設定をさせることもできるはずです。

=============================

int i ;

int k ;

int c;

int pin10 = 0;

int pin11 = 0;

int pin12 = 0;

int pin13 = 0;

int point = 0;

int timeOn_Const = 350;//10倍

int timeOn;

int timeOff_Const = 1000;

int timeOff;

int incomingByte = 0;

int randNum;

void setup() {

Serial.begin(9600);

for (i = 4; i < 8; i++) {

pinMode (i + 6, INPUT);

pinMode(i, OUTPUT);

}

randomSeed(analogRead(0)); //乱数

}

void loop() {

if (timeOn > 100) {

randNum = random(4, 8);

Serial.print("point= ");

Serial.println(point);

Serial.print(timeOn);

Serial.print(",");

Serial.println(timeOff);

timeOn = timeOn * 0.90;

timeOff = timeOff * 1.1;

for (c = 1; c < 11; c++) {

digitalWrite(randNum, HIGH);

pin10 = digitalRead(10);

pin11 = digitalRead(11);

pin12 = digitalRead(12);

pin13 = digitalRead(13);

if (pin10 + pin11 + pin12 + pin13 == 1) {

point++;

}

delay(timeOn);

}

digitalWrite(randNum, LOW);

delay(timeOff);

}

if (timeOn < 100) {

Serial.print("point= ");

Serial.println(point);

Serial.println("GAME OVER!!");

Serial.println("Type Any Key.");

for (c = 1; c < 10; c++) {

delay(100);

for (i = 4; i < 8; i++) {

digitalWrite(i, HIGH);

}

delay(100);

for (i = 4; i < 8; i++) {

digitalWrite(i, LOW);

}

}

if (Serial.available() > 0) {

incomingByte = Serial.read();;

Serial.println("GAME START!! ");

delay(1000);

timeOn = timeOn_Const;

timeOff = timeOff_Const;

}

}

}

=============================

今回はArduino Leonardo↓を使っています。

Arduino Leonardo(+Headers)