第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}}
}
これで、使い魔の部分はほぼ完成です。
次回は敵スクリプト内で呼び出す処理を実装しましょう。