モグラたたき(ボタン版)
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 2 | ||||
| × | 5 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
必要なツールとマシン
> |
| |||
| ||||
|
アプリとオンラインサービス
> |
| |||
|
このプロジェクトについて
これはカスタムのモグラたたきゲームです。今のところ、基本的なゲームでプログラムされていますが、機能の更新を作成することは可能です。
主な機能:
- ゲーム自体に5つのボットン。各ボタンには、独自の明るいLEDがあります。 LEDはPWM制御されています(ゲームオーバーシーケンスに使用されます)。
- 10の選択可能なレベル。レベル1(簡単)から10(非常識)。ゲームプレイ中は、特定の時間内に正しいボタンを押す必要があります。この持続時間は各レベル内で可変です(したがって、他のステップよりも速く押す必要がある場合があります)。
- (疑似)ゲームプレイ中のランダムなボタン選択。次のステップ(押す必要のあるボタン)は常に別のボタンです。
- 2つのLED数字が表示されます。 1つは現在のスコア/カウントダウン/レベルの選択用で、もう1つはハイスコアを表示するためのものです。
- デジタルボリュームコントロール
- ハイスコア保存
- 効果音。ゲームのさまざまな状態で、内蔵スピーカーからサウンドループが再生されます。
- レーザーカットエンクロージャー
- 多くの3Dプリントパーツ
- カスタムArduinoメガシールド
エンクロージャー
まず、エンクロージャーの組み立てから始めます。
<図><図>
3Dプリントされた取り付けブラケットをトップカバーに取り付けます。
<図>必要に応じて、エンクロージャーをペイントします。
次に、LEDディスプレイマウントを取り付けます。マウントの下にボルトを配置することを忘れないでください。そうしないと、垂直バーを固定できません。
<図>Arduinoシールドを組み立てます。積み重ね可能なヘッダーの追加セットを使用したので、シールドとArduinoの間にもっとスペースがあります。
<図>背面のコントロールパネルを組み立てます。
<図>トップカバー(ボタンとLEDパネル)を組み立てます。
<図><図>
<図> <図>
背面のコントロールパネルには、2つのポテンショメータコントロールが含まれています。 1つは音量調節用、もう1つはレベル選択用です。
<図><図>
結論
終了しました!
左側のLED数字パネルで、選択したレベルを確認できます。レベル1(簡単)から10(非常識)まで選択できます。右側のLED数字パネルには、対応するレベルのハイスコアが表示されます。アクティブなゲーム中、左の数字パネルに現在のスコアが表示されます。次に、緑色のボタンを押してゲームを開始します。カウントダウン後、ゲームが始まります。
<図>
コード
- Whac_A_Mole_v1.0.0
Whac_A_Mole_v1.0.0 Arduino
VisualStudio内で記述されたArduinoコード/ * Whac_A_Mole_v1.0.0By WT040 * /#include "Wire.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" Adafruit_7segment matrix1 =Adafruit_7segment(); Adafruit_7segment matrix2 =Adafruit_7segment();#define debounceTime 10 // potmetercontrolsを宣言します#definepotmeterVolume0#define potmeterGameLevel 1 // declare amp power pin#define ampPower 32 // declare buttons#define btn1Pin 22#define btn2Pin 24#define btn3Pin 26#define btn4 28#define btn5Pin 30byte btnArray [] ={btn1Pin、btn2Pin、btn3Pin、btn4Pin、btn5Pin};#define btn1 0 // btn配列を使用する場合#definebtn2 1 // btn配列を使用する場合#definebtn3 2 // btn array#definebtn4の使用3 / // btn arrayの使用#define btn5 4 // btn配列の使用// declareボタンleds#define btnLed1Pin 9#define btnLed2Pin 10#define btnLed3Pin 11#define btnLed4Pin 12#define 13バイトbtnLedArray [] ={btnLed1Pin、btnLed2Pin、btnLed3Pin、btnLed4Pin、btnLed5Pin};#define btnLed1 0 // btn array#define btnLed2 1 // btn array#define btnLed3 2 // btn array#define btnLed4 3 // btn array#define btnLed5 4 // btnarrayを使用する場合/ / describe audio fx digitals#define fx0TriggerPin 29#define fx1TriggerPin 31#define fx2TriggerPin 33#define fx3TriggerPin 35#define fx4TriggerPin 37#define fx5TriggerPin 39#define fx6TriggerPin 41#defineバイトfxVolumeArray [] ={fxVolUpPin、fxVolDnPin};#定義fx0Trigger 0定義fxVolUpPin 51位fxVolDnPin 53byte fxTriggerArray [] ={fx0TriggerPin、fx1TriggerPin、fx2TriggerPin、fx3TriggerPin、fx4TriggerPin、fx5TriggerPin、fx6TriggerPin、fx7TriggerPin、fx8TriggerPin、fx9TriggerPin、fx10TriggerPin}定義します// btn array#define fx1Trigger1を使用する場合// btn array#define fx2Trigger2を使用する場合// btn array#define fx3Trigger3を使用する場合// btn array#definefx4Triggerを使用する場合4 // btn array#define fx5Trigger 5 // btn array#define fx6Trigger6を使用する場合// btn array#define fx7Trigger7を使用する場合// btn array#define fx8Trigger8を使用する場合// btn array#define fx9Trigger9を使用する場合// btn array#define fx10Trigger10を使用する場合// btn array#define fxVolUp0を使用する場合// btn array#define fxVolDn1を使用する場合// btnarraysignedを使用する場合intcurrentPlayingSound =-1; byte btnPressed [5 ]、ledState [5]; //点滅ledunsignedlong previousMillisLedBlink =0; //点滅する場合led#define intervalLedBlink 750 ////ゲーム開始シーケンスunsignedlong previousMillisGameStarting =0; #define intervalCountDown 1000byte gameStartCountDown; ////ゲームstepsunsigned long previousMillisGameStep =0; int gameStepLength =0; //個々のstepintgameStepBtn =0の長さ; //押す必要のあるボタン// int valPotmeterVolume =0; int volume =0; int actualVolume =35; // adafruitfxボードのボリュームintvalPotmeterGameLevel =0; int gameLevel; int currentScore; int highScore; int highScoreAddr =1; byte activeBtn; bool debug; //デバッグまたはnotbyteを有効にしますwackAMoleState; //ゲームブールの状態SystemInitialized =false; #define stateUnknown 0#define waitForStart 1#define start 2#define running 3#define gameOver 4#definestopped 5void setup(){Serial.begin(9600); //アンプの電源ピンを初期化しますpinMode(ampPower、OUTPUT); digitalWrite(ampPower、LOW); // btnピンを初期化します(int Pin =0; Pin <5; Pin ++){pinMode(btnArray [Pin]、INPUT); } // init btn led pin for(int Pin =0; Pin <5; Pin ++){pinMode(btnLedArray [Pin]、OUTPUT); } // init btn fx pin for(int Pin =0; Pin <11; Pin ++){pinMode(fxTriggerArray [Pin]、OUTPUT); digitalWrite(fxTriggerArray [Pin]、HIGH); } // init btn fx volume pin for(int Pin =0; Pin <2; Pin ++){pinMode(fxVolumeArray [Pin]、OUTPUT); digitalWrite(fxVolumeArray [Pin]、HIGH); } matrix1.begin(0x70); matrix2.begin(0x71); while(!eeprom_is_ready()); // EEPROMの準備が整うのを待ちますcli(); highScore =eeprom_read_word((uint16_t *)(gameLevel * 2)); sei(); matrix1.print(0); matrix1.writeDisplay(); matrix2.print(0); matrix2.writeDisplay(); initializeSystem();} void loop(){checkButtonInputs(); //スイッチをチェックすると、現在の状態が取得されますreadVolumePotmeter(); if(wackAMoleState ==waitForStart){playSound(fx0Trigger); if(btnPressed [btn4]){wackAMoleState =開始; } readGameLevelPotmeter(); ledBlinkStart(); } if(wackAMoleState ==start){startGame(); } if(wackAMoleState ==running){playSound(fx1Trigger); checkNextGameStep(); }} void checkNextGameStep(){unsigned long currentMillisGameStep =millis(); int amountOfButtonPresses =0; for(int btn =0; btn <5; btn ++){if(btnPressed [btn]){amountOfButtonPresses ++; }} if(previousMillisGameStep ==0){previousMillisGameStep =currentMillisGameStep; digitalWrite(btnLedArray [btnLed4]、LOW); randomSeed(analogRead(2)); gameStepBtn =random(0、5); gameStepLength =random(3000 / gameLevel、5000 / gameLevel); digitalWrite(btnLedArray [gameStepBtn]、HIGH); //新しいボタンライトを点灯} if((currentMillisGameStep --previousMillisGameStep> =gameStepLength)||(amountOfButtonPresses> 1)||(amountOfButtonPresses ==1)&&!btnPressed [gameStepBtn]){//ゲームオーバー... playSound( fx2Trigger); wackAMoleState =gameOver; previousMillisGameStep =0; for(int counter =0; counter <5; counter ++){analogWrite(btnLedArray [counter]、255); } for(int輝度=255;輝度> 0;輝度-){analogWrite(btnLedArray [btnLed1]、輝度); analogWrite(btnLedArray [btnLed2]、明るさ); analogWrite(btnLedArray [btnLed3]、明るさ); analogWrite(btnLedArray [btnLed4]、明るさ); analogWrite(btnLedArray [btnLed5]、明るさ); delay(10); } analogWrite(btnLedArray [btnLed1]、0); analogWrite(btnLedArray [btnLed2]、0); analogWrite(btnLedArray [btnLed3]、0); analogWrite(btnLedArray [btnLed4]、0); analogWrite(btnLedArray [btnLed5]、0); Serial.println( "ゲームOVer"); if(currentScore> highScore){while(!eeprom_is_ready()); // EEPROMの準備が整うのを待ちますcli(); eeprom_write_word((uint16_t *)(gameLevel * 2)、currentScore); //値をEEPROMに初期化しますsei(); } int counter =0; do {delay(1); checkButtonInputs();カウンター++; } while((counter <1000)&&!btnPressed [btn1] &&!btnPressed [btn2 &&!btnPressed [btn3] &&!btnPressed [btn4] &&!btnPressed [btn5]]); //ボタンマトリックスのリリースを待つ1 .print(0); matrix1.writeDisplay(); wackAMoleState =waitForStart; } else if(btnPressed [gameStepBtn] &&(amountOfButtonPresses ==1)){digitalWrite(btnLedArray [gameStepBtn]、LOW); // LEDの前のボタンをオフにしますintcounter =0; do {delay(1); checkButtonInputs();カウンター++; } while((counter <1000)&&btnPressed [gameStepBtn]); //ボタンのリリースを待つpreviousMillisGameStep =currentMillisGameStep; int tempStepBtn =0; do {tempStepBtn =random(0、5); gameStepLength =random(3000 / gameLevel、5000 / gameLevel); } while(gameStepBtn ==tempStepBtn); gameStepBtn =tempStepBtn; digitalWrite(btnLedArray [gameStepBtn]、HIGH); //新しいボタンを点灯しますcurrentScore ++; matrix1.print(currentScore); matrix1.writeDisplay(); if(currentScore> highScore){matrix2.print(currentScore); matrix2.writeDisplay(); }}} void ledBlinkStart()// LEDを遅滞なく点滅させる{unsignedlong currentMillisLedBlink =millis(); if(currentMillisLedBlink-previousMillisLedBlink> =intervalLedBlink){previousMillisLedBlink =currentMillisLedBlink; if(ledState [0] ==LOW){ledState [0] =HIGH; } else {ledState [0] =LOW; } digitalWrite(btnLedArray [btnLed4]、ledState [0]); //緑色のLED /ボタン}} void startGame()//ゲーム自体のシーケンスを開始{unsigned long currentMillisGameStarting =millis(); digitalWrite(btnLedArray [btnLed4]、0); //緑色のLED /ボタンをオフにしますcurrentScore =0; if(gameStartCountDown ==0){playSound(fx3Trigger); previousMillisGameStarting =millis(); gameStartCountDown =4; delay(300); matrix1.print(gameStartCountDown、DEC); matrix1.writeDisplay(); } if(currentMillisGameStarting-previousMillisGameStarting> =intervalCountDown){previousMillisGameStarting =currentMillisGameStarting; if(gameStartCountDown> 0){gameStartCountDown--; matrix1.print(gameStartCountDown、DEC); matrix1.writeDisplay(); if(gameStartCountDown ==0){wackAMoleState =実行中; }}}} void initializeSystem(){//ここに初期化コードを追加... digitalWrite(btnLedArray [btnLed1]、HIGH); delay(75); digitalWrite(btnLedArray [btnLed2]、HIGH); delay(75); digitalWrite(btnLedArray [btnLed3]、HIGH); delay(75); digitalWrite(btnLedArray [btnLed4]、HIGH); delay(75); digitalWrite(btnLedArray [btnLed5]、HIGH); delay(1000); digitalWrite(btnLedArray [btnLed5]、LOW); delay(75); digitalWrite(btnLedArray [btnLed4]、LOW); delay(75); digitalWrite(btnLedArray [btnLed3]、LOW); delay(75); digitalWrite(btnLedArray [btnLed2]、LOW); delay(75); digitalWrite(btnLedArray [btnLed1]、LOW); delay(1000); debug =true; wackAMoleState =waitForStart; initVolume(); if(actualVolume> 0){enableAmpPower(true); }} void checkButtonInputs()//ボタンの変更をチェックします{static byte previousstate [5];静的バイトcurrentstate [5];前回は静的で長い;バイトインデックス; //デバウンスif((lasttime + debounceTime)> millis()){return; } lasttime =millis(); // for(index =0; index <5; index ++){currentstate [index] =digitalRead(btnArray [index]); //ボタンを読み取りますif(currentstate [index]!=btnPressed [index]){if((btnPressed [index] ==HIGH)&&(currentstate [index] ==LOW)){if(debug){Serial.print ( "ボタンが離されました:"); Serial.println(index + 1); } btnPressed [index] =0; } if((btnPressed [index] ==LOW)&&(currentstate [index] ==HIGH)){if(debug){Serial.print( "button Pressed:"); Serial.println(インデックス+ 1); } btnPressed [index] =1; }}}} void initVolume(){valPotmeterVolume =(analogRead(potmeterVolume)/ 30); if(actualVolume> valPotmeterVolume){do {digitalWrite(fxVolumeArray [fxVolDn]、LOW); actualVolume--; delay(20); digitalWrite(fxVolumeArray [fxVolDn]、HIGH); delay(20); } while(actualVolume> valPotmeterVolume); } else if(actualVolumevalPotmeterVolume){digitalWrite(fxVolumeArray [fxVolDn]、LOW); actualVolume--; delay(40); digitalWrite(fxVolumeArray [fxVolDn]、HIGH); if(actualVolume ==0){enableAmpPower(false); }} else if(actualVolume -1){matrix2.print(highScore); } else {matrix2.print(0); } matrix2.writeDisplay();} void playSound(int sound){if(currentPlayingSound!=sound){for(int counter =0; counter <11; counter ++){digitalWrite(fxTriggerArray [counter]、HIGH); } digitalWrite(fxTriggerArray [sound]、LOW); currentPlayingSound =サウンド; }} void enableAmpPower(bool state){digitalWrite(ampPower、state);}
カスタムパーツとエンクロージャー
LasercutMDFパーツ6mm OC9CvHjuTzsYL9POZCJt.dxfLasercutMDFパーツ9mm 1irkeqvO4ABzhKqhmyG7.dxfLasercutプレキシガラスパーツ3mm j4Tnmni6dQ0KXJtiHcy1.dxfCustomArduinoメガシールド 回路図
製造プロセス