シューティングゲームの4回目です.今回は前回までの演習を構造体を使い実装しています.
まず,12行目から20行目で構造体myObjectを定義しています.メンバとしては,位置pos[3],回転行列R[12],質量m,半径r,サイズside[3],色*colorなどの変数です.
Step3との大きな違いは113行目のinitObject関数でゲームに使う物体を初期化しています.114行目のwelcomeMessage()で,ゲームのウェルカム表示と遊び方を表示します.具体的な遊び方は書いていないので,自分のオリジナルゲームを制作するときは、ユーザーが遊べるように遊び方を書きましょう.
また,Collision関数の引数がStep3では要素数3個の配列からmyObjecgt構造体に変更されています.
それ以外は,Step3とあまり違いはありません.Step3の演習は難しかったので,今回もほとんど同じにしています.構造体の復習を兼ねて,ソースコードを読んで演習をしましょう.
該当するソースコードは次のとおりです.
/* step4 */
/* A simple shooting game */
/* step4 2015-07-09 */
#include "dm4.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>
#define TARGET_NUM 10 // 敵の数
#define BULLET_NUM 100 // 弾数
typedef struct myObject {
double pos[3]; // 位置 x, y, z [m]
double R[12]; // 回転行列 要素数4x3
double m; // 質量 [kg]
double r,l; // 半径 [m], 長さ [m]
double side[3]; // サイズ x,y,z
float *color; // 色 r,g,b
int hit; // 弾が当たった数
};
myObject target[TARGET_NUM];
myObject bullet[BULLET_NUM];
myObject robot;
int bullet_no = 0;
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 sides[3] = {1.0, 0.5, 1.0}; // 直方体のサイズ(x, y, z)[m]
static float blue[3] = {0.0, 0.0, 1.0}, red[3] = {1.0, 0, 0}, yellow[3] = {1.0, 1.0, 0}; // 青、赤、黄色
void setBullet(int no, double pos[3]) {
bullet[no].pos[0] = pos[0];
bullet[no].pos[1] = pos[1];
bullet[no].pos[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[i].hit) continue;
dsSetColor(target[i].color[0],target[i].color[1],target[i].color[2]); // 色の設定
dsDrawBox(target[i].pos,target[i].R,target[i].side); // 直方体の表示
}
}
void drawBullet() {
int i;
for (i=0; i< BULLET_NUM; i++) {
dsSetColor(bullet[i].color[0], bullet[i].color[1], bullet[i].color[2]); // 色の設定
dsDrawSphere(bullet[i].pos,bullet[i].R, bullet[i].r); // 球の表示
}
}
void drawRobot() {
// ロボットの表示
dsSetColor(robot.color[0], robot.color[1], robot.color[2]); // 黄色
dsDrawSphere(robot.pos, robot.R, robot.r);
}
// ブロックが他のブロックと衝突したら1を返す,それ以外は0を返す
int collision(myObject a, myObject b) {
// ブロック間の距離が1未満なら1を返すコードを
// ここに書きなさい
double dist = sqrt((a.pos[0]- b.pos[0]) * (a.pos[0]-b.pos[0])
+ (a.pos[1]-b.pos[1]) * (a.pos[1]-b.pos[1]));
if (dist < 0.5) return 1;
else return 0;
}
void simLoop(int pause) { /*** シミュレーションループ ***/
int i,j;
for (i=0; i < bullet_no; i++) {
bullet[i].pos[1] += 0.01;
for (j = 0; j < TARGET_NUM; j++) {
if (collision(bullet[i],target[j])) {
target[j].hit = 1;
}
}
}
drawBullet();
drawTarget(); // 敵の描画
drawRobot(); // ロボットの描画
}
// 物体の初期化
void initObject() {
int i, j, k, c;
// 敵
for (i =0; i < TARGET_NUM; i++) {
target[i].pos[0] = 2 * i + start_x - TARGET_NUM + 1; // 位置のx成分
target[i].pos[1] = start_y + 10; // 位置のx成分
target[i].pos[2] = 0.5;
target[i].color = blue;
target[i].hit = 0;
for (k = 0; k < 12; k++) target[i].R[k] = R[k];
for (j = 0; j < 3; j++) target[i].side[j] = sides[j];
}
// ロボット
robot.pos[0] = start_x;
robot.pos[1] = start_y - 10;
robot.pos[2] = start_z;
robot.color = yellow;
for (k = 0; k < 12; k++) robot.R[k] = R[k];
robot.r = 0.5;
// 弾
for (i =0; i < BULLET_NUM; i++) {
for (j=0; j < 3; j++) bullet[i].pos[j] = robot.pos[j];
bullet[i].color = red;
for (k = 0; k < 12; k++) bullet[i].R[k] = R[k];
bullet[i].r = 0.1;
}
}
void welcomeMessage() {
printf("****************************************\n");
printf("* Welcom to the Simple Shooting Game ! *\n");
printf("****************************************\n\n");
printf(" Please write here. how to play.\n");
}
int main() { /*** main関数 ***/
welcomeMessage();
initObject(); // 物体の初期化
dmLoop(800, 600); // シミュレーションループ ウインドウの幅,高
return 0;
}
演習
- step4-150709.zipをダウンロードし,実行してください.
- 遊び方を表示するwelcomeMessage()を自分の好きなように変えよう!
- サンプルでは弾が1発当たると敵は破壊されましたが,1発命中すると敵の色が赤くように改良しよう!
- サンプルでは弾が1発当たると敵は破壊されましたが,1発命中すると敵の色が赤くなり,2発目で破壊するように改良しよう!
- 敵がインベーダーゲームのように移動するように改良しよう!
- 敵も弾を発射するように改良しよう!
- 敵の弾が自分のロボットに命中したら,ゲームオーバーにするよう改良しよう!また,敵を1台破壊したら10点入るようにし,Scoreを表示しよう.
- ロボットの初期位置に弾が残って表示されるバグがあります。バグを取ろう!

コメント