ODEで学ぶC言語の3回目です.ODEの物理計算の部分は使わず,drawstuffを使った表示だけにします.今回は今まで演習で作ったコードを整理して関数化しています.
まず,76行目のsimLoop関数から説明します.ここはシミュレーションで毎回呼び出される関数です.67行目のcollision関数で弾が敵に衝突しているかどうかの判定を行っています。衝突したら1を返し,それ以外は0を返します.衝突したら,敵が被弾した情報を格納する配列target_hit[j]に1を代入しています.被弾したら1を代入します.
89行目は弾を描画し,91行目で敵を表示しています.
24行目からのキー入力処理をするcommand関数では,スペースキー(32)が押されると,弾を設定し,弾数を1増加させています.
48行目のdrawTarget関数では敵を描画しています.51行目で,敵が被弾していたら,continueを使い,被弾した敵の描画を飛ばします.
説明はこのぐらいにして,ソースコードを読んで演習をしましょう.約100行です.
#include "dm3.h" #include #include #include #define TARGET_NUM 10 // 敵の数 #define BULLET_NUM 100 // 弾数 int bullet_no = 0; int target_hit[TARGET_NUM] = {0}; // 弾が当たったら1に設定 double start_x =0.0, start_y = 0.5, start_z = 0.5; // 初期位置 double R[12] = {1,0,0,0, 0,1,0,0, 0,0,1,0}; // 回転行列が格納される配列, 位置(x,y,z)[m] double target_pos[TARGET_NUM][3] = {0.0, 0.0, 0.5}; // 位置(x,y,z)[m] double robot_pos[3] = {start_x, start_y, start_z}; // ロボットの位置 double bullet_pos[BULLET_NUM][3]; // 弾の位置; double sides[3] = {1.0, 0.5, 1.0}; // 直方体のサイズ(x, y, z)[m] void setBullet(int no, double pos[3]) { bullet_pos[no][0] = pos[0]; bullet_pos[no][1] = pos[1]; bullet_pos[no][2] = pos[2]; } void command(int cmd) { switch (cmd) { case 'a': robot_pos[0] -= 1.0; break; case 'd': robot_pos[0] += 1.0; break; case 'x': robot_pos[1] -= 1.0; break; case 'w': robot_pos[1] += 1.0; break; case 32: setBullet(bullet_no,robot_pos); bullet_no++; printf("bullet=%d\n",bullet_no); break; default: printf("Input %c (%d)\n",(char)cmd, cmd); } } void drawTarget() { int i; for (i = 0; i < TARGET_NUM; i++) { if (target_hit[i]) continue; dsSetColor(1.0, 0.0, 0.0); // 色の設定 target_pos[i][0] = 2 * i + start_x - TARGET_NUM + 1; // 位置のx成分 target_pos[i][1] = start_y + 10; // 位置のx成分 target_pos[i][2] = 0.5; // 位置のz成分 dsDrawBox(target_pos[i],R,sides); // 直方体の表示 } } void drawBullet(double pos[3]) { int i; dsSetColor(0.0, 0.0, 1.0); // 色の設定 dsDrawSphere(pos,R,0.1); // 球の表示 } // ブロックが他のブロックと衝突したら1を返す,それ以外は0を返す int collision(double pos1[3], double pos2[3]) { // ブロック間の距離が1未満なら1を返すコードを // ここに書きなさい double dist = sqrt((pos1[0]-pos2[0]) * (pos1[0]-pos2[0]) + (pos1[1]-pos2[1]) * (pos1[1]-pos2[1])); if (dist < 0.5) return 1; else return 0; } void simLoop(int pause) { /*** シミュレーションループ ***/ int i,j; // ロボットの表示 dsSetColor(1.0, 1.0, 0.0); // 黄色 dsDrawSphere(robot_pos, R, 0.5); for (i=0; i < bullet_no; i++) { bullet_pos[i][1] += 0.01; for (j = 0; j < TARGET_NUM; j++) { if (collision(bullet_pos[i],target_pos[j])) { target_hit[j] = 1; } } drawBullet(bullet_pos[i]); // 弾の描画 } drawTarget(); // 敵の描画 } int main() { /*** main関数 ***/ robot_pos[1] = start_y - 10; dmLoop(800, 600); // シミュレーションループ ウインドウの幅,高 return 0; }
では,演習をしながらシューティングゲームを作っていきましょう.
演習
- step3-150701.zipをダウンロードし,実行してください.
- ンプルでは弾が1発当たると敵は破壊されましたが,1発命中すると敵の色が赤くように改良しよう!
- サンプルでは弾が1発当たると敵は破壊されましたが,1発命中すると敵の色が赤くなり,2発目で破壊するように改良しよう!
- 敵がインベーダーゲームのように移動するように改良しよう!
- 敵も弾を発射するように改良しよう!
- 敵の弾が自分のロボットに命中したら,ゲームオーバーにするよう改良しよう!また,敵を1台破壊したら10点入るようにし,Scoreを表示しよう.
コメント