50 章

49章で自機のショットにオプションを付けてみましたね。今回はそのショットにホーミング処理を付けてみましょう。

各弾から一番近い敵を見つけて、その敵の方向に弾を飛ばします。

2つの点と点の角度を計算するにはいつものようにatan2関数を利用します。

ホーミング処理はボスがいるときと、ボスが居ない時で処理を分ける必要があります。

boss.flagがオンになっていたとしても、ボスのHPが無い時は当たり判定がありませんから

ボスのフラグがオンになっていて、かつボスのHPがある時にボスのホーミング処理を行います。

また、自機ショットというものは単純に増やして行ってはいけません。

1筋ショットだったのが、パワーアップするごとに2筋ショット、・・・6筋ショットみたいに増やしてしまっては、

この時点で単純にもとの6倍の強さになってしまいます。

こうなってしまうと、パワーマックスでは10秒で倒せる相手がパワー0では1分もかかってしまうことになります。

実はトータル的な強さは2倍、3倍・・と増やすのではなく、1.1倍、1.2倍単位で強くしていくほうがいいのです。

ですから、同時発射の弾が増えるほど、弾の威力を減らしていく処理をしてみましょう。

(「パワーアップで弾の威力を減らす」??と思った方へ。 例えば1筋ショットから2筋ショット(同時発射2弾)にするときは、

1筋ショットが弾1つのパワーが10だったら、2筋ショットは弾一つのパワーを6に減らす事で全体的に1.2倍になりますね。

そういうことです。)

弾が豪快になればプレイヤーとしてはそれだけで強くなった印象を受けます。

パワーアップしたときは、実際に弾の威力をイキナリあげるのではなく、演出を豪快にして、

弾の威力はビビたる上昇になるようにしてあげましょう。

この辺の調整はゲームをプレイしながらじゃないと難しいのでとりあえずその辺の調整は今はいい加減にしておきます。



---- cshot.cpp に以下を追加 ----
//通常ショット登録
//通常ショット登録
void ch0_shot_pattern(){
        int k;
        int n=cshot0num[ch.power<200?0:1];
        for(int i=0;i<n;i++){
                if((k=search_cshot())!=-1){
                        cshot[k].flag=1;
                        cshot[k].cnt=0;
                        cshot[k].angle=-PI/2;
                        cshot[k].spd=20;
                        cshot[k].x=ch.x+cshot0pos_x[i];
                        cshot[k].y=ch.y+cshot0pos_y[i];
                        cshot[k].power= (n<2 ? 20 : 12) + ch.power/100;//2筋なら20,4筋なら12(50)
                        cshot[k].knd=0;
                        cshot[k].img=img_cshot[0];//画像番号代入(49)
                }
        }
        se_flag[2]=1;//発射音オン
        if(ch.power>=100){
                for(int i=0;i<(ch.power<300?2:4);i++){
                        if((k=search_cshot())!=-1){
                                cshot[k].flag=1;
                                cshot[k].cnt=0;
                                cshot[k].angle=option0ang[i];
                                cshot[k].spd=20;
                                cshot[k].x=option_bb[i%2].x;
                                cshot[k].y=option_bb[i%2].y;
                                cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
                                cshot[k].knd=1;
                                cshot[k].img=img_cshot[1];//画像番号代入(49)
                        }
                }
        }
}

//低速通常ショット登録
void ch1_shot_pattern(){
        int k;
        int n=cshot0num[ch.power<200?0:1];
        for(int i=0;i<n;i++){
                if((k=search_cshot())!=-1){
                        cshot[k].flag=1;
                        cshot[k].cnt=0;
                        cshot[k].angle=-PI/2;
                        cshot[k].spd=20;
                        cshot[k].x=ch.x+cshot0pos_x[i]/3;//低速中なら位置を中心側へ
                        cshot[k].y=ch.y+cshot0pos_y[i]/2;
                        cshot[k].power= (n<2 ? 20 : 12) + ch.power/100;//2筋なら20,4筋なら12(50)
                        cshot[k].knd=0;
                        cshot[k].img=img_cshot[0];//画像番号代入(49)
                }
        }
        se_flag[2]=1;
        if(ch.power>=100){
                for(int i=0;i<(ch.power<300?2:4);i++){
                        if((k=search_cshot())!=-1){
                                cshot[k].flag=1;
                                cshot[k].cnt=0;
                                cshot[k].angle=option0ang[i];
                                cshot[k].spd=20;
                                cshot[k].x=option_bb[i%2].x;
                                cshot[k].y=option_bb[i%2].y;
                                cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
                                cshot[k].knd=1;
                                cshot[k].img=img_cshot[1];//画像番号代入(49)
                        }
                }
        }
}


(略)

//一番近い敵を探して角度をセットする
void calc_homing(int k){
        int i,d, num=-1, min=-1;
        double x,y;
        if(boss.flag==0){//ボスが居ない時
                for(i=0;i<ENEMY_MAX;i++){//敵の総数分
                        if(enemy[i].flag==1){
                                x=(enemy[i].x-cshot[k].x);
                                y=(enemy[i].y-cshot[k].y);
                                d=(int)(x*x+y*y);//ショットと敵の距離
                                if(d<min || min==-1){//計算結果が最小値かまだ格納していないなら
                                        num=i;//番号記録
                                        min=d;//距離記録
                                }
                        }
                }
        }
        //近い敵が見つかったら、あるいはボスがいて、HPがあるときは角度をセット
        if(num!=-1 || boss.flag==1 && boss.hp>0){
                if(boss.flag==0){
                        x=enemy[num].x-cshot[k].x;
                        y=enemy[num].y-cshot[k].y;
                }
                else{
                        x=boss.x-cshot[k].x;
                        y=boss.y-cshot[k].y;
                }
                cshot[k].angle=atan2(y,x);
        }
}

//ショットの移動計算
void calc_cshot(){
        for(int i=0;i<CSHOT_MAX;i++){
                if(cshot[i].flag==1){
                        int dranx=(int)(cshot[i].spd+11/2),drany=(int)(cshot[i].spd+55/2);
                        if(cshot[i].knd==1)
                                calc_homing(i);
                        cshot[i].x+=cos(cshot[i].angle)*cshot[i].spd;
                        cshot[i].y+=sin(cshot[i].angle)*cshot[i].spd;
                        cshot[i].cnt++;
                        if(cshot[i].x<-dranx || cshot[i].x>FMX+dranx ||
                                cshot[i].y<-drany || cshot[i].y>FMY+drany)//画面から外れたら
                                cshot[i].flag=0;
                }
        }
}


実行結果




- Remical Soft -