チーム1748
課題名
音階当てゲーム
研究者名
森屋吏記 根本真也
使用器具
PSoc基盤
Miniprog
シリアル通信用ケーブル
ジャンパー線 2本
スピーカー
内容
このゲームは出題者と回答者の二人で対戦する。
<操作方法>
1.出題者がキーボードで音を鳴らす。
PC,LCD上にスタートメッセージが表示され、起動音がでたらゲーム開始
出題者が下記キーから一つキーを押し、エンターキーで出題する音を登録し
スピーカーよりその音階の音が発生する。
(a:ド s:レ d:ミ f:ファ g:ソ h:ラ j:シ k:ド に対応する)
※小文字のLを入力するとゲームが終了する
※何文字か押した後エンターを押すと、はじめに押したキーに
対応した音階のみが発生する
2.回答者はその音をよく聴き、答えだと思う音階に対応したキーを押す。
起動音でドレミの音階が発生するのでよく聞き
音を頭に入れておくとよい。
3.正解か不正解か、その時点での正解数(スコア)をLCD画面に表示する。
4.3回正解したらゲームクリア、1回間違えるとゲームオーバー
クリアするとクリア音が流れ、LCD上に「GAME CLEAR」と表示される
不正解するとゲームオーバー音が流れ、LCD上にメッセージと正解数が表示される
5.ゲームを再開するときはリセットボタンを押す
※以下のような仕様になっています
LCD画面…回答者用
PC画面 …出題者用
(入力はどちらもキーボードである)
ソースコード
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
#include <stdio.h>
#pragma interrupt_handler myISR
int PW=125;
int SILENT=0,D=229,L=204,M=182,F=172,S=153,R=136,C=121,DD=115,LL=102;
int SCORE=0,LIFE=1,CLEAR=3;
int TC = 15,n=2;
void myISR(void)
{
TC += 1;
if(n == 2){ //起動音
PWM16_1_WritePulseWidth(PW);
/******ドレミ******/
if(TC == 1)
PWM16_1_WritePeriod(D);
else if(TC == 2)
PWM16_1_WritePeriod(L);
else if(TC == 3)
PWM16_1_WritePeriod(M);
else if(TC == 4)
PWM16_1_WritePeriod(F);
else if(TC == 5)
PWM16_1_WritePeriod(S);
else if(TC == 6)
PWM16_1_WritePeriod(R);
else if(TC == 7)
PWM16_1_WritePeriod(C);
else if(TC == 8)
PWM16_1_WritePeriod(DD);
else if(TC == 10)
PWM16_1_WritePeriod(SILENT); }
else if(n == 1){ //GAME OVER音
PWM16_1_WritePulseWidth(PW);
/******マリオ******/
if(TC == 1)
PWM16_1_WritePeriod(L);
else if(TC == 2)
PWM16_1_WritePeriod(DD);
else if(TC == 3)
PWM16_1_WritePeriod(SILENT);
else if(TC == 4)
PWM16_1_WritePeriod(DD);
else if(TC == 5)
PWM16_1_WritePeriod(DD);
else if(TC == 6)
PWM16_1_WritePeriod(C);
else if(TC == 7)
PWM16_1_WritePeriod(SILENT);
else if(TC == 8)
PWM16_1_WritePeriod(R);
else if(TC == 9)
PWM16_1_WritePeriod(S);
else if(TC == 10)
PWM16_1_WritePeriod(SILENT); } else if(n == 0){ //CLEAR音 PWM16_1_WritePulseWidth(M);
/******マリオ******/
if(TC == 1)
PWM16_1_WritePeriod(M);
else if(TC == 2)
PWM16_1_WritePeriod(SILENT);
else if(TC == 3)
PWM16_1_WritePeriod(M);
else if(TC == 4)
PWM16_1_WritePeriod(SILENT);
else if(TC == 5)
PWM16_1_WritePeriod(D);
else if(TC == 6)
PWM16_1_WritePeriod(M);
else if(TC == 7)
PWM16_1_WritePeriod(SILENT);
else if(TC == 8)
PWM16_1_WritePeriod(S);
else if(TC == 9)
PWM16_1_WritePeriod(SILENT); }
}
void main(void)
{
// M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts // Insert your main routine code here. char *strPtr_1; char *strPtr_2; int answer; // 正解の音 int choice; // 回答した音 int score = SCORE; // スコア char score_char[20]; // スコアの文字列化 int life = LIFE; // ライフ char life_char[20]; // ライフの文字列化 UART_CmdReset(); UART_IntCntl(UART_ENABLE_RX_INT); Counter8_WritePeriod(155); Counter8_WriteCompareValue(77); Counter8_Start(); UART_Start(UART_PARITY_NONE); M8C_EnableGInt; LCD_Start(); PWM16_1_Start(); // ゲームスタートの初期画面 // UART側に出題を要求する UART_CPutString("\r\nPSoC Synthesizer V1.1 \r\n"); UART_CPutString("\r\nSet the Answer Tone.\r\n"); // LCD LCD_PrCString("GAME START!"); //ゲーム開始とともに起動音を発生 TC=0;n=2; M8C_EnableGInt; PWM16_1_Start(); Timer16_1_EnableInt(); Timer16_1_Start(); while(1){ // 1つ目のループ 出題(鳴らす音を選ぶ) while(1){ if(UART_bCmdCheck()){ if(strPtr_1 = UART_szGetParam()){ // コマンド入力と音の発生、正解をanswerに記憶 if(*strPtr_1 == 'a'){ PWM16_1_WritePeriod(D); answer = 1; } else if(*strPtr_1 == 's'){ PWM16_1_WritePeriod(L); answer = 2; } else if(*strPtr_1 == 'd'){ PWM16_1_WritePeriod(M); answer = 3; } else if(*strPtr_1 == 'f'){ PWM16_1_WritePeriod(F); answer = 4; } else if(*strPtr_1 == 'g'){ PWM16_1_WritePeriod(S); answer = 5; } else if(*strPtr_1 == 'h'){ PWM16_1_WritePeriod(R); answer = 6; } else if(*strPtr_1 == 'j'){ PWM16_1_WritePeriod(C); answer = 7; } else if(*strPtr_1 == 'k'){ PWM16_1_WritePeriod(DD); answer = 8; } // 無音(SILENT)を選択した場合、ゲーム終了 else if(*strPtr_1 == 'l'){ PWM16_1_WritePeriod(SILENT); UART_CPutString("Bye!\r\n"); break; } UART_CmdReset(); // 回答を要求する表示 // UART UART_CPutString("Inputed your Answer from [a, s, d, f, g, h, j, k] => "); // LCD LCD_Control(0x01); LCD_Position(0,0); LCD_PrCString("Input Answer"); // 出題し、回答を要求したところで、1つ目のループを抜ける break; } } } // 2つ目のループ 回答(鳴っている音を選ぶ) while(1){ if(strPtr_2 = UART_szGetParam()){ UART_PutString(strPtr_2); PWM16_1_WritePeriod(SILENT); // コマンド入力、回答をchoiceに記憶 if(*strPtr_2 == 'a'){ choice = 1; } else if(*strPtr_2 == 's'){ choice = 2; } else if(*strPtr_2 == 'd'){ choice = 3; } else if(*strPtr_2 == 'f'){ choice = 4; } else if(*strPtr_2 == 'g'){ choice = 5; } else if(*strPtr_2 == 'h'){ choice = 6; } else if(*strPtr_2 == 'j'){ choice = 7; } else if(*strPtr_2 == 'k'){ choice = 8; } //LCDの初期化 LCD_Control(0x01); LCD_Position(0,0); // 正解の場合 if(choice == answer){ score++; // 正解の表示 if(score != CLEAR) { // UART UART_CPutString("\r\nTrue!"); // LCD LCD_PrCString("True!"); // 出力のために、int型変数をchar型配列にコピー csprintf(score_char, "%d", score); csprintf(life_char, "%d", life); } // クリアした場合(スコアがCLEARに達した場合) // クリア音を発生させる // もういちど遊ぶにはリセットを押す else { TC = 0; n = 0; csprintf(score_char, "%d", score); // UART UART_CPutString("\r\n\r\nGAME CLEAR!\r\nscore : "); UART_PutString(score_char); // LCD LCD_PrCString("GAME CLEAR!"); LCD_Position(1,0); LCD_PrCString("Score : "); LCD_PrString(score_char); //クリア音の発生 M8C_EnableGInt; PWM16_1_Start(); Timer16_1_EnableInt(); Timer16_1_Start(); while(1) {}; } } // 不正解の場合 else { life--; // 不正解の表示 if(life != 0) { // UART UART_CPutString("\r\nFalse"); // LCD LCD_PrCString("False"); // 出力のために、int型変数をchar型配列にコピー csprintf(score_char, "%d", score); csprintf(life_char, "%d", life); LCD_Position(1,0); } // ゲームオーバーの場合(ライフが0になった場合) else { n = 1; //GAME OVER音の設定 TC = 0; csprintf(score_char, "%d", score); // UART UART_CPutString("\r\n\r\nGAME OVER.\r\nscore : "); UART_PutString(score_char); // LCD の表示 // LCDへの表示とゲームオーバー音を発生させる LCD_Position(0,0); LCD_PrCString("GAME OVER."); LCD_Position(1,0); LCD_PrCString("Score : "); LCD_PrString(score_char); M8C_EnableGInt; PWM16_1_Start(); Timer16_1_EnableInt(); Timer16_1_Start(); while(1) {}; } } // スコアの表示 // UART UART_CmdReset(); UART_CPutString("\r\nscore : "); UART_PutString(score_char); // LCD LCD_Position(0,7); LCD_PrCString("Score: "); LCD_PrString(score_char); // ライフの表示 // UART UART_CPutString("\r\nlife : "); UART_PutString(life_char); // LCD LCD_Position(1,7); LCD_PrCString("Life : "); LCD_PrString(life_char); // 次の出題をUART側に要求して、2つ目のループを抜ける UART_CPutString("\r\n\r\nSet the Answer Tone.\r\n"); break; } } }
}
考察
ラボ timer_pwm2 pwm_uart2を基に音階を作成し、ゲーム内容に関しては、チーム1568の内容を参考にさせていただいた。
ゲームに挑戦し、成功した場合と失敗した場合とで、多くの人が聞いたことあるであろう音楽をそれぞれ作ったのだが、質のいい音楽が作成できたかと言われたらそうとは言い難い。また、一回でも間違うとゲームオーバーという仕様にしたので、面白みやユニークさに欠けてしまう部分があった。
実行中における改善点として、コマンドを打ち間違えると(Enterキーを2回押してしまった場合等)、そのあとのコマンドを押しても何も反応しなくなってしまった。打ち間違えた場合の対処は何も考えていなかったので、より良いゲームを作るためには、あらゆる場合にも実行が続くソースコードを記述しなければならない。
- 最終更新:2017-10-24 16:13:26