#include #include #include #include #define MXM 20 //MapX_MAX #define MYM 10 //MapY_MAX #define MBM 1 //My_Bullet_MAX #define TIMELIMIT 30 int NewChangeFlag = 1; int myscore = 0; int shootcount = 0; int TimeLimit = 0; //時間制限 //マップデータ。0:空間 1:壁 2:触ったら死ぬ穴 int MapData[MYM][MXM] = { //基盤となるマップデータ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1}, {1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1}, {1,0,2,0,0,0,2,0,0,0,0,0,0,0,0,2,0,0,0,2}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,2,0,0,0,1,1,1,2,0,0,2,0,0,0,0,0,1}, {2,0,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} }; int InstantMapData[MYM][MXM]; //画面表示用マップデータ。プログラム開始後はこっちがメイン struct ZahyouPoint { int x; //X座標 int y; //Y座標 int s; //状態 } jiki,enemy,MyBullet[MBM]; void Initialize(void); //初期化 void ShowTitle(void); //タイトル画面の表示 void EnemyMove(void); //敵機の移動 void AtariHantei(void); //マップ全体の当たり判定 void MyCharDeath(void); //自キャラの死亡を処理 void LineOut(int LineNum); //マップデータの指定行を描画 void TranslationMapData(int x,int y); //マップデータの各数値データを文字データに置き換える void DrawMyChar(void); //自キャラを描画 void DrawMyBullet(void); //自弾を描画 void ShowMessage(int mode); //メッセージ表示 void DrawClear(void); //画面消去 void DrawAllScreen(void); //全画面描画 void DrawPoints(void); //スコア表示 int MyBulletExist(int mode);//残弾確認 void MyBulletShoot(void); //弾を発射 void MyBulletPut(int bnum); //自弾をマップにプット void MyBulletClear(int bnum); //自弾の残像を消去 void MyBulletDelete(int bnum); //弾の実体を消去 void MyBulletMove(int bnum); //自弾を移動 int MyBulletMHantei(int bnum); //弾の移動可不可を判定 int idou(int input_buff); //移動を受け付けるメイン関数 int MHantei(int MoveD); //移動したい方向の情報を取得して判定を下す void MyCharPut(void); //自キャラをマップにプット void MyCharClear(void); //自キャラの残像を消す int Enidou(int input_buff); //敵の移動 int EnMHantei(int MoveD); //敵の移動可能判定 void EnCharPut(void); //敵をマップにプット void EnCharClear(void); //敵の残像を消す int TimeControl(int timing); //敵移動判定用タイマー int TimeControlBullet(int timing); //弾移動判定用タイマー int TimeControlLimit(int timing); //時間制限用タイマー void PlayEnd(void); //終了処理 int main(void) { int input_buff; //入力バッファ srand(time(NULL)); ShowTitle(); DrawClear(); Initialize(); while(1){ // if(TimeControl(100)){ if(NewChangeFlag){ AtariHantei(); DrawAllScreen(); } if(TimeControl(300)){ EnemyMove(); } if(TimeControlBullet(50)){ DrawMyBullet(); } if(TimeControlLimit(1000)){ TimeLimit++; } //入力受付 if(kbhit()){ input_buff = getch(); idou(input_buff); fflush(stdin); //バッファを空……にできたらいいな } if(jiki.s==0){ MyCharDeath(); } //プレイヤーが死んだら終了 if(TimeLimit==TIMELIMIT){ PlayEnd(); } //制限時間が過ぎたら終了 // } } return 0; } //---------------------------/ //------------------初期化--/ //-------------------------/ //今のところ自機の情報を初期化するのみ void Initialize(void) { int i,j; for(i=0;i-4で左上右下 case -1: if(MapData[jiki.y][jiki.x-1] == 1){ return; } MyBullet[TamaIN].x = jiki.x - 1; MyBullet[TamaIN].y = jiki.y; MyBullet[TamaIN].s = -1; break; case -2: if(MapData[jiki.y-1][jiki.x] == 1){ return; } MyBullet[TamaIN].x = jiki.x; MyBullet[TamaIN].y = jiki.y-1; MyBullet[TamaIN].s = -2; break; case -3: if(MapData[jiki.y][jiki.x+1] == 1){ return; } MyBullet[TamaIN].x = jiki.x + 1; MyBullet[TamaIN].y = jiki.y; MyBullet[TamaIN].s = -3; break; case -4: if(MapData[jiki.y+1][jiki.x] == 1){ return; } MyBullet[TamaIN].x = jiki.x; MyBullet[TamaIN].y = jiki.y + 1; MyBullet[TamaIN].s = -4; break; default: break; } shootcount++; } void MyBulletPut(int bnum) { InstantMapData[MyBullet[bnum].y][MyBullet[bnum].x] = -4; } void MyBulletClear(int bnum) { InstantMapData[MyBullet[bnum].y][MyBullet[bnum].x] = MapData[MyBullet[bnum].y][MyBullet[bnum].x]; } /* void MyBulletDelete(int bnum) { MyBullet[bnum].s = 0; } */ void MyBulletMove(int bnum) { MyBulletClear(bnum); switch(MyBullet[bnum].s){ case -1: if(MyBulletMHantei(bnum)){ MyBullet[bnum].x--; } break; case -2: if(MyBulletMHantei(bnum)){ MyBullet[bnum].y--; } break; case -3: if(MyBulletMHantei(bnum)){ MyBullet[bnum].x++; } break; case -4: if(MyBulletMHantei(bnum)){ MyBullet[bnum].y++; } break; deafault:break; } } int MyBulletMHantei(int bnum) { int tempX,tempY; //「もし移動したら」を比較する為にその場合の座標を格納 switch(MyBullet[bnum].s){ //引数により上下左右どちらに移動したいのか判定 case -1:tempY = MyBullet[bnum].y; tempX = MyBullet[bnum].x-1; break; case -2:tempY = MyBullet[bnum].y-1; tempX = MyBullet[bnum].x; break; case -3:tempY = MyBullet[bnum].y; tempX = MyBullet[bnum].x+1; break; case -4:tempY = MyBullet[bnum].y; tempX = MyBullet[bnum].x+1; break; default: return 0; } //画面上下左右を突き抜けないように if( tempY==-1 ||tempX==-1 ||tempY==MYM ||tempX==MXM ){ return 0; } /* // else if( // InstantMapData[tempY][tempX]==2 //2は触れると死ぬ // ){ ShowMessage(1); jiki.s=0; NewChangeFlag = 1; return 1; } else if( InstantMapData[tempY][tempX]!=1 //1は単なる移動不可障害物 ){ NewChangeFlag = 1; return 1; } */ return 1; } //---------------------------/ //----------------移動関係--/ //-------------------------/ int idou(int input_buff){ MyCharClear(); //移動する前に以前に自分が居た場所を消去しておく switch(input_buff){ case 32: printf("終了\n"); exit(0); break; case 97: printf("←"); jiki.s=-1; if(MHantei(0)){ jiki.x--; } break; case 119:printf("↑"); jiki.s=-2; if(MHantei(1)){ jiki.y--; } break; case 100:printf("→"); jiki.s=-3; if(MHantei(2)){ jiki.x++; } break; case 106:printf("j"); if(MyBulletExist(0) < MBM){ MyBulletShoot(); } break; case 115:printf("↓"); jiki.s=-4; if(MHantei(3)){ jiki.y++; } break; default: break; } return 0; } int MHantei(int MoveD) { int tempX,tempY; //「もし移動したら」を比較する為にその場合の座標を格納 switch(MoveD){ //引数により上下左右どちらに移動したいのか判定 case 0: tempY = jiki.y; tempX = jiki.x-1; break; case 1: tempY = jiki.y-1; tempX = jiki.x; break; case 2: tempY = jiki.y; tempX = jiki.x+1; break; case 3: tempY = jiki.y+1; tempX = jiki.x; break; default: return 0; } //画面上下左右を突き抜けないように if( tempY==-1 ||tempX==-1 ||tempY==MYM ||tempX==MXM ){ return 0; } // else if( // InstantMapData[tempY][tempX]==2 //2は触れると死ぬ // ){ ShowMessage(1); jiki.s=0; NewChangeFlag = 1; return 1; } else if( InstantMapData[tempY][tempX]!=1 //1は単なる移動不可障害物 ){ NewChangeFlag = 1; return 1; } return 0; } //以下の二つの関数は統合してスイッチで切り替えた方がわかり易いかもしれない void MyCharClear(void) { InstantMapData[jiki.y][jiki.x] = MapData[jiki.y][jiki.x]; } void MyCharPut(void) { InstantMapData[jiki.y][jiki.x] = -2; //自機は-2。負の数は特殊なデータを扱う、と勝手に設定。-「2」なのはテスト段階で0を-1としていた名残 } //---------------------------/ //----------------敵機関連--/ //-------------------------/ int Enidou(int input_buff) { EnCharClear(); //移動する前に以前に自分が居た場所を消去しておく switch(input_buff){ case 32: printf("終了\n"); exit(0); break; case 1: printf("@←"); if(EnMHantei(0)){ enemy.x--; } break; case 2:printf("@↑"); if(EnMHantei(1)){ enemy.y--; } break; case 3:printf("@→"); if(EnMHantei(2)){ enemy.x++; } break; case 4:printf("@↓"); if(EnMHantei(3)){ enemy.y++; } break; default: break; } return 0; } int EnMHantei(int MoveD) { int tempX,tempY; //「もし移動したら」を比較する為にその場合の座標を格納 switch(MoveD){ //引数により上下左右どちらに移動したいのか判定 case 0: tempY = enemy.y; tempX = enemy.x-1; break; case 1: tempY = enemy.y-1; tempX = enemy.x; break; case 2: tempY = enemy.y; tempX = enemy.x+1; break; case 3: tempY = enemy.y+1; tempX = enemy.x; break; default: return 0; } //画面上下左右を突き抜けないように if( tempY==-1 ||tempX==-1 ||tempY==MYM ||tempX==MXM ){ return 0; } else if( InstantMapData[tempY][tempX]==2 //2は触れると死ぬ ){ return 0; } else if( InstantMapData[tempY][tempX]!=1 //1は単なる移動不可障害物 ){ NewChangeFlag = 1; return 1; } return 0; } //以下の二つの関数は統合してスイッチで切り替えた方がわかり易いかもしれない void EnCharClear(void) { InstantMapData[enemy.y][enemy.x] = MapData[enemy.y][enemy.x]; } void EnCharPut(void) { InstantMapData[enemy.y][enemy.x] = -3; //敵機は-3 } //---------------------------/ //----------------タイマー--/ //-------------------------/ //引数ミリ秒毎に信号を出す int TimeControl(int timing) { int timer; static int temp; int result = 0; timer = clock(); if((timer/timing)!=temp) { temp = timer/timing; result = 1; } return result; } int TimeControlBullet(int timing) { int timer; static int temp; int result = 0; timer = clock(); if((timer/timing)!=temp) { temp = timer/timing; result = 1; } return result; } int TimeControlLimit(int timing) { int timer; static int temp; int result = 0; timer = clock(); if((timer/timing)!=temp) { temp = timer/timing; result = 1; } return result; } void PlayEnd(void){ printf("弾消費数:%d\n",shootcount); printf("エンターキーを押してください\n"); while( getch()!=13 ) { } exit(0); }