第17回

prev slash top slash next

第17回:召喚「豪族乱舞」 1

今回からは[召喚「豪族乱舞」(Normal)]です。
いつものように基本情報から見て行きましょう。

基本情報

出典:東方神霊廟Stage6
使用者:豊聡耳神子
制限時間:65秒
攻撃方法:
1: 開始から4s後に布都(右)&屠自古(左)を召喚
2: 150Fごとに自機方向に移動→4*8wayの矢弾の発射を3回繰り返す。
  1ループごとに1*8wayずつ増え、最終的に72way全方位弾になる
3: 1ループあたり620Fである
4: 3回撃つと一旦消滅し、最初の位置に戻る

といった流れです。
本家だと布都と屠自古が喋りまくりますが、今回は無しです。
出現&消滅モーションも面倒なので無しです。

使い魔

布都と屠自古の動きを再現するのには、使い魔を使うことにします。
使い魔を作成するには、[script_enemy]を使います。
script_enemyで作った敵は、[CreateEnemyFromScript]という関数で出現させることができます。

これまで、スクリプトを作成するときは、[script_enemy_main]を使っていました。
使い魔は、これまで作ってきたスクリプトと同じように作れるのです。
今回は実際に作り始める前に新しいフォルダを作りましょう。名前はなんでもいいです。
作ったらFamiliar.txtという名前でスクリプトファイルを保存しましょう。

では、実際にスクリプトを書いてみましょう。script_enemy_mainと違うところは、
script_enemy の後に[敵スクリプト名を登録する]というところです。

script_enemy Familiar
{
 let imgFamiliar = "script\img\ExRumia.png";
 @Initialize
 {
  LoadGraphic(imgFamiliar);
  SetLife(2000);
  SetDamageRateEx(0, 0, 0, 0);
  Tmain;
 }
 @MainLoop
 {
  yield;
 }
 @DrawLoop
 {
  DrawGraphic(GetX, GetY);
 }
 task Tmain
 {
  wait(240);//4s待機
  SetTexture(imgFamiliar);
  SetGraphicRect(0, 0, 63, 63);
  loop
  {
   yield;
  }
 }
 function nway(x, y, speed, anglebase, way, span, color)
 {
  let angle = anglebase - (way - 1) / 2 * span;
  loop(way)
  {
   CreateShot01(x, y, speed, angle, color, 10);
   angle += span;
  }
 }
 function offsetX(radius, angle)
 {
  return radius*cos(angle);
 }
 function offsetY(radius, angle)
 {
  return radius*sin(angle);
 }
 function wait(w){loop(w){yield}}  task SmoothMove(X,Y,Time,Time2) {
  // X x座標
  // Y y座標
  // Time 等速で移動する時間
  // Time2 減速して移動する時間
  let Distance = ((Y-GetY)^2+(X-GetX)^2)^0.5;
  let Speed = Distance/(Time*2+Time2)*2;
  SetAngle(atan2(Y-GetY,X-GetX));
  SetSpeed(Speed);
  loop(Time) {yield;}
  loop(Time2) {
   SetSpeed(GetSpeed-(Speed/(Time2*2)));
   yield;
   SetSpeed(GetSpeed-(Speed/(Time2*2)));
  }
  SetSpeed(0);
 }
}

これを軸にして作っていきましょう。まずは、移動の部分からです。
移動前に出現、移動後に消滅するという挙動は簡略化バージョンを使うことにしましょう。

task Move(X, radius)
{
 //X:一番始めの敵X座標の指定
 //radius:移動距離の指定
 SetX(X);
 SetY(GetCenterY);
 SetGraphicRect(0, 0, 63, 63);//出現
 wait(110);//出現モーションの分だけ待機
 loop(3)
 {
  let x = GetX + offsetX(radius, GetAngleToPlayer);
  let y = GetY + offsetY(radius, GetAngleToPlayer);
  SmoothMove(x, y, 60, 30);//90fかけて移動し、60f待機
  wait(150);
 }
 SetGraphicRect(0, 0, 0, 0);//消滅
 wait(60)//消滅エフェクトの分だけ待機、ここまでで610f経過
 Move(X, radius);//再起動
}

こうやって書くことで、
出現→110f待機→自機方向へ移動*3→消滅→60f待機→初期位置に戻って再出現
を繰り返すようになります。

次はn-way*8弾を発射する処理を作りましょう。

task Shot
{
 let angle;
 let way = 4;//初期way数
 while(way*8<72)//72way全方位弾になるまで繰り返し
 {
  wait(110);
  loop(3)
  {
   angle = rand(0, 360);
   wait(120);//移動している間待機
   loop(8)
   {
    nway(GetX, GetY, 1, angle, way, 5, BLUE11);//弾を発射、本来なら青矢弾です。
    angle+=360/8;
   }
   wait(30);
  }
 way++;
 wait(60);
 }
 loop//スクリプト終了までループ
 {
  wait(110);
  loop(3)
  {
   angle = rand(0, 360);
   wait(150);
   loop(72)
   {
    CreateShot01(GetX, GetY, 1, angle, BLUE11, 10);
    angle+=360/72;
   }
  }
 wait(60);
 }
}

これで、弾を撃つ部分は完成です。組み込んでみましょう。

script_enemy Familiar
{
 let imgFamiliar = "script\img\ExRumia.png";
 @Initialize
 {
  LoadGraphic(imgFamiliar);
  SetLife(2000);
  SetDamageRateEx(0, 0, 0, 0);
  Tmain;
 }
 @MainLoop
 {
  yield;
 }
 @DrawLoop
 {
  DrawGraphic(GetX, GetY);
 }
 task Tmain
 {
  wait(240);
  SetTexture(imgFamiliar);
  SetGraphicRect(0, 0, 63, 63);
  Move(GetX, 95);
  Shot;
  loop
  {
   yield;
  }
 }
 function nway(x, y, speed, anglebase, way, span, color)
 {
  let angle = anglebase - (way - 1) / 2 * span;
  loop(way)
  {
   CreateShot01(x, y, speed, angle, color, 10);
   angle += span;
  }
 }
 function offsetX(radius, angle)
 {
  return radius*cos(angle);
 }
 function offsetY(radius, angle)
 {
  return radius*sin(angle);
 }
 task SmoothMove(X,Y,Time,Time2) {
  let Distance = ((Y-GetY)^2+(X-GetX)^2)^0.5;
  let Speed = Distance/(Time*2+Time2)*2;
  SetAngle(atan2(Y-GetY,X-GetX));
  SetSpeed(Speed);
  loop(Time) {yield;}
  loop(Time2) {
   SetSpeed(GetSpeed-(Speed/(Time2*2)));
   yield;
   SetSpeed(GetSpeed-(Speed/(Time2*2)));
  }
  SetSpeed(0);
 }
 task Move(X, radius)
 {
  SetX(X);
  SetY(GetCenterY);
  SetGraphicRect(0, 0, 63, 63);
  wait(110);
  loop(3)
  {
   let x = GetX + offsetX(radius, GetAngleToPlayer);
   let y = GetY + offsetY(radius, GetAngleToPlayer);
   SmoothMove(x, y, 60, 30);
   wait(150);
  }
  SetGraphicRect(0, 0, 0, 0);
  wait(60);
  Move(X, radius);
 }  task Shot
 {
  let angle;
  let way = 4;
  while(way*8<72)
  {
   wait(110);
   loop(3)
   {
    angle = rand(0, 360);
    wait(120);
    loop(8)
    {
     nway(GetX, GetY, 1, angle, way, 5, BLUE11);
     angle+=360/8;
    }
    wait(30);
   }
  way++;
  wait(60);
  }
  loop
  {
   wait(110);
   loop(3)
   {
    angle = rand(0, 360);
    wait(150);
    loop(72)
    {
     CreateShot01(GetX, GetY, 1, angle, BLUE11, 10);
     angle+=360/72;
    }
   }
  wait(60);
  }
 }
 function wait(w){loop(w){yield}}
}

これで、使い魔の部分はほぼ完成です。
次回は敵スクリプト内で呼び出す処理を実装しましょう。


top
prev slash next
inserted by FC2 system