Stutteの備忘録

プログラミングや日々の雑感等の備忘録です

ただし点Pは放物線上を動くものとする

 数学みたいなタイトルですがゲームの話です

 5日ぐらい前から作り始めてたYZY姉貴の弾幕が完成したので紹介です 2日ほどで完成すると踏んでいたのですが、PCが調子悪かったり、急に妖精大戦争をやりたくなったりして遅くなりました

 

 YZY姉貴って一年前ぐらいに合作やってたからあの後流行るかな~って思ってましたが、結局全然流行らなかったですよね... 一体何がダメだったんでしょうかねぇ~ 

www.nicovideo.jp

 

 YZY姉貴の元ネタの小悪魔はスペカが一枚も無いので私もスペカを作るのはやめました 「〇符」のような名前は自分で考えたくないので、たいてい原作の原作を参考にしているからです 「キャラクターのスペカ名がイメージと違う」とか思われたくないのです

 

以下解説 ↓

 

 一発目は渦巻状に弾を吐いた後に角度を変えてばらまきます 写真じゃわかりにくい...

f:id:sktks1609:20191207194928p:plain f:id:sktks1609:20191207195058p:plain

しょうがないからソースコードの一部をのせてお茶を濁しておきましょう 関連する部分全部をここに記すには余白が狭すぎる
private void shot1() {
 if(this.firstShotCount==0) {
  this.firstShotCount=200;
  this.firstShotRotate=AppManager.rnd.NextInt(360);
  this.isFirstRight=new java.util.Random().nextBoolean();
 }else {
  this.firstShotCount--;
  if(firstShotCount>=50){
   if(firstShotCount%7==0) {
    ShotType shotType;
    for(int i=0;i<=9;i++) {
     if(i%2==0) {
      shotType=ShotType.ENEMYYZYMIDDLEFIRSTSHOT1;
     }else {
      shotType=ShotType.ENEMYYZYMIDDLEFIRSTSHOT2;
     }
     this.createFirstShot(firstShotRotate+36*i,shotType);
    }
    if(this.isFirstRight) {
     firstShotRotate-=10;
    }else {
     firstShotRotate+=10;
    }
   }
  }
  if(this.firstShotCount==50) {
   Iterator<EnemyShot>enemyShots=

                                       this.getGameManager().objects.getEnemyShots();
   while(enemyShots.hasNext()) {
    EnemyShot shot=enemyShots.next();
    if(shot.getBarrageType().equals(BarrageType.STARTMOVINGIFORDER)) {
     StartMovingIfOrderShot shot2=(StartMovingIfOrderShot) shot;
     if(!shot2.isOrder) {
      shot.setxSpeed(0);
      shot.setySpeed(0);
     }
    }
   }
  }
  if(this.firstShotCount==0) {
  Iterator<EnemyShot>enemyShots=                                                                                          this.getGameManager().objects.getEnemyShots();
       int random=new java.util.Random().nextInt(10);
       int count=0;
       int speed=0;
       while(enemyShots.hasNext()) {
        EnemyShot shot=enemyShots.next();
        if(shot.getBarrageType().equals(BarrageType.STARTMOVINGIFORDER)) {
           StartMovingIfOrderShot shot2=(StartMovingIfOrderShot) shot;
           if(!shot2.isOrder) {
             count++;
             speed=2+(count%10)/5;
             shot2.setSpeed(speed);
             shot2.setIsDecideRotate(true,shot2.getNowRotate()+135+random*10);
             shot2.orderMoving();
           }
        }
      }
    }
  }
}

 私のガバガバ英単語がばれちゃう 馬鹿じゃねぇの(嘲笑)

 (追記)動画できました

 

 二発目はYZY姉貴の手の辺りから赤いうねうねビームが出て、口からオレンジのお札弾を吐きだします さっきのと違って今度は写真写りが良いですね ゲームでも大体こんな感じです

f:id:sktks1609:20191207202034p:plain f:id:sktks1609:20191207202047p:plain

 それはそうと、弾はデフォルトだと敵画像の中央から発射される、という仕様になっているのですが、このYZY姉貴の画像だと中央がちょうど口の部分にあたるわけですよ

f:id:sktks1609:20191207203621p:plain

 その結果、このように口からビームを出して、非常にシュールで間抜け面なのです

 

 三発目は耐久スペルです(スペルじゃないですが...)耐久スペルを作るのは初めてなのでボスクラスも少し変更して姿を消せるようにしました 弾幕は下図のように渦巻状の弾を放つだけです 初めは敵が一体なので楽勝ですが、時間経過で数が最大5まで増えます 耐久時間は80秒で、残り65秒から3体に、50秒から5体になります また残り25秒から弾速が速くなります

f:id:sktks1609:20191207204128p:plain f:id:sktks1609:20191207204142p:plain

 更にこの弾、直進せず放物線を描いて飛んでいきます これを作るのが意外と面倒でした まず、y=ax^2のグラフを描くように、手計算で弾の速さを表す式を作ります その時に、速さを一定にする為に速度式に補正値をかけないといけません これをしないと時間が経つにつれて弾の速さが加速度的に速くなってしまいます

 速度を表せたら、今度は求めた速度ベクトルを回転させます(回転できるようにしないと同じ所にしか弾が飛んでいかないのです) ベクトルの回転はいろいろやり方があると思いますが、私は複素数平面に飛ばして回転させるやり方が好きです 行列を使うやり方は知らないので...

 それが終われば後はプログラムを書くだけです

f:id:sktks1609:20191207210047p:plain  f:id:sktks1609:20191207210029p:plain

 

 四発目は「東方紅魔郷」6面、レミリアの「スカーレット・シュート」のような弾幕です ただし、あちらよりは簡単だと思いますね

f:id:sktks1609:20191207213812p:plain f:id:sktks1609:20191207213823p:plain

 「スーレット・シュート」だと上手く大弾を誘導する必要がありますが、こちらはそんな操作は不要です 弾速が遅いので大弾と小弾の塊の間を抜けられるからです 私は操作が下手くそなのでたまに事故りますが...

f:id:sktks1609:20191207214417p:plain

 

 これを撃破すればYZY姉貴は倒れます そして道中後半へ突入し、HZNの下へと向かっていきます 来週ぐらいに完成の目処が立つといいなぁ...