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を表示しよう.

コメント