


13. 敵の動作と判定。
敵は5枚の画像を時間差で表示して表現します。
時間はれいによってcounterで表現しますが、どうやればいいでしょうか。
counterは0から無限へ1ずつ増加していきます。
画像は配列でハンドルが格納してあり、
[0]から[4]まであります。今画像を
[0] -> [1] -> [2] -> [3] -> [4] -> [3] -> [2] -> [1]
-> [0] -> [1] -> 
と繰り返していきたいのです。サンプルにはこのように書いてあります。
counterは昇順にしか増加しません。それなら配列にこの番号を順に格納すればよいですね。
int enemy_img[8]={0,1,2,3,4,3,2,1};
としてやり、counterの値でこの配列要素をさしてやればよいです。
サンプルでは
img_enemy1[enemy_img[counter%32/4]]
このように書きました。これはcounterの値を32でわったあまりを4で割っています。
つまり、counterの値は時間によって全て0〜31の値に分けられますからそれをさらに4で割ることで
0〜3→0
4〜7→1
・・・・・
28〜31→7
と、綺麗にcounterの値をもちいて0〜7の値が作れました。
これで、表示したい順番で画像が表示できますね。ですからサンプルにはこのように書いてあるわけです。
DrawRotaGraph( (int)enemy[i].x , (int)enemy[i].y , enemy[i].size , 0.0f
, img_enemy1[enemy_img[counter%32/4]] , TRUE ) ;
前章で定義した
MONSTER1_X_SIZE
MONSTER1_Y_SIZE
ですが、これは、敵の画像サイズです。
縦が140.0
横が128.0
小数計算するので、小数で書いてあります。
これは、敵が画面の外へ出た時に、出現フラグを戻すための判定に使うものです。
enemy[i].xが0の時は、画像はすでに半分出ていますね。
使っている描画関数は座標が画像の中央に来る仕様ですから。
ですから、もう画像半分ほど外にでたら画面から出たことになります。
画像サイズ / 2 で画像半分ほどの計算が出来ます。縮小率はsizeに格納してありますからさらにこれをかけて
MONSTER1_X_SIZE / 2.0 * enemy[i].size;
これで画像半分がわかります。つまり
if ( enemy[i].x < 0.0-MONSTER1_X_SIZE / 2.0 * enemy[i].size)
と書くことで、画像が画面から左に外れた時の処理が可能です。
これを4方向全て書いたのが
if(enemy[i].x<0.0-MONSTER1_X_SIZE/2.0*enemy[i].size || enemy[i].x>420.0+MONSTER1_X_SIZE/2.0*enemy[i].size
|| enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size || enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size)
これです。長くて読みにくいですね。この時、敵のフラグを戻します。
enemy[i].flag=0;
では、サンプルです。
/* enemy.cpp */
/* 素材 ver 1.10以上必要 */
#include "DxLib.h"
#include "ExternGV.h"
void EnemyPattern1(int i){
    enemy[i].y+=1.5f;
}
void EnemyControl(){
        for(int i=0;i<100;i++){
                if(enemy[i].flag==1){
                        if(enemy[i].pattern==1)
                                EnemyPattern1(i);
                }
        }
}
void EnemyCalcDisp(){
        int i;
        for(i=0;i<100;i++)
                if(enemy[i].flag==0)
                        break;
        switch(counter){
                case 100:
                case 200:
                case 300:
                case 400:
                        enemy[i].pattern=1; //どういう軌道を描くか
                        enemy[i].flag=1;   //出現フラグを立てる
                        enemy[i].counter=0;//出現して何カウント目か測るカウンター初期化
                        enemy[i].size=0.5f;//敵の大きさ
                        enemy[i].x=100.0;  //xの初期座標
                        enemy[i].y=-10.0;  //yの初期座標
                        break;
                default:
                        break;
        }
        for(i=0;i<100;i++){
                if(enemy[i].flag==1){
                        enemy[i].counter++;
                        int enemy_img[8]={0,1,2,3,4,3,2,1};
                        DrawRotaGraph( (int)enemy[i].x , (int)enemy[i].y , enemy[i].size , 0.0f , img_enemy1[enemy_img[counter%32/4]] , TRUE ) ;
                        if(enemy[i].x<0.0-MONSTER1_X_SIZE/2.0*enemy[i].size || enemy[i].x>420.0+MONSTER1_X_SIZE/2.0*enemy[i].size ||
                                enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size || enemy[i].y<0.0-MONSTER1_Y_SIZE/2.0*enemy[i].size)
                                enemy[i].flag=0;
                }
        }
}
実行画面
DXライブラリ著作権表示
DX Library Copyright (C) 2001-2006 Takumi 
Yamada.