RCサーボで動かすモグラたたきゲームのプロトタイプを作ってみました。
まだ3台をつないだだけですが,ソフトやハードを試しているところです。

LEDのボタン式のモグラたたきは一応作れています。
100円ショップのLEDルームライトを使ったモグラたたきゲームの試作1号機
段ボール箱に組んだモグラたたきゲームの外装を少し整えてみた


次はモグラの動くのを,といろいろと考えてはきましたが,,やはりRCサーボが扱いやすいという事で,試作です。


3台つないだプロトタイプです。
MPUはSeeeduinoXIAO,サーボは小型のSG90タイプです。





RCサーボで上下させ,頭をヒットしたセンサーはモグラの底にキャップをつけて土台のタクトスイッチを押すようにしました。





制作途中の写真です。
3Dプリンターで作った土台にタクトスイッチを取り付けています。





動かしてみたところです。
少しフェイクの動作を入れてみたので,最初は少々惑わされます(^^)。






以下は,上の動画のソフトです。

サーボはまだ3台だけなので,ジンプルにArduinoで普通のサーボライブラリを使い,音はtone関数です(^^;;;。


1.サーボとボタンなどの関係の設定です。
 SeeeduinoXIAOのほとんどのピンを使っています,,,。


/* Xiao test2, Sound Pin 0 Servo Pin 1,2,3
Input Pin 4,5,6 LED Pin 7,8,9 Start Pin 10
*/

#include <Servo.h>

#define servo_Max 3

Servo myservo0;
Servo myservo1;
Servo myservo2;

const int L_Pos=65; // default servo position
const int M_Pos=95;
const int H_Pos=125;

void set_allservo(int ang){
for (int i=0; i < servo_Max; i++){
set_1servo(i, ang);
}
}

void set_1servo(int svn, int ang){
switch (svn) {
case 0:
myservo0.write(ang);
break;
case 1:
myservo1.write(ang);
break;
case 2:
myservo2.write(ang);
}
}

const int game_loop=30; // Init. game_basic_val
int hit_Max=0;

#define sePin 0

void setup() {

myservo0.attach(1); // servo: Pin 1,2,3
myservo1.attach(2);
myservo2.attach(3);
set_allservo(L_Pos);

pinMode(4, INPUT); //hit_switch: Pin 4,5,6
pinMode(5, INPUT);
pinMode(6, INPUT);

for (byte i=7; i<10; i++){ // LED: Pin 7,8,9
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}

pinMode(10, INPUT); // start_button: Pin 10

Serial.begin(9600); // Use UART

}




2.loop部です。
 フェイク部と実動部でできていて,実動部の設定時間内でヒットすると得点が上がります。
フェイク部では乱数の数値のビットを読んで各サーボが動くようにしてみました。何台がフェイクで動くのかもランダムになりますね(^^)。


void loop() {

disp_game_basic(game_loop,hit_Max); // Disp. basic values

/* Start button */
while (digitalRead(10)==0){}; // waiting for start
se_start(); // sound start
delay(1000);

/* Init. for new game */
randomSeed(micros()); // get randomSeed
int hit_count=0; // clear hit_count


//******** GAME LOOP ***********//
for(int m_count=0 ; m_count < game_loop; m_count++){

while(1){ /* Fake_stage */
byte ss=random(0, 16); // select random servo
if (ss < 8){
for (int i=0; i < servo_Max; i++){
if (bitRead(ss, i) == 0){
set_1servo(i, M_Pos); // move to middle position
}
}
delay (100);
set_allservo(L_Pos); // move to low position
}else{
break; // escape from the fake move
}
}

/* Real Mole_Up_stage */
byte ss1=random(0, servo_Max); // select random servo

se_Up(); // sound mole_up
set_1servo(ss1, M_Pos); // move to middle position
int hit=0;
unsigned long hit_time=500;
unsigned long delay_time=1000;
unsigned long start_time=millis();

set_1servo(ss1, H_Pos); // move to high position
while(millis()-start_time < hit_time){
if (digitalRead((ss1+4)) == 1){
hit=1;
digitalWrite((ss1+7), HIGH); // turn the LED on
se_Hit(); // sound hit the mole
}
}
hit_count += hit; // hit_count up
set_1servo(ss1, L_Pos); // move to low position
digitalWrite((ss1+7), LOW); // turn the LED low

disp_countup(m_count+1,hit_count);

delay(delay_time); // delay for next mole_up

} // game_loop end

if (hit_count > hit_Max){ // check hit_Max ?
hit_Max=hit_count;
se_Win();
}

} // loop end




3.表示と音出し部です。
 今はおまけの感じでシリアルモニタに出力していますが,7segLEDなどにする予定です。また音もゲームには必須ですから,もっと良いのが出せるようにしたいですね(^^)。


/* disp_game_basic(game_loop,hit_Max) */
void disp_game_basic(int gl, int hm){
Serial.print("Mole:");Serial.print(gl);
Serial.print(" Hit_Max:");Serial.println(hm);
}

/* disp_countup(m_count,hit_count) */
void disp_countup(int mc,int hc){
Serial.print("Mole:");Serial.print(mc);
Serial.print(" Hit:");Serial.println(hc);
}



/* SOUND C D E F G A H C_ */
// 262,294,330,349,392,440,494,523


void se_start(){
tone(sePin, 330, 100);delay(500);
tone(sePin, 330, 100);delay(500);
tone(sePin, 330, 100);delay(500);
tone(sePin, 440, 800);delay(800);
}

void se_Up(){
tone(sePin, 262, 100);delay(100);
tone(sePin, 330, 100);delay(100);
tone(sePin, 392, 100);
}

void se_Hit(){
tone(sePin, 392, 100);delay(100);
tone(sePin, 262, 300);delay(300);
}

void se_Win(){
tone(sePin, 523, 100);delay(150);
tone(sePin, 523, 100);delay(150);
tone(sePin, 523, 100);delay(150);
tone(sePin, 523, 100);delay(150);
tone(sePin, 440, 100);delay(300);
tone(sePin, 588, 100);delay(300);
tone(sePin, 523, 800);delay(800);
}



シリアルモニタにはヒットの累計の途中経過と電源が入ってからの最高得点を出しています。





ゲームはより楽しくしたり,易しくしたり難しくしたりなど工夫するところが多くて面白いですね。

ただ,そのためにも柔軟に変化に対応できるプログラムにしておかないといけませんので,,と言いつつ,ぐちゃぐちゃしてくるのを感じています(^^;;;;;;;;。