サンプル

以下で、なるべくコメントを付けながらサンプルを紹介します。
各サンプルはコピーペーストで貼り付けても動作するので、
いろいろ試してみてください。

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;
    			}
    		}

    	}