以下で、なるべくコメントを付けながらサンプルを紹介します。
各サンプルはコピーペーストで貼り付けても動作するので、
いろいろ試してみてください。
Sample.A | 弾幕風の組み込み関数のみを用いた弾操作サンプル |
A01 | 弾を真下に出す |
A02 | 自機方向へ5WAY |
A03 | 一定時間で自機方向へ角度を変える弾 |
A04 | 分裂する弾 |
Sample.B | 弾スクリプトを用いた弾操作サンプル |
B01 | ホーミング弾 |
Sample.C | オブジェクト操作関数を用いた弾操作サンプル |
C01 | オブジェクト操作関数を用いた弾作製 |
C02 | ホーミング弾(マイクロスレッド版) |
C03 | 特定の弾(A)に触れた弾(B)から、弾を出現させる |
C04 | レーザーに当たった弾の軌道を変える |
A01 弾を真下に出す | |
![]() |
弾を真下に出すサンプルです。 60フレーム(1秒)間隔で赤色の弾を真下に向かって出しつづけます。 |
#東方弾幕風 #Title[SampleA01] #Text[SampleA01:弾を真下に出す] #Image[] #ScriptVersion[2] script_enemy_main { let count; let cx; @Initialize { count=0;//弾を出す間隔を制御するための変数; cx=GetCenterX();//変数cxに真ん中の座標を代入; SetLife(1000);//敵のライフを1000に SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic("script\img\ExRumia.jpg");//script\img\ExRumia.jpgをテクスチャに読みこみ SetMovePosition02(cx,60,60);//座標(cx,60)に60フレームで移動 } @MainLoop { if(count==60) {//countが60になったら実行される部分 //敵の座標から真下に向かって弾を発射する //速度:1フレームに3 //角度:90 (真下) //遅延時間:30フレーム CreateShot01(GetX(),GetY(),3,90,RED01,30); count=0;//弾を出したらcountを0にする } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 } @DrawLoop { SetTexture("script\img\ExRumia.jpg");//描画元テクスチャを設定 DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize { DeleteGraphic("script\img\ExRumia.jpg");//読みこんだテクスチャを破棄 } } |
A02 自機方向へ5WAY | |
![]() |
自機方向へ5WAYを発射するサンプルです。 60フレーム(1秒)間隔で青色の5WAYを自機へ向かって出しつづけます。 SetShotDirectionType(PLAYER); で弾の角度を自機基準に変更したあと、 whileでループして5WAYにしています。 |
#東方弾幕風 #Title[SampleA02] #Text[SampleA02:自機方向へ5WAY] #Image[] #ScriptVersion[2] script_enemy_main { let count;//弾を出す間隔を制御するための変数; let cx;//変数cxに真ん中の座標を代入; @Initialize { count=0;//弾を出す間隔を制御するための変数; cx=GetCenterX();//変数cxに真ん中の座標を代入; SetLife(1000);//敵のライフを1000に SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic("script\img\ExRumia.jpg");//script\img\ExRumia.jpgをテクスチャに読みこみ SetMovePosition02(cx,60,60);//座標(cx,60)に60フレームで移動 } @MainLoop { if(count==60) {//countが60になったら実行される部分 SetShotDirectionType(PLAYER);//弾の角度を自機基準に変更 //angleを-30から15ずつ増加させ5WAYにする let angle=-30; while(angle<=30) {//(angle=-30, -15, 0, 15, 30) //敵の座標から自機に向かって5WAY弾を発射する //速度:1フレームに3 //角度:angle //遅延時間:30フレーム CreateShot01(GetX(),GetY(),3,angle,BLUE11,30); angle+=15; } count=0;//弾を出したらcountを0にする } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 } @DrawLoop { SetTexture("script\img\ExRumia.jpg");//描画元テクスチャを設定 DrawGraphic(GetX(),GetY())//敵の座標にExルーミアを描画; } @Finalize { DeleteGraphic("script\img\ExRumia.jpg");//読みこんだテクスチャを破棄 } } |
A03 一定時間で自機方向へ角度を変える弾 | ||
![]() |
→ | ![]() |
一定時間で自機方向へ角度を変える全方位弾を発射します。 CreateShotAで弾を作製し、ShotShotDataAを使うことで、角度を変化させます。 |
#東方弾幕風 #Title[SampleA03] #Text[SampleA03:一定時間で自機方向へ角度を変える弾] #Image[] #ScriptVersion[2] script_enemy_main { let count; let cx; @Initialize { count=0;//弾を出す間隔を制御するための変数; cx=GetCenterX();//変数cxに真ん中の座標を代入; SetLife(1000);//敵のライフを1000に SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic("script\img\ExRumia.jpg");//script\img\ExRumia.jpgをテクスチャに読みこみ SetMovePosition02(cx,120,60);//座標(cx,120)に60フレームで移動 } @MainLoop { if(count==180) {//countが180になったら実行される部分 let angle=0; while(angle<360) {//(angle:15°間隔で0〜360まで) //一定時間で自機方向へ角度を変える弾 let shot=0; CreateShotA(shot,GetX(),GetY(),30); SetShotDirectionType(ABSOLUTE);//弾の角度を絶対角度に変更 SetShotDataA(shot,0,5,angle,0,-0.15,1,BLUE11);//0フレームでの弾データ設定(初期設定) SetShotDirectionType(PLAYER);//弾の角度を自機基準に変更 SetShotDataA(shot,60,3,0,0,0,3,BLUE11);//60フレーム目で自機方向へ角度を変える FireShot(shot);//弾を発射 angle+=15; } count=0;//弾を出したらcountを0にする } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 } @DrawLoop { SetTexture("script\img\ExRumia.jpg");//描画元テクスチャを設定 DrawGraphic(GetX(),GetY())//敵の座標にExルーミアを描画; } @Finalize { DeleteGraphic("script\img\ExRumia.jpg");//読みこんだテクスチャを破棄 } } |
A04 分裂する弾 | ||||
![]() |
→ | ![]() |
→ | ![]() |
AddShotを使った分裂する弾です。 自機方向への3WAY(青)が、 それぞれ自機と逆方向への3WAY(赤)に分裂し、 さらに自機方向への5WAY(紫)に分裂します。 |
#東方弾幕風 #Title[SampleA04] #Text[SampleA04:分裂する弾] #Image[] #ScriptVersion[2] script_enemy_main { let count; let cx; @Initialize { count=300;//弾を出す間隔を制御するための変数; cx=GetCenterX();//変数cxに真ん中の座標を代入; SetLife(1000);//敵のライフを1000に SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic("script\img\ExRumia.jpg");//script\img\ExRumia.jpgをテクスチャに読みこみ SetMovePosition02(cx,120,60);//座標(cx,120)に60フレームで移動 } @MainLoop { if(count==360) {//countが360になったら実行される部分 SetShotDirectionType(PLAYER);//弾の角度を自機基準に変更 let i=-20; while(i<=20) {//(i=-20 ,0 ,20)の3WAY let shot1=1; CreateShotA(shot1,GetX(),GetY(),30);//shot1作製 SetShotDataA(shot1,0,4,i,0,0,0,BLUE21);//弾データ設定(shot1) let j=-15; while(j<=15) {//(j=-15 ,0 ,15)の3WAY let shot2=2; CreateShotA(shot2,0,0,10);//shot2作製 SetShotDataA(shot2,0,3,180+j,0,0,0,RED21);//弾データ設定(shot2) let k=-30; while(k<=30) {//(k=-30, -15 , 0 , 15, 30)の5WAY let shot3=3; CreateShotA(shot3,0,0,10);//shot3作製 SetShotDataA(shot3,0,2,k,0,0,0,PURPLE21);//弾データ設定(shot3) AddShot(60,shot2,shot3,0);//shot2にshot3を追加(60フレームでshot3放出) k+=15; } SetShotKillTime(shot2,61);//分裂直後に消滅 AddShot(45,shot1,shot2,0);//shot1にshot2を追加(60フレームでshot2放出) j+=15; } SetShotKillTime(shot1,46);//分裂直後に消滅 FireShot(shot1);//弾(shot1)を発射 i+=20; } count=0;//弾を出したらcountを0にする } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 } @DrawLoop { SetTexture("script\img\ExRumia.jpg");//描画元テクスチャを設定 DrawGraphic(GetX(),GetY())//敵の座標にExルーミアを描画; } @Finalize { DeleteGraphic("script\img\ExRumia.jpg");//読みこんだテクスチャを破棄 } } |
B01 ホーミング弾 | ||
![]() |
→ | ![]() |
自機へ向かってのホーミング弾です。 script_shotを使って実現します。 画面外にでても勝手に消えないので、300フレームで消えるようにしておきます。 script_shotは重いので注意してください。 |
#東方弾幕風 #Title[SampleB01] #Text[SampleB01:ホーミング弾] #Image[] #ScriptVersion[2] script_enemy_main { let count; let cx; @Initialize { count=300;//弾を出す間隔を制御するための変数; cx=GetCenterX();//変数cxに真ん中の座標を代入; SetLife(1000);//敵のライフを1000に SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic("script\img\ExRumia.jpg");//script\img\ExRumia.jpgをテクスチャに読みこみ SetMovePosition02(cx,60,60);//座標(cx,60)に60フレームで移動 } @MainLoop { if(count==360) {//ホーミング弾作製 CreateShotFromScript("Homing",GetX(),GetY(),3,GetAngleToPlayer()-90,0,0); CreateShotFromScript("Homing",GetX(),GetY(),3,GetAngleToPlayer(),0,0); CreateShotFromScript("Homing",GetX(),GetY(),3,GetAngleToPlayer()+90,0,0); count=0; } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 } @DrawLoop { SetTexture("script\img\ExRumia.jpg");//描画元テクスチャを設定 DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize { DeleteGraphic("script\img\ExRumia.jpg");//読みこんだテクスチャを破棄 } } script_shot Homing {//ホーミング弾を定義 let count=0; let angle=GetAngle();//進行角度取得 @Initialize { count=0; angle=GetAngle();//進行角度取得 SetDefault(BLUE21);//組み込みの弾をセット } @MainLoop { let toAngle=GetAngleToPlayer();//自機方向の角度取得 //dAngle:1フレームあたりの角度変化量限界 //dAngleを増加させるほどホーミング性能が増す let dAngle=2; let ret=toAngle-angle; if((ret>0&&ret<=180)||(ret<0&&ret<=-180)){angle+=dAngle;} else if((ret>0&&ret>180)||(ret<0&&ret>-180)){angle-=dAngle;} if(angle>=360){angle-=360;}//360°以上なら0〜360内に補正 if(angle<0){angle+=360;}//0°未満なら0〜360内に補正 SetAngle(angle); SetCollisionBDefault();//組み込みの弾の当たり判定を登録 if(count==300){End();}//300フレームで消滅 count++; } @DrawLoop { DrawGraphicDefault();//組み込みの弾を描画 } @Finalize { } } |
C01 オブジェクト操作関数を用いた弾作製 | |
![]() |
マイクロスレッドを用いてオブジェクト操作を行うサンプルです。 単に直進する弾を発射しているだけですが、多少ややこしいのでサンプルを作製しておきます。 この弾操作法も半スクリプト動作なので軽くはありません。 しかしながら、弾と弾の当り判定をとったりもでき、 多彩な弾幕を作製できます。 |
#東方弾幕風 #Title[SampleC01] #Text[SampleC01:オブジェクト操作関数を用いた弾作製] #Image[] #BackGround[User] #ScriptVersion[2] script_enemy_main { let count=0;//弾を出す間隔を制御するための変数 let cx=GetCenterX();//変数cxに中心x座標を代入 let cy=GetCenterY();//変数cxに中心y座標を代入 let imgExRumia=GetCurrentScriptDirectory~"img\ExRumia.png"; @Initialize() { SetLife(1000);//敵のライフを1000に設定 SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic(imgExRumia);//画像「img\ExRumia.png」を読みこむ SetMovePosition02(cx,cy,60);//座標(cx,cy)に60フレームで移動 } @MainLoop() { if(count==300) { let angle=0; while(angle<360) {//10°間隔で全方位に弾を発射 //弾タスク起動 ShotObject(GetX(),GetY(),2,angle,ORANGE21,10); angle+=10; } count=0; } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 yield;//毎フレームタスク復帰 } @DrawLoop() { SetTexture(imgExRumia); DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize() { DeleteGraphic(imgExRumia); } task ShotObject(let x, let y, let speed, let angle, let grf, let delay) { //弾タスク初期化 let obj = Obj_Create(OBJ_SHOT);//弾オブジェクトを作成 Obj_SetX(obj, x);//x座標設定 Obj_SetY(obj, y);//y座標設定; Obj_SetSpeed(obj, speed);//速度設定 Obj_SetAngle(obj, angle);//移動角度設定 ObjShot_SetGraphic(obj, grf);//画像設定 ObjShot_SetDelay(obj, delay);//遅延時間設定 while( !Obj_BeDeleted(obj) ) {//削除されるまでループを実行 yield; } } } |
C02 ホーミング弾(マイクロスレッド版) | ||
![]() |
→ | ![]() |
ホーミング弾のマイクロスレッド版です。 オブジェクト操作関数を用いても、弾スクリプトと同様のことができます。 (弾スクリプト版SampleB02と比べてみると違いが分かり易いです) |
#東方弾幕風 #Title[SampleC02] #Text[SampleC02:ホーミング弾(マイクロスレッド版)] #Image[] #BackGround[User] #ScriptVersion[2] script_enemy_main { let count=0;//弾を出す間隔を制御するための変数 let cx=GetCenterX();//変数cxに中心x座標を代入 let cy=GetCenterY();//変数cxに中心y座標を代入 let imgExRumia=GetCurrentScriptDirectory~"img\ExRumia.png"; let laserData=[]; @Initialize() { SetLife(1000);//敵のライフを1000に設定 SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic(imgExRumia);//画像「img\ExRumia.png」を読みこむ SetMovePosition02(cx,60,60);//座標(cx,60)に60フレームで移動 } @MainLoop() { if(count==360) { Homing(GetX(),GetY(),3,GetAngleToPlayer()-90,0); Homing(GetX(),GetY(),3,GetAngleToPlayer(),0); Homing(GetX(),GetY(),3,GetAngleToPlayer()+90,0); count=0; } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 yield;//毎フレームタスク起動 } @DrawLoop() { SetTexture(imgExRumia); DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize() { DeleteGraphic(imgExRumia); } task Homing(let x, let y, let speed, let angle, let delay) { //弾タスク初期化 let count = 0; let obj = Obj_Create(OBJ_SHOT);//弾オブジェクトを作成 Obj_SetX(obj, x);//x座標設定 Obj_SetY(obj, y);//y座標設定; Obj_SetSpeed(obj, speed);//速度設定 Obj_SetAngle(obj, angle);//移動角度設定 ObjShot_SetGraphic(obj, BLUE21);//画像設定 ObjShot_SetDelay(obj, delay);//遅延時間設定 while( !Obj_BeDeleted(obj) ) {//削除されるまでループを実行 //ホーミング let toAngle=atan2(GetPlayerY()-Obj_GetY(obj), GetPlayerX()-Obj_GetX(obj));//自機方向の角度取得 //dAngle:1フレームあたりの角度変化量限界 //dAngleを増加させるほどホーミング性能が増す let dAngle=2; let ret=toAngle-angle; if((ret>0&&ret<=180)||(ret<0&&ret<=-180)){angle+=dAngle;} else if((ret>0&&ret>180)||(ret<0&&ret>-180)){angle-=dAngle;} if(angle>=360){angle-=360;}//360°以上なら0〜360内に補正 if(angle<0){angle+=360;}//0°未満なら0〜360内に補正 Obj_SetAngle(obj, angle); if(count == 300){ObjShot_FadeDelete(obj);}//300フレームで消滅 count++; yield; } } } |
C03 特定の弾(A)に触れた弾(B)から、弾を出現させる | ||
![]() |
→ | ![]() |
弾と弾の当り判定をとるサンプルです。 ShotAに触れたShotBから自機方向に弾を出します 当り判定をとるためのShotAのオブジェクトを保存しているのがarrayShotAです。 ShotA初期化時にarrayShotAに追加し、ShotA消滅時にarrayShotAから削除しています。 当り判定はCollision_Obj_Objでとっています。 この関数でオブジェクト同士の当り判定を調べられます。 |
#東方弾幕風 #Title[SampleC03] #Text[SampleC03:特定の弾(A)に触れた弾(B)から、弾を出現させる] #Image[] #BackGround[User] #ScriptVersion[2] script_enemy_main { let count=0;//弾を出す間隔を制御するための変数 let cx=GetCenterX();//変数cxに中心x座標を代入 let cy=GetCenterY();//変数cxに中心y座標を代入 let imgExRumia=GetCurrentScriptDirectory~"img\ExRumia.png"; let arrayShotA=[];//ShotAのオブジェクトを保存しておく配列 @Initialize() { SetLife(1000);//敵のライフを1000に設定 SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic(imgExRumia);//画像「img\ExRumia.png」を読みこむ SetMovePosition02(cx,60,60);//座標(cx,60)に60フレームで移動 } @MainLoop() { if(count == 120) {//自機の周りにShotBを配置 let px = GetPlayerX();//自機のx座標取得 let py = GetPlayerY();//自機のy座標取得 let x = px - 160; while(x < px + 160) { let y = py - 160; while(y < py + 160) {//自機と距離が近い場所には出現させない if((x-px)^2 + (y-py)^2 > 40^2) { ShotB(x, y); } y+=20; } x+=20; } } else if(count == 240) {//240フレーム目にShotAタスクを起動 let pAngle = GetAngleToPlayer(); ShotA(GetX(), GetY(), rand(3,5), rand(pAngle-45, pAngle+45)); } else if(count == 480) {//480フレームで0フレーム目に戻す count=0; } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 yield;//毎フレームタスク復帰 } @DrawLoop() { SetTexture(imgExRumia); DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize() { DeleteGraphic(imgExRumia); } task ShotA(let x, let y, let speed, let angle) {//弾A(画面の大玉) //弾タスク初期化 let obj = Obj_Create(OBJ_SHOT);//弾オブジェクトを作成 arrayShotA = arrayShotA ~ [obj];//オブジェクトを追加 Obj_SetX(obj, x);//x座標設定 Obj_SetY(obj, y);//y座標設定; Obj_SetSpeed(obj, speed);//速度設定 Obj_SetAngle(obj, angle);//移動角度設定 ObjShot_SetGraphic(obj, RED03);//画像設定 while( !Obj_BeDeleted(obj) ) {//削除されるまでループを実行 yield; } let i=0; loop(length(arrayShotA)) {//arrayAから自身を削除 if(arrayShotA[i] == obj) {//配列arrayShotAからi番目(自身)の要素を削除 arrayShotA = erase(arrayShotA, i); break; } i++; } } task ShotB(let x, let y) {//ShotAに当たったら弾を自機方向に出す弾 //弾タスク初期化 let count=0; let obj = Obj_Create(OBJ_SHOT);//弾オブジェクトを作成 Obj_SetX(obj, x);//x座標設定 Obj_SetY(obj, y);//y座標設定; ObjShot_SetGraphic(obj, AQUA01);//画像設定 ObjShot_SetDelay(obj, 30); while( !Obj_BeDeleted(obj) ) {//削除されるまでループを実行 let i=0; loop(length(arrayShotA)) {//ShotAとの当り判定を調査 if(Collision_Obj_Obj(arrayShotA[i], obj)) {//ShotAと接触 CreateShot01(x, y, 3, atan2(GetPlayerY()-y, GetPlayerX()-x), PURPLE21, 10); Obj_Delete(obj);//触れたら削除 break; } i++; } if(count == 240) {//240フレームで消滅 ObjShot_FadeDelete(obj); break; } count++; yield; } } } |
C04 レーザーに当たった弾の軌道を変える | ||
![]() |
→ | ![]() |
弾とレーザーの当り判定をとるサンプルです。 敵の放つ弾の軌道が実体化したレーザーにあたると変化します。 Collision_Obj_Objで当り判定を調べます。 Collision_Obj_Objはレーザーと弾等、異なったオブジェクトの当り判定も可能です。 |
#東方弾幕風 #Title[SampleC04] #Text[SampleC04:レーザーに当たった弾の軌道を変える] #Image[] #BackGround[User] #ScriptVersion[2] script_enemy_main { let count= -90 ;//弾を出す間隔を制御するための変数 let cx=GetCenterX();//変数cxに中心x座標を代入 let cy=GetCenterY();//変数cxに中心y座標を代入 let imgExRumia=GetCurrentScriptDirectory~"img\ExRumia.png"; let arrayLaser=[];//LaserObjectのオブジェクトを保存しておく @Initialize() { SetLife(1000);//敵のライフを1000に設定 SetGraphicRect(64,1,127,64);//描画元の矩形を(64,1)-(127,64)に設定 LoadGraphic(imgExRumia);//画像「img\ExRumia.png」を読みこむ SetMovePosition02(cx,cy,60);//座標(cx,60)に60フレームで移動 } @MainLoop() { if(count>0 && count%30 == 0) {//30フレーム毎に弾をばらまく let angle = 0; while(angle<360) { ShotObject(GetX(), GetY(), 3, angle, AQUA21, 5); angle+=8; } } if(count == 60) {//弾の軌道を変えるレーザー作成 LaserObject(0,RED01); LaserObject(1,BLUE01); LaserObject(2,GREEN01); } if(count == 360) {//レーザー削除 let i=0; loop(length(arrayLaser)) { ObjShot_FadeDelete(arrayLaser[i]); i++; } count=0;//カウンタを0にする } SetCollisionA(GetX(),GetY(),32);//敵の座標に当たり判定を登録 SetCollisionB(GetX(),GetY(),24);//敵の座標に当たり判定(体当たり用)を登録 count++;//1フレーム毎にcountが1増加 yield;//毎フレームタスク復帰 } @DrawLoop() { SetTexture(imgExRumia); DrawGraphic(GetX(),GetY());//敵の座標にExルーミアを描画; } @Finalize() { DeleteGraphic(imgExRumia); } task LaserObject(let num, let grf) {//弾の軌道を変えるレーザー //numは0-2のセットで敵を中心に三角形にレーザーを出現させる //レーザータスク初期化 let r=120; let angle=210+120*num; let obj = Obj_Create(OBJ_LASER); arrayLaser = arrayLaser~[obj];//オブジェクトをarrayLaserに登録 Obj_SetX(obj, GetX() + r*cos(angle-150)); Obj_SetY(obj, GetY() + r*sin(angle-150)); Obj_SetAngle(obj, angle); ObjShot_SetGraphic(obj, grf); ObjShot_SetDelay(obj, 120);//遅延時間:120フレーム ObjLaser_SetLength(obj, (3^0.5)*r);//円に内接する正三角形の辺の長さ:√3*r ObjLaser_SetWidth(obj, 12);//レーザーの幅:12 while( !Obj_BeDeleted(obj) ) { angle+=1;//レーザーを回転 Obj_SetX(obj, GetX() + r*cos(angle-150)); Obj_SetY(obj, GetY() + r*sin(angle-150)); Obj_SetAngle(obj, angle); yield; } let i=0; loop(length(arrayLaser)) {//オブジェクトを削除 if(arrayLaser[i] == obj) {//配列arrayLaserからi番目の要素を削除 arrayLaser = erase(arrayLaser, i); break; } i++; } } task ShotObject(let x, let y, let speed, let angle, let grf, let delay) {//レーザーに当たったら軌道を変える弾 //弾タスク初期化 let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, speed); Obj_SetAngle(obj, angle); ObjShot_SetGraphic(obj, grf); ObjShot_SetDelay(obj, delay); while( !Obj_BeDeleted(obj) ) {//削除されるまでループを実行 let i=0; loop(length(arrayLaser)) {//レーザーとの当り判定を調査 if(Collision_Obj_Obj(arrayLaser[i], obj)) {//Laserと接触したら //連続で判定されないよう普通の弾と入れ替える //角度も変えておく //数フレーム触れないようにカウンタで管理してもよいかも x = Obj_GetX(obj); y = Obj_GetY(obj); CreateShot01(x, y, 3, Obj_GetAngle(arrayLaser[i])-90, grf, 0); Obj_Delete(obj); break; } i++; } yield; } } } |