サンプルプログラム:3 モグラたたきゲームっぽい何か。


モグラたたきゲームを実装しました。
実機との速度合わせが一番面倒で時間掛かった気がします。



音階当てゲームと構造が似てたのでそれをベースに
もぐらたたき用に書き換えたという体です。手抜きですね。


もぐらを叩いた際の効果音は 796.7Hz のものでした。
専用の再生関数をアンプモジュールに追記しました。


モグラ出現パターンは rand 関数で生成してます。
ですので実機との出現具合に違いがあると思います。
rand 関数で妥協したのは FX-マイコンシミュレータの実装も
出現パターンが rand 関数っぽかったので…。<言掛り
違ってたら済みません。


出現パターンは1回1回取っても10回分まとめて取っても
結果は同じなので最初に一括で取得してます。
デバッグプリントで次の手が分かるようにしたかっただけです。


MoleBeat.h

/*---------------------------------------------------------------------------------
	
	Sample3 MoleBeat module header
	
	version 0.01
	Nov 30, 2009
	
	By. REGEKATSU
	
---------------------------------------------------------------------------------*/

#ifndef _MOLE_BEAT_H_
#define _MOLE_BEAT_H_


#ifdef __cplusplus
extern "C" {
#endif


void MoleBeat_Update(void);
void MoleBeat_Clear(void);
bool MoleBeat_IsExit(void);


#ifdef __cplusplus
}
#endif

#endif	//_MOLE_BEAT_H_


MoleBeat.h

/*---------------------------------------------------------------------------------
	
	Sample3 MoleBeat  module routine
	
	version 0.01
	Nov 30, 2009
	
	By. REGEKATSU
	
---------------------------------------------------------------------------------*/

#include <stdio.h>//debug print

#include <stdlib.h>
#include <time.h>
#include <string.h>

#include <nds/ndstypes.h>

#include "MoleBeat.h"

#include "Outport.h"
#include "Key.h"
#include "KeyState.h"
#include "Amp.h"


#define MOLE_MAX 10


typedef enum{
	
	MOLE_BEAT_INIT,
	MOLE_BEAT_PLAY,
	MOLE_BEAT_EXIT
	
}MOLE_BEAT_ACT;


typedef enum{
	
	MOLE_BEAT_PLAY_INIT, 
	MOLE_BEAT_PLAY_LEVEL, 
	MOLE_BEAT_PLAY_START, 
	MOLE_BEAT_PLAY_STOP, 
	MOLE_BEAT_PLAY_END
	
}MOLE_BEAT_PLAY_ACT;


typedef struct{
	
	u16 act;
	u16 play_act;
	
	u8 level;
	u8 score;
	u8 mole_cnt;
	u8 mole_ptn[MOLE_MAX];
	
}MoleBeatStatus;


static MoleBeatStatus st_mole_beat;


void moleBeat_Init(void);
void moleBeat_Play(void);
void moleBeat_Exit(void);


//---------------------------------------------------------------------------------
void moleBeat_Init(void) {
//---------------------------------------------------------------------------------
	
	srand(time(NULL));
	memset(&st_mole_beat, 0, sizeof(st_mole_beat));
	
	st_mole_beat.act = MOLE_BEAT_PLAY;
	
}

//---------------------------------------------------------------------------------
void moleBeat_Play(void) {
//---------------------------------------------------------------------------------
	
	u8 key;
	
	static u32 frame = 0;
	static bool is_draw_mole = false;
	
	
	if(frame){
		frame--;
	}
	
	
	switch(st_mole_beat.play_act){
		
	//ゲーム初期化
	case MOLE_BEAT_PLAY_INIT:
		
		st_mole_beat.score = st_mole_beat.mole_cnt = 0;
		frame = 0;
		is_draw_mole = true;
		
		//モグラ出現パターンの生成
		int i;
		
		//0〜6までの範囲の乱数をセットする
		for(i = 0;i < MOLE_MAX;i++){
			st_mole_beat.mole_ptn[i] = (u8)rand() % 7;
		}
		
		Outport_HideBinLED();
		Outport_HideNumLED();
		
		st_mole_beat.play_act = MOLE_BEAT_PLAY_LEVEL;
		
		break;
		
		
	//ゲーム難易度選択
	case MOLE_BEAT_PLAY_LEVEL:
		
		if(Key_IsKeyDown()){
			
			key = Key_GetKeyValue();
			
			if( (key == KEYPAD_0) || (key == KEYPAD_4) || (key == KEYPAD_8) || (key == KEYPAD_C) ){
				
				Amp_BeepSound();
				
				switch(key){
					
				case KEYPAD_0:
					st_mole_beat.level = 0;
					break;
					
				case KEYPAD_4:
					st_mole_beat.level = 1;
					break;
					
				case KEYPAD_8:
					st_mole_beat.level = 2;
					break;
					
				case KEYPAD_C:
					st_mole_beat.level = 3;
					break;
					
				}
				
				frame = 20;
				st_mole_beat.play_act = MOLE_BEAT_PLAY_START;
				
			}
			
		}
		
		break;
		
		
	//ゲーム開始
	case MOLE_BEAT_PLAY_START:
		
		//モグラを10回表示する
		if(st_mole_beat.mole_cnt <= MOLE_MAX){
			
			if(!frame){
				
				//モグラを非表示する
				if(is_draw_mole){
					
					st_mole_beat.mole_cnt++;
					frame = 42;		//0.7秒の間隔を置く
					
					is_draw_mole = false;
					
					Outport_HideBinLED();
					
				//モグラを表示する
				}else{
					
					switch(st_mole_beat.level){
						
					case 0:
						frame = 94;
						break;
						
					case 1:
						frame = 70;
						break;
						
					case 2:
						frame = 40;
						break;
						
					case 3:
						frame = 30;
						break;
						
					}
					
					is_draw_mole = true;
					
					Outport_SetBinLED(st_mole_beat.mole_ptn[ st_mole_beat.mole_cnt - 1 ]);
					
				}
				
			}
			
			//モグラを叩けたかどうか判断する
			if(is_draw_mole && Key_IsKeyDown()){
				
				key = Key_GetKeyValue();
				
				if(key >= KEYPAD_0 && key <= KEYPAD_6){
					
					if(key == st_mole_beat.mole_ptn[ st_mole_beat.mole_cnt - 1 ]){
						Amp_HitSound();
						st_mole_beat.score++;
					}
					
					frame = 0;
					
				}
				
			}
			
		//モグラの表示を全て終えた
		}else{
			
			if(Amp_IsStopSound()){
				Amp_CallEndSound();
				st_mole_beat.play_act = MOLE_BEAT_PLAY_STOP;
			}
			
		}
		
		break;
		
		
	//ゲーム終了
	case MOLE_BEAT_PLAY_STOP:
		
		//得点を7セグへ表示する
		if(Amp_IsStopSound()){
			Outport_ShowNumLED(st_mole_beat.score);
			st_mole_beat.play_act = MOLE_BEAT_PLAY_END;
		}
		
		break;
		
		
	//ゲームの再スタート/モニタへ戻る かの選択を待つ
	case MOLE_BEAT_PLAY_END:
		
		if(Key_IsKeyDown()){
			
			key = Key_GetKeyValue();
			
			//RUNならゲームを再スタートする
			if(key == KEYPAD_RUN){
				st_mole_beat.play_act = MOLE_BEAT_PLAY_INIT;
				
			//RESETならゲーム終了してモニタへ戻る
			}else if(key == KEYPAD_RESET){
				st_mole_beat.act = MOLE_BEAT_EXIT;
				
			}
			
		}
		
		break;
		
		
	}
	
}

//---------------------------------------------------------------------------------
void moleBeat_Exit(void) {
//---------------------------------------------------------------------------------
	
	st_mole_beat.act = MOLE_BEAT_INIT;
	
}


//---------------------------------------------------------------------------------
void MoleBeat_Update(void) {
//---------------------------------------------------------------------------------
	
	//debug print (cheating)
	int i;
	printf("\x01b[4;0Hdebug print (cheating)\n");
	for(i = 0;i < MOLE_MAX;i++){
		printf(" %01X", st_mole_beat.mole_ptn[i]);
	}
	
	
	switch(st_mole_beat.act){
		
	case MOLE_BEAT_INIT:
		moleBeat_Init();
		break;
		
	case MOLE_BEAT_PLAY:
		moleBeat_Play();
		break;
		
	case MOLE_BEAT_EXIT:
		moleBeat_Exit();
		break;
		
	}
	
}

//---------------------------------------------------------------------------------
void MoleBeat_Clear(void) {
//---------------------------------------------------------------------------------
	
	st_mole_beat.act = MOLE_BEAT_INIT;
	
}

//---------------------------------------------------------------------------------
bool MoleBeat_IsExit(void) {
//---------------------------------------------------------------------------------
	
	return (st_mole_beat.act == MOLE_BEAT_INIT) ? true:false;
	
}

//---------------------------------------------------------------------------------