#東方弾幕風 #Title[天流「お天水の奇跡」] #Text[神奈子のコピー弾幕] #ScriptVersion[2] script_enemy_main { let name = "天流「お天水の奇跡」"; let imgBoss = "script\img\ExRumia.png"; @Initialize { CutIn(YOUMU, name, "", 0, 0, 0, 0); SetX(GetCenterX); SetY(GetCenterY - 64); SetLife(5000); LoadGraphic(imgBoss); SetTexture(imgBoss); setGraphicStop; TMain; } @MainLoop { SetCollisionA(GetX, GetY, 24); SetCollisionB(GetX, GetY, 24); yield; } @DrawLoop { DrawGraphic(GetX, GetY); } @Finalize { DeleteGraphic(imgBoss); } //メインタスク task TMain{ yield; //ショット準備タスクを起動 StandBy; //後は移動 loop{ move; }//loop }//task //ショット準備タスク //左から時間差をつけて滴が流れてくるのを再現する task StandBy{ //弾幕の設定 弾幕出現位置と画像を配列、しかし全部をascentで使うわけでないので余り意味が… let ShotPoint = [GetClipMinX + 32, GetCenterX - 96, GetCenterX - 32, GetCenterX +32, GetCenterX + 96, GetClipMaxX - 32]; let BulletColor = [RED21, YELLOW11, GREEN11, AQUA11, BLUE11, PURPLE21]; ShotL(ShotPoint[0], GetClipMinY, BulletColor[0], -90, false); wait(50); ascent (let i in 1..5){ Shot(ShotPoint[i], GetClipMinY, BulletColor[i], 0, true); wait(50); } ShotR(ShotPoint[5], GetClipMinY, BulletColor[5], 180, false); } //ショットタスク //変数をそのままオブジェクト弾制御タスクに渡して10フレームごとに滴弾を発射 //これと弾制御タスクは一緒にできそうだけど、そうすると弾変化を別タスクにしなきゃいけないのかな? task Shot(x, y, type, angle, shoot){ loop{ shizuku(x + rand(-30, 30), y, type, angle, shoot); wait(10); } } //左右端用のショットタスク task ShotL(x, y, type, angle, shoot){ loop{ shizuku(x + rand(-30, 30), y, type, angle, shoot); //左は半時計回り angle -= 3.6; wait(10); } } task ShotR(x, y, type, angle, shoot){ loop{ shizuku(x + rand(-30, 30), y, type, angle, shoot); //右は時計回り angle += 3.6; wait(10); } } //オブジェクト弾制御タスク //x, y :発射位置 //type :弾の画像 //angle :発射角 自機狙いの場合はタスク内で上書きされる //shoot :自機狙いかどうか truefalseで判断 task shizuku(x, y, type, angle, shoot){ let obj = Obj_Create(OBJ_SHOT); let changeY = GetClipMaxY - 144; //変化するY座標 //滴弾 Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetAngle(obj, 90); ObjShot_SetGraphic(obj, BLUE04); Obj_SetSpeed(obj, 7); //決めたY座標に来るまでループ while(Obj_GetY(obj) < changeY){;yield;} //ちょっと停止 Obj_SetSpeed(obj, 0); wait(10); //shootが真なら自機狙いに変化 if(shoot) { angle = atan2(GetPlayerY - Obj_GetY(obj) , GetPlayerX - Obj_GetX(obj)) ; } //弾変化 ObjShot_SetGraphic(obj, type); Obj_SetSpeed(obj, 1); Obj_SetAngle(obj, angle); } //     ここから先は講座のコピペ //移動サブルーチン sub move { let wMove = 60; moveToPlayer(rand(40, 80), rand(-40, 40), wMove, GetClipMinX + 48, GetCenterY - 128, GetClipMaxX - 48, GetCenterY ); setGraphicMove; wait(wMove + 30); } // なるべくプレイヤーの方向に移動 // xMove : x 方向の移動量(正の数) // yAdd : y 方向の移動量 // frame : 移動に要するフレーム数 // left : 以下、可動範囲 // top : // right : // bottom : function moveToPlayer(xMove, yAdd, frame, left, top, right, bottom) { let x; let y; if(GetPlayerX < GetX) { // プレイヤーより右に敵がいれば、敵は左に動きます。 x = GetX - xMove; // 但し、敵が可動領域の左端よりも左にいくようなら、右に動きます。 if(x < left) { x = GetX + xMove; } } else { // さもなくば、敵は右に動きます。 x = GetX + xMove; // 但し、敵が可動領域の右端よりも右にいくようなら、左に動きます。 if(right < x) { x = GetX - xMove; } } // 可動領域の外に行く場合は、端っこで止めます。 y = GetY + yAdd; if(y < top) { y = top; } else if(bottom < y) { y = bottom; } SetMovePosition02(x, y, frame); } // グラフィックの設定 sub setGraphicStop { SetGraphicRect( 0, 0, 64, 64); } sub setGraphicPose { SetGraphicRect( 64, 0, 128, 64); } sub setGraphicLeft { SetGraphicRect(128, 0, 192, 64); } sub setGraphicRight { SetGraphicRect(192, 0, 256, 64); } sub setGraphicMove { if(GetSpeedX < 0) { setGraphicLeft; } else { setGraphicRight; } } // w フレームだけ待つ function wait(w) { loop(w) { yield; } } }