■エフェクトサンプル

描画エフェクトのサンプルです。

SampleE エフェクトサンプル
E01 モーションブラー
E02 ボス周囲のゆらぎ

※E01,E02はこのままでは、同時には実行できません。
 (どちらもGetReservedRenderTargetName(0)を使用しているため。)

E01 モーションブラー
モーションブラーです。
このサンプルでのモーションブラーは、前フレームの描画内容を利用した残像効果です。
前フレームの描画内容を半透明で現フレームに上書きすることで残像を残します。

サンプルではSTGフレーム全体にモーションブラーをかけていますが、
一部の描画優先度のみ(例えば弾のみ)にモーションブラーをかけることもできます。

以下の手順で行えます。
1) 現フレーム描画用テクスチャAに
 モーションブラー対象とする範囲の優先度を描画する。
2) 前フレームの描画内容であるテクスチャBを半透明でテクスチャAに描画。
3) テクスチャAを画面に描画する。
4) 1フレーム毎にテクスチャA/Bをきりかえ1)-3)を繰り返す。

task TMotionBlur()
{
	//レンダリングターゲットに使用するテクスチャ
	let renderTexture = [GetReservedRenderTargetName(0), GetReservedRenderTargetName(1)];

	//モーションブラーでの描画でまかなえるため、
	//優先度20〜79の通常描画を無効にする。
	SetInvalidRenderPriorityA1(20, 79);

	//現フレームを描画するオブジェクト
	let objCurentFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objCurentFrame, 80);//優先度80に描画する
	ObjRender_SetPermitCamera(objCurentFrame, false);

	//過去フレーム用オブジェクト
	let objOldFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objOldFrame, 0);
	ObjRender_SetPermitCamera(objOldFrame, false);
	ObjRender_SetAlpha(objOldFrame, 224);//α値はモーションブラーの強さになります
	Obj_SetVisible(objOldFrame, false);//過去フレーム用なので通常の描画がされないようにします。

	//ボスのライフが0になるまでモーションブラーをかける。
	let frame = 0;
	while(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0)
	{
		let currentFrameTexture = renderTexture[frame % 2];

		//優先度20〜79(STGフレーム全体)をテクスチャに描画する。
		RenderToTextureA1(currentFrameTexture, 20, 79, true);

		if(frame >= 1) 
		{
			//前フレームを現フレームに半透明描画
			//0フレーム目は前フレームがないためこの処理は行わない。
			let oldFrameTexture = renderTexture[(frame - 1) % 2];
			ObjPrim_SetTexture(objOldFrame, oldFrameTexture);
			ObjSprite2D_SetSourceRect(objOldFrame, 32, 16, 416, 464);
			ObjSprite2D_SetDestRect(objOldFrame, 32, 16, 416, 464);
			RenderToTextureB1(currentFrameTexture, objOldFrame, false);
		}

		//現フレーム描画用オブジェクトを設定
		ObjPrim_SetTexture(objCurentFrame, currentFrameTexture);
		ObjSprite2D_SetSourceRect(objCurentFrame, 32, 16, 416, 464);
		ObjSprite2D_SetDestRect(objCurentFrame, 32, 16, 416, 464);

		frame++;
		yield;
	}

	//モーションブラー用オブジェクト削除
	Obj_Delete(objCurentFrame);
	Obj_Delete(objOldFrame);
	ClearInvalidRenderPriority();
}



E02 ボス周囲のゆらぎ
ボス周囲のゆらぎエフェクトです。
←の画像ではゆらいでいるのがわかりづらいので
実際の動きは本体付属のサンプルスクリプトを実行お願いします。

以下の手順で行えます。
1) 描画用テクスチャに背景を描画する。
2) 背景を描画したテクスチャをゆがませて、画面に描画する。

	task TWaveCircle()
	{
		//レンダリングターゲットに使用するテクスチャ
		let renderTexture = GetReservedRenderTargetName(0);

		let frame = 0; //フレーム
		let baseEffectRadius = 144; //基準エフェクト半径
		let outerFluct = 16; //エフェクト半径の最大変化量
		let effectRadius = 0; //エフェクト半径
		let circleVertexCount = 16; //円をあらわすのに使用する頂点の数
		let innerCircleCount = 4;

		let priEffectMin = 20; //エフェクトをかける最小優先度
		let priEffectMax = 28; //エフェクトをかける最大優先度

		//背景のみエフェクトの対象とする
		//エフェクトの描画でまかなえるため、
		//優先度20〜28の通常描画を無効にする。
		SetInvalidRenderPriorityA1(priEffectMin, priEffectMax);


		let frameWidth = GetStgFrameWidth();
		let frameHeight = GetStgFrameHeight();
		let frameLeft = GetStgFrameLeft();
		let frameRight = frameLeft + frameWidth;
		let frameTop = GetStgFrameTop();
		let frameBottom = frameTop + frameHeight;

		//--------------------------------
		//円形の影
		let path = GetCurrentScriptDirectory() ~ "Effect02.png";
		let objShadow = ObjPrim_Create(OBJ_SPRITE_2D); //2Dスプライトオブジェクト生成
		Obj_SetRenderPriorityI(objShadow, 25); //描画優先度を設定
		ObjPrim_SetTexture(objShadow, path); //テクスチャを設定
		ObjRender_SetBlendType(objShadow, BLEND_MULTIPLY);
		ObjSprite2D_SetSourceRect(objShadow, 1, 1, 255, 255); //描画元設定(44, 54)-(71,105)
		ObjSprite2D_SetDestCenter(objShadow);
		ObjRender_SetScaleXYZ(objShadow, 1.2, 1.2, 0);


		//--------------------------------
		//円内
		let objInnerC = ObjPrim_Create(OBJ_PRIMITIVE_2D);
		Obj_SetRenderPriorityI(objInnerC, priEffectMax + 1);
		ObjPrim_SetTexture(objInnerC, renderTexture);
		ObjPrim_SetVertexCount(objInnerC, 6 * circleVertexCount * innerCircleCount);

		//円外〜エフェクト枠
		let objOuterC = ObjPrim_Create(OBJ_PRIMITIVE_2D);
		Obj_SetRenderPriorityI(objOuterC, priEffectMax + 1);
		ObjPrim_SetTexture(objOuterC, renderTexture); //テクスチャを設定
		ObjPrim_SetVertexCount(objOuterC, 3 * circleVertexCount);

		//エフェクト枠外オブジェクト
		let objOuterE = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
		Obj_SetRenderPriorityI(objOuterE, priEffectMax + 1);
		ObjPrim_SetTexture(objOuterE, renderTexture); //テクスチャを設定


		//ボスのライフが0になるまでエフェクトをかける。
		let objEnemy = GetEnemyBossObjectID[0];
		while(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0)
		{
			//エフェクト半径
			effectRadius = baseEffectRadius + outerFluct * sin(frame*4);

			let enemyX = ObjMove_GetX(objEnemy); //敵座標X
			let enemyY = ObjMove_GetY(objEnemy); //敵座標Y
			let circleLeft = enemyX - effectRadius + frameLeft; //エフェクト円の左端
			let circleRight = enemyX + effectRadius + frameLeft; //エフェクト円の右端
			let circleTop = enemyY - effectRadius + frameTop; //エフェクト円の上端
			let circleBottom = enemyY + effectRadius + frameTop; //エフェクト円の下端

			//--------------------------------
			//優先度20〜28(背景)をエフェクト用のテクスチャに描画
			RenderToTextureA1(renderTexture, priEffectMin, priEffectMax, true);

			//--------------------------------
			//影
			ObjRender_SetPosition(objShadow, enemyX, enemyY, 0);

			//--------------------------------
			//円内
			//エフェクト内円を描画
			//ゆらいでいる部分
			ObjRender_SetPosition(objInnerC, -frameLeft, -frameTop, 0);
			ascent(let iPosI in 0 .. circleVertexCount) 
			{
				let xyOldRadius = 0;
				ascent(let iCircle in 0 .. innerCircleCount) 
				{
					let vertexIndex = (iPosI * innerCircleCount + iCircle) * 6;
					let angle1 =  iPosI * (360 / circleVertexCount);
					let angle2 =  (iPosI + 1) * (360 / circleVertexCount);

					//テクスチャのUV座標
					let uvRadius1 = iCircle * effectRadius / innerCircleCount;
					let uvRadius2 = (iCircle + 1) * effectRadius / innerCircleCount;

					//テクスチャのUV座標と描画先のXY座標を変化させることでゆらぎを表現する
					let xyRadius1t = iCircle * effectRadius / innerCircleCount;
					let xyRadius2t = (iCircle + 1) * effectRadius / innerCircleCount;
					let xyRadius1 = xyOldRadius;
					let xyBias = (xyRadius2t - xyRadius1t) / 2 + (xyRadius2t - xyRadius1t) * sin(frame*16 + (iCircle * 360 / innerCircleCount)) / 4;
					let xyRadius2 = xyRadius2t + xyBias / ((innerCircleCount - iCircle + 1) / 2);

					xyOldRadius = xyRadius2;
					if(iCircle == innerCircleCount - 1)
					{
						xyRadius2 = uvRadius2;
					}

					//上記の頂点座標を設定
					let leftBias = enemyX + frameLeft;
					let topBias = enemyY + frameTop;
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex  , leftBias + xyRadius1 * cos(angle1), topBias + xyRadius1 * sin(angle1), 0);
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex+1, leftBias + xyRadius2 * cos(angle1), topBias + xyRadius2 * sin(angle1), 0);
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex+2, leftBias + xyRadius1 * cos(angle2), topBias + xyRadius1 * sin(angle2), 0);
				
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex+3, leftBias + xyRadius1 * cos(angle2), topBias + xyRadius1 * sin(angle2), 0);
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex+4, leftBias + xyRadius2 * cos(angle1), topBias + xyRadius2 * sin(angle1), 0);
					ObjPrim_SetVertexPosition(objInnerC, vertexIndex+5, leftBias + xyRadius2 * cos(angle2), topBias + xyRadius2 * sin(angle2), 0);

					ObjPrim_SetVertexUVT(objInnerC, vertexIndex  , leftBias + uvRadius1 * cos(angle1), topBias + uvRadius1 * sin(angle1));
					ObjPrim_SetVertexUVT(objInnerC, vertexIndex+1, leftBias + uvRadius2 * cos(angle1), topBias + uvRadius2 * sin(angle1));
					ObjPrim_SetVertexUVT(objInnerC, vertexIndex+2, leftBias + uvRadius1 * cos(angle2), topBias + uvRadius1 * sin(angle2));
				
					ObjPrim_SetVertexUVT(objInnerC, vertexIndex+3, leftBias + uvRadius1 * cos(angle2), topBias + uvRadius1 * sin(angle2));
					ObjPrim_SetVertexUVT(objInnerC, vertexIndex+4, leftBias + uvRadius2 * cos(angle1), topBias + uvRadius2 * sin(angle1));
					ObjPrim_SetVertexUVT(objInnerC, vertexIndex+5, leftBias + uvRadius2 * cos(angle2), topBias + uvRadius2 * sin(angle2));

				}
			}


			//--------------------------------
			//円外〜エフェクト枠
			//揺らいでいる円の外側から矩形までを埋める
			ObjRender_SetPosition(objOuterC, -frameLeft, -frameTop, 0);
			ascent(let iPosO in 0 .. circleVertexCount) 
			{
				let angle1 = iPosO * (360 / circleVertexCount);
				let angle2 = (iPosO + 1) * (360 / circleVertexCount);
				let rectX = 0;
				let rectY = 0;
				if(angle1 >= 0 && angle1 < 90)
				{
					rectX = circleRight;
					rectY = circleBottom;
				}
				else if(angle1 >= 90 && angle1 < 180)
				{
					rectX = circleLeft;
					rectY = circleBottom;
				}
				else if(angle1 >= 180 && angle1 < 270)
				{
					rectX = circleLeft;
					rectY = circleTop;
				}
				else if(angle1 >= 270 && angle1 < 360)
				{
					rectX = circleRight;
					rectY = circleTop;
				}
				let vertexIndex = iPosO * 3;
				ObjPrim_SetVertexPosition(objOuterC, vertexIndex, enemyX + effectRadius * cos(angle1) + frameLeft, enemyY + effectRadius * sin(angle1) + frameTop, 0);
				ObjPrim_SetVertexPosition(objOuterC, vertexIndex+1, rectX, rectY, 0);
				ObjPrim_SetVertexPosition(objOuterC, vertexIndex+2, enemyX + effectRadius * cos(angle2) + frameLeft, enemyY + effectRadius * sin(angle2) + frameTop, 0);

				ObjPrim_SetVertexUVT(objOuterC, vertexIndex, enemyX + effectRadius * cos(angle1) + frameLeft, enemyY + effectRadius * sin(angle1) + frameTop);
				ObjPrim_SetVertexUVT(objOuterC, vertexIndex+1, rectX, rectY);
				ObjPrim_SetVertexUVT(objOuterC, vertexIndex+2, enemyX + effectRadius * cos(angle2) + frameLeft, enemyY + effectRadius * sin(angle2) + frameTop);
			}
			

			//--------------------------------
			//エフェクト枠外
			//エフェクト枠外の背景を描画する
			ObjSpriteList2D_ClearVertexCount(objOuterE);
			ObjRender_SetPosition(objOuterE, -frameLeft, -frameTop, 0);
			ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, frameTop, frameRight, circleTop + 1);
			ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, frameTop, frameRight, circleTop + 1);
			ObjSpriteList2D_AddVertex(objOuterE);

			ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, circleTop, circleLeft + 1, circleBottom);
			ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, circleTop, circleLeft + 1, circleBottom);
			ObjSpriteList2D_AddVertex(objOuterE);

			ObjSpriteList2D_SetSourceRect(objOuterE, circleRight, circleTop, frameRight, circleBottom);
			ObjSpriteList2D_SetDestRect(objOuterE, circleRight, circleTop, frameRight, circleBottom);
			ObjSpriteList2D_AddVertex(objOuterE);

			ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, circleBottom, frameRight, frameBottom);
			ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, circleBottom, frameRight, frameBottom);
			ObjSpriteList2D_AddVertex(objOuterE);

			frame++;
			yield;
		}

		//エフェクト用オブジェクト削除
		Obj_Delete(objInnerC);
		Obj_Delete(objOuterC);
		Obj_Delete(objOuterE);
		Obj_Delete(objShadow);
		ClearInvalidRenderPriority();
	}
	



inserted by FC2 system