This commit is contained in:
Kevinmonitor 2023-01-26 18:34:56 +07:00
commit d3ada59252
391 changed files with 25819 additions and 0 deletions

BIN
script/sample/Effect01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
script/sample/Effect02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
script/sample/ExRumia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
script/sample/SampleA01.txt Normal file

Binary file not shown.

BIN
script/sample/SampleA02.txt Normal file

Binary file not shown.

BIN
script/sample/SampleA03.txt Normal file

Binary file not shown.

103
script/sample/SampleB01.txt Normal file
View file

@ -0,0 +1,103 @@
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["SampleB01"]
#Text["SampleB01: ObjPatternShot Demonstrations[r] Powered by Junko"]
#include "script/default_system/Default_ShotConst.txt"
let objEnemy;
let frame = 0;
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(500);
}
}
@Initialize {
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objEnemy, imgExRumia);
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objEnemy);
let cx = GetStgFrameWidth() / 2;
ObjMove_SetDestAtFrame(objEnemy, cx, 120, 60);
SetPlayerInvincibilityFrame(600000);
TShot();
}
@MainLoop {
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);
ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);
yield;
if (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0) {
Obj_Delete(objEnemy);
CloseScript(GetOwnScriptID());
return;
}
}
task TShot() {
let objPattern1 = ObjPatternShot_Create();
ObjPatternShot_SetParentObject(objPattern1, objEnemy);
ObjPatternShot_SetDelay(objPattern1, 12);
ObjPatternShot_SetGraphic(objPattern1, DS_BALL_S_RED);
ObjPatternShot_SetSpeed(objPattern1, 2, 1);
ObjPatternShot_SetAngle(objPattern1, 90, 0);
ObjPatternShot_SetPatternType(objPattern1, PATTERN_RING);
ObjPatternShot_SetShotCount(objPattern1, 22, 1);
ObjPatternShot_SetShootRadius(objPattern1, 48);
let objPattern2 = ObjPatternShot_Create();
ObjPatternShot_CopySettings(objPattern2, objPattern1);
ObjPatternShot_SetGraphic(objPattern2, DS_BALL_S_PURPLE);
ObjPatternShot_SetSpeed(objPattern2, 1, 1);
ObjPatternShot_SetShotCount(objPattern2, 10, 1);
wait(60);
let frame = 0;
while (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) {
if (frame % 30 == 0) {
ObjPatternShot_SetBasePointOffsetCircle(objPattern1, rand(0, 360), 32);
ObjPatternShot_Fire(objPattern1);
}
if (frame % 40 == 0 && frame > 75) {
for each (iX in [288, 96]) {
ObjPatternShot_SetBasePoint(objPattern2, iX, 144);
ObjPatternShot_SetBasePointOffsetCircle(objPattern2, rand(0, 360), 32);
ObjPatternShot_SetAngle(objPattern2, rand(0, 360), 0);
ObjPatternShot_Fire(objPattern2);
}
}
frame++;
yield;
}
Obj_Delete(objPattern1);
Obj_Delete(objPattern2);
}

View file

@ -0,0 +1,81 @@
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["SampleB02"]
#Text["SampleB02: ObjPatternShot Transforms 1"]
#include "script/default_system/Default_ShotConst.txt"
let objEnemy;
let frame = 0;
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(500);
}
}
@Initialize {
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objEnemy, imgExRumia);
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objEnemy);
let cx = GetStgFrameWidth() / 2;
ObjMove_SetDestAtFrame(objEnemy, cx, 120, 60);
TShot();
}
@MainLoop {
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);
ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);
yield;
if (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0) {
Obj_Delete(objEnemy);
CloseScript(GetOwnScriptID());
return;
}
}
task TShot() {
let objPattern = ObjPatternShot_Create();
ObjPatternShot_SetParentObject(objPattern, objEnemy);
ObjPatternShot_SetPatternType(objPattern, PATTERN_ARROW);
ObjPatternShot_SetDelay(objPattern, 12);
ObjPatternShot_SetGraphic(objPattern, DS_SCALE_BLUE);
ObjPatternShot_SetSpeed(objPattern, 1.5, 1.2);
ObjPatternShot_SetShotCount(objPattern, 3, 5);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_WAIT, 20);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 900, 0, 0.015, 0);
ObjPatternShot_SetShootRadius(objPattern, 32);
wait(60);
let frame = 0;
while (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) {
ObjPatternShot_SetAngle(objPattern, rand(0, 360), 6);
let ang_vel = 6.4 * sin(frame * 8);
ObjPatternShot_SetTransform(objPattern, 2, TRANSFORM_ANGULAR_MOVE, 30, ang_vel, 2);
ObjPatternShot_Fire(objPattern);
frame++;
wait(10);
}
}

View file

@ -0,0 +1,86 @@
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["SampleB03"]
#Text["SampleB03: ObjPatternShot Transforms 2 : Transform Harder"]
#include "script/default_system/Default_ShotConst.txt"
let objEnemy;
let frame = 0;
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(500);
}
}
@Initialize {
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objEnemy, imgExRumia);
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objEnemy);
let cx = GetStgFrameWidth() / 2;
ObjMove_SetDestAtFrame(objEnemy, cx, 120, 60);
SetPlayerInvincibilityFrame(600000);
TShot();
}
@MainLoop {
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);
ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);
yield;
if (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0) {
Obj_Delete(objEnemy);
CloseScript(GetOwnScriptID());
return;
}
}
task TShot() {
let objPattern = ObjPatternShot_Create();
ObjPatternShot_SetParentObject(objPattern, objEnemy);
ObjPatternShot_SetPatternType(objPattern, PATTERN_RING);
ObjPatternShot_SetDelay(objPattern, 12);
ObjPatternShot_SetGraphic(objPattern, DS_BALL_S_RED);
ObjPatternShot_SetSpeed(objPattern, 2, 1.2);
ObjPatternShot_SetShotCount(objPattern, 16, 1);
ObjPatternShot_SetInitialBlendMode(objPattern, BLEND_ADD_ARGB);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_WAIT, 20);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_N_DECEL_CHANGE, 25, 5, 1, 2.7, 10.12); //Think of Aunn's first spell
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADDPATTERN_A1, 0, 0, NO_CHANGE);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_WAIT, 60);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_BLEND_CHANGE, BLEND_ALPHA);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_GRAPHIC_CHANGE, DS_RICE_S_RED);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_TO_SPEED_ANGLE, 60, 1.8, NO_CHANGE);
wait(60);
let frame = 0;
while (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) {
ObjPatternShot_SetAngle(objPattern, rand(0, 360), 0);
ObjPatternShot_SetTransform(objPattern, 1, TRANSFORM_N_DECEL_CHANGE, 25, 5, 1, 2.7, 14 * sin(frame * 6));
ObjPatternShot_Fire(objPattern);
frame++;
wait(4);
}
}

View file

@ -0,0 +1,87 @@
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["SampleB04"]
#Text["SampleB04: ObjPatternShot Transforms 3 : 14 Werewolves[r]Transformation"]
#include "script/default_system/Default_ShotConst.txt"
let objEnemy;
let frame = 0;
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(2500);
}
}
@Initialize {
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objEnemy, imgExRumia);
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objEnemy);
SetPlayerInvincibilityFrame(6000000);
ObjMove_SetDestAtFrame(objEnemy, 192, 224, 60);
TShot();
}
@MainLoop {
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);
ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);
yield;
if (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0) {
Obj_Delete(objEnemy);
CloseScript(GetOwnScriptID());
return;
}
}
task TShot() {
wait(90);
while (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) {
_TShot(1, DS_RICE_M_PURPLE);
wait(330);
_TShot(-1, DS_RICE_M_RED);
wait(330);
}
}
task _TShot(dir, graphic) {
if (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0) { return; }
let objPattern = ObjPatternShot_Create();
ObjPatternShot_SetParentObject(objPattern, objEnemy);
ObjPatternShot_SetPatternType(objPattern, PATTERN_RING);
ObjPatternShot_SetShotType(objPattern, OBJ_CURVE_LASER);
ObjPatternShot_SetDelay(objPattern, 0);
ObjPatternShot_SetGraphic(objPattern, graphic);
ObjPatternShot_SetAngle(objPattern, rand(0, 360), 0);
ObjPatternShot_SetSpeed(objPattern, 6, 6);
ObjPatternShot_SetShotCount(objPattern, 28, 1);
ObjPatternShot_SetLaserParameter(objPattern, 8, 128);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 30, 0, 0, -8 * dir);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 30, 30, 0, 8 * dir);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 30, 60, -0.12, -4 * dir);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 30, 90, 0, 4 * dir);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 30, 120, 0, -8 * dir);
ObjPatternShot_AddTransform(objPattern, TRANSFORM_ADD_SPEED_ANGLE, 45, 150, 0, 7 * dir);
ObjPatternShot_Fire(objPattern);
Obj_Delete(objPattern);
}

BIN
script/sample/SampleE01.txt Normal file

Binary file not shown.

BIN
script/sample/SampleE02.txt Normal file

Binary file not shown.

View file

@ -0,0 +1,40 @@
#東方弾幕風[Stage]
#ScriptVersion[3]
#Title["SamplePS01"]
#Text["SamplePS01ピクセルシェーダトーン"]
#Background["script/default_system/Default_Background_IceMountain.txt"]
@Initialize
{
TSamplePS1();
}
@MainLoop
{
yield;
}
task TSamplePS1
{
//パス設定
let dir = GetCurrentScriptDirectory();
let pathShader = dir ~ "SamplePS01_HLSL.txt";
//シェーダ生成
let objShader = ObjShader_Create();
ObjShader_SetShaderF(objShader, pathShader);
ObjShader_SetTechnique(objShader, "TecMonotone");
loop
{
//特定の描画優先度にシェーダを適応
SetShaderI(objShader, 0, 100);
loop(180){yield;}
//シェーダ解除
ResetShaderI(0, 100);
loop(180){yield;}
}
}

View file

@ -0,0 +1,59 @@
//================================================================
//大域設定値
//Texture
sampler sampler0_ : register(s0);
//================================================================
//--------------------------------
//ピクセルシェーダ入力値
struct PS_INPUT
{
float4 diffuse : COLOR0; //ディフューズ色
float2 texCoord : TEXCOORD0; //テクスチャ座標
float2 vPos : VPOS; //描画先座標
};
//--------------------------------
//ピクセルシェーダ出力値
struct PS_OUTPUT
{
float4 color : COLOR0; //出力色
};
//================================================================
// シェーダ
//--------------------------------
//ピクセルシェーダ
PS_OUTPUT PsMonotone( PS_INPUT In ) : COLOR0
{
PS_OUTPUT Out;
//テクスチャの色
float4 colorTexture = tex2D(sampler0_, In.texCoord);
//頂点ディフーズ色
float4 colorDiffuse = In.diffuse;
//合成
float4 color = colorTexture * colorDiffuse;
//モノトーンの計算
Out.color.rgb = ( color.r + color.g + color.b ) * 0.3333f;
Out.color.a = color.a;
return Out;
}
//================================================================
//--------------------------------
//technique
technique TecMonotone
{
pass P0
{
PixelShader = compile ps_3_0 PsMonotone();
}
}

View file

@ -0,0 +1,36 @@
#東方弾幕風[Stage]
#ScriptVersion[3]
#Title["SamplePS02"]
#Text["SamplePS02ピクセルシェーダマスク"]
#Background["script/default_system/Default_Background_IceMountain.txt"]
@Initialize
{
TSamplePS2();
}
@MainLoop
{
yield;
}
task TSamplePS2
{
//パス設定
let dir = GetCurrentScriptDirectory();
let pathShader = dir ~ "SamplePS02_HLSL.txt";
//シェーダ生成
let objShader = ObjShader_Create();
ObjShader_SetShaderF(objShader, pathShader);
ObjShader_SetTechnique(objShader, "TecMask");
//シェーダにマスク画像を設定
let pathMask = dir ~ "SamplePS02_Mask.png";
ObjShader_SetTexture(objShader, "textureMask_", pathMask);
//特定の描画優先度にシェーダを適応
SetShaderI(objShader, 30, 100);
}

View file

@ -0,0 +1,85 @@
//================================================================
//大域設定値
//Texture
sampler sampler0_ : register(s0);
//--------------------------------
//マスク用テクスチャ
//画面幅(マスクテクスチャサイズ)
const float SCREEN_WIDTH = 640;
const float SCREEN_HEIGHT = 480;
texture textureMask_;
sampler samplerMask_ = sampler_state
{
Texture = <textureMask_>;
};
//================================================================
//--------------------------------
//ピクセルシェーダ入力値
struct PS_INPUT
{
float4 diffuse : COLOR0; //ディフューズ色
float2 texCoord : TEXCOORD0; //テクスチャ座標
float2 vPos : VPOS; //描画先座標
};
//--------------------------------
//ピクセルシェーダ出力値
struct PS_OUTPUT
{
float4 color : COLOR0; //出力色
};
//================================================================
// シェーダ
//--------------------------------
//ピクセルシェーダ
PS_OUTPUT PsMask( PS_INPUT In ) : COLOR0
{
PS_OUTPUT Out;
//テクスチャの色
float4 colorTexture = tex2D(sampler0_, In.texCoord);
//頂点ディフーズ色
float4 colorDiffuse = In.diffuse;
//合成
float4 color = colorTexture * colorDiffuse;
Out.color = color;
if(color.a > 0)
{
//--------------------------------
//マスク用のテクスチャから色成分を取得
//UVでの位置は画像ファイルの横幅と高さからの割合
//例えば、640x480の画像の位置(320,240)はUVでは0.5,0.5になる。
float2 maskUV;
//描画先からマスク用テクスチャの位置を計算
maskUV.x = In.vPos.x / SCREEN_WIDTH;
maskUV.y = In.vPos.y / SCREEN_HEIGHT;
float4 colorMask = tex2D(samplerMask_, maskUV);
//マスクのRGB値を出力結果のα値として合成する
Out.color.a = ( colorMask.r + colorMask.g + colorMask.b ) * 0.3333f * color.a;
}
return Out;
}
//================================================================
//--------------------------------
//technique
technique TecMask
{
pass P0
{
PixelShader = compile ps_3_0 PsMask();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View file

@ -0,0 +1,193 @@
#東方弾幕風[Single]
#ScriptVersion[3]
#Title["SamplePS03"]
#Text["SamplePS03ピクセルシェーダボス周囲のゆらぎエフェクト"]
#Background["script/default_system/Default_Background_IceMountain.txt"]
//デフォルト弾画像をロード
#include"script/default_system/Default_ShotConst.txt"
//----------------------------------------------------
//グローバル変数宣言
//この位置で宣言した変数はスクリプト全体で有効です。
//ただしこの箇所での変数への代入は、定数以外の代入は行えません。
//(実行順序が保障されないため乱数などの使用はできません)
//----------------------------------------------------
let objEnemy; //敵オブジェクト
let objPlayer; //自機オブジェクト
let frame = 0; //敵動作に使用するカウンタ(@MainLoopで1づつ増加させます)
//----------------------------------------------------
//敵の動作
//----------------------------------------------------
@Event
{
alternative(GetEventType())
case(EV_REQUEST_LIFE)
{
//敵ライフを要求された
SetScriptResult(500);//ライフを500に設定
}
}
@Initialize
{
//自機オブジェクト取得
objPlayer = GetPlayerObjectID();
//敵オブジェクトを生成し登録
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
//敵画像の設定
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png"; //敵画像ファイル
ObjPrim_SetTexture(objEnemy, imgExRumia); //画像ファイルを読み込む
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64); //描画元矩形を(64,1) - (127,64)に設定
ObjSprite2D_SetDestCenter(objEnemy); //描画先を中心(0, 0)に設定
//座標(cx, 120)へ60フレームかけて移動する
let cx = GetStgFrameWidth() / 2;//STGシーンの中心x座標を取得
ObjMove_SetDestAtFrame(objEnemy, cx, 120, 60);
//let objScene = GetEnemyBossSceneObjectID();
//ObjEnemyBossScene_StartSpell(objScene);
TWaveCircle();
}
@MainLoop
{
//敵の座標を取得
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
if(frame == 90)
{
let px = GetPlayerX();
ObjMove_SetDestAtFrame(objEnemy, rand(192-100, 192+100), rand(50, 200), 60);
}
if(frame == 180)
{
//frameが180になったら実行される部分
//自機の座標を取得
let px = GetPlayerX();
let py = GetPlayerY();
//敵からみた自機方向の角度を求める。
let angleToPlayer = atan2(py - ey, px - ex);
//angleを-30から15ずつ増加させ5WAYにする
let angle=0;
while(angle<360)
{//(angle15°間隔で0360まで)
//一定時間で自機方向へ角度を変える弾
//弾を作成する。
let obj = CreateShotA2(ex, ey, 5, angle, -0.10, 1, DS_RICE_S_BLUE, 30);
//発射後60フレーム目に、自機方向を基準に角度変更するように設定
ObjMove_AddPatternA4(obj, 60, 3, 0, 0, 0, 3, objPlayer, NO_CHANGE);
angle += 15;
}
frame = 0;//弾を出したらframeを0にする
}
//当たり判定登録
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);//当たり判定(自機弾用)登録
ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);//当たり判定(体当たり用)登録
//カウンタに1追加
frame++;
//ライフ0処理
if(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) <= 0)
{
//ライフが0になったら即座に終了
//本来は爆発エフェクトのタスクを登録し、
//エフェクト終了を待って、スクリプトを終了します。
yield;
Obj_Delete(objEnemy);
CloseScript(GetOwnScriptID());
return;
}
yield;
}
//----------------------------------------------------
//ボス周囲のゆらぎエフェクト
//----------------------------------------------------
task TWaveCircle()
{
//レンダリングターゲットに使用するテクスチャ
let renderTexture = GetReservedRenderTargetName(0);
let frame = 0; //フレーム
let baseEffectRadius = 128; //基準エフェクト半径
let outerFluct = 16; //エフェクト半径の最大変化量
let effectRadius = 0; //エフェクト半径
let priEffectMin = 20; //エフェクトをかける最小優先度
let priEffectMax = 28; //エフェクトをかける最大優先度
//背景のみエフェクトの対象とする
//エフェクトの描画でまかなえるため、
//優先度2028の通常描画を無効にする。
SetInvalidRenderPriorityA1(priEffectMin, priEffectMax);
let frameWidth = GetStgFrameWidth();
let frameHeight = GetStgFrameHeight();
let frameLeft = GetStgFrameLeft();
let frameRight = frameLeft + frameWidth;
let frameTop = GetStgFrameTop();
let frameBottom = frameTop + frameHeight;
//--------------------------------
//ゆがみオブジェクト
let objWave = ObjPrim_Create(OBJ_SPRITE_2D); //2Dスプライトオブジェクト生成
Obj_SetRenderPriorityI(objWave, 25); //描画優先度を設定
ObjPrim_SetTexture(objWave, renderTexture); //テクスチャを設定
ObjSprite2D_SetSourceRect(objWave, frameLeft, frameTop, frameRight, frameBottom);
ObjSprite2D_SetDestRect(objWave, 0, 0, frameWidth, frameHeight);
Obj_SetRenderPriorityI(objWave, priEffectMax + 1);
//ゆがみオブジェクトにシェーダを設定
let pathShader = GetCurrentScriptDirectory ~ "SamplePS03_HLSL.txt";
ObjShader_SetShaderF(objWave, pathShader);
ObjShader_SetTechnique(objWave, "TecWave");
//ボスのライフが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
//--------------------------------
//優先度2028(背景)をエフェクト用のテクスチャに描画
//シェーダ解除
RenderToTextureA1(renderTexture, priEffectMin, priEffectMax, true);
//--------------------------------
//シェーダにパラメータを設定
ObjShader_SetFloat(objWave, "frame_", frame);
ObjShader_SetFloat(objWave, "enemyX_", enemyX + frameLeft);
ObjShader_SetFloat(objWave, "enemyY_", enemyY + frameTop);
ObjShader_SetFloat(objWave, "waveRadius_", effectRadius);
frame++;
yield;
}
//エフェクト用オブジェクト削除
Obj_Delete(objWave);
ClearInvalidRenderPriority();
}

View file

@ -0,0 +1,107 @@
//================================================================
//大域設定値
//Texture
sampler sampler0_ : register(s0);
//--------------------------------
//ゆがみ生成用パラメータ
static const float RENDER_WIDTH = 1024; //レンダリングテクスチャの幅
static const float RENDER_HEIGHT = 1024; //レンダリングテクスチャの高さ
float frame_; //フレーム数
float enemyX_; //敵の位置X
float enemyY_; //敵の位置Y
float waveRadius_; //エフェクトの半径
//================================================================
//--------------------------------
//ピクセルシェーダ入力値
struct PS_INPUT
{
float4 diffuse : COLOR0; //ディフューズ色
float2 texCoord : TEXCOORD0; //テクスチャ座標
float2 vPos : VPOS; //描画先座標
};
//--------------------------------
//ピクセルシェーダ出力値
struct PS_OUTPUT
{
float4 color : COLOR0; //出力色
};
//================================================================
// シェーダ
//--------------------------------
//ピクセルシェーダ
PS_OUTPUT PsWave( PS_INPUT In ) : COLOR0
{
PS_OUTPUT Out;
//--------------------------------
//ゆらぎを計算
float dist2 = pow(In.vPos.x-enemyX_ ,2) + pow(In.vPos.y-enemyY_ ,2);
float dist = sqrt(dist2);
float sinTheta = (In.vPos.y - enemyY_) / dist;
float cosTheta = (In.vPos.x - enemyX_) / dist;
//歪み作成用のsinに使用する角度パラメータ
float angle = In.vPos.y - enemyY_ + In.vPos.x - enemyX_ + frame_;
angle = radians(angle);
//該当ピクセルの歪みの半径を計算
//エフェクト半径の1/16を最大の歪み幅とする
float waveRadius = waveRadius_ + waveRadius_/16 * (-1 + sin(angle));
//中心から距離が離れるほど影響を小さくする
float powerRatio = (waveRadius - dist) / waveRadius;
if(powerRatio < 0){powerRatio = 0;}
//色情報を取得する位置のバイアス値
float biasRadius = waveRadius * powerRatio;
float biasX = biasRadius * cosTheta;
float biasY = biasRadius * sinTheta;
//テクスチャの色情報を取得する位置
float2 texUV;
texUV.x = -biasX / RENDER_WIDTH + In.texCoord.x;
texUV.y = -biasY / RENDER_HEIGHT + In.texCoord.y;
//--------------------------------
//テクスチャの色
float4 colorTexture = tex2D(sampler0_, texUV);
//頂点ディフーズ色
float4 colorDiffuse = In.diffuse;
//合成
float4 color = colorTexture * colorDiffuse;
//色を赤っぽく変化させる
if(powerRatio > 0)
{
color.g = color.g * (1 - powerRatio);
color.b = color.b * (1 - powerRatio);
}
Out.color = color;
return Out;
}
//================================================================
//--------------------------------
//technique
technique TecWave
{
pass P0
{
PixelShader = compile ps_3_0 PsWave();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,78 @@
#TouhouDanmakufu[Stage]
#ScriptVersion[3]
#Title["SampleRC01"]
#Text["SampleRC01: Particle Rendering"]
@Initialize {
TSample();
}
@MainLoop {
yield;
}
task TSample() {
let dir = GetCurrentScriptDirectory();
let obj = ObjParticleList_Create(OBJ_PARTICLE_LIST_2D);
Obj_SetRenderPriorityI(obj, 21);
ObjPrim_SetTexture(obj, dir ~ "Effect01.png");
ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
//You may treat a 2D particle list object as a 2D primitive object.
ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLELIST);
ObjPrim_SetVertexCount(obj, 4);
ObjPrim_SetVertexUVT(obj, 0, 140, 39);
ObjPrim_SetVertexUVT(obj, 1, 186, 39);
ObjPrim_SetVertexUVT(obj, 2, 140, 86);
ObjPrim_SetVertexUVT(obj, 3, 186, 86);
ObjPrim_SetVertexPosition(obj, 0, -46 / 2, -47 / 2, 1);
ObjPrim_SetVertexPosition(obj, 1, 46 / 2, -47 / 2, 1);
ObjPrim_SetVertexPosition(obj, 2, -46 / 2, 47 / 2, 1);
ObjPrim_SetVertexPosition(obj, 3, 46 / 2, 47 / 2, 1);
//This is absolutely necessary, rendering will not be performed otherwise.
ObjPrim_SetVertexIndex(obj, [0, 1, 2, 1, 2, 3]);
loop {
CreateParticle();
yield;
}
task CreateParticle() {
let x = rand(0, 384);
let y = rand(0, 448);
let x_speed = rand(-1, 1);
let y_speed = rand(-1, 1);
let z_angle = rand(0, 360);
let z_add = rand(-5, 5);
let scale = rand(0.3, 0.7);
let timer_begin = floor(rand(10, 30 + 1));
ascent (i in 0..timer_begin) Update(Interpolate_Smooth(0, 1, i / (timer_begin - 1)));
loop (rand(30, 90)) Update(1);
let timer_end = floor(rand(10, 30 + 1));
descent (i in 0..timer_end) Update(Interpolate_Smooth(0, 1, i / (timer_end - 1)));
function Update(mul_scale) {
//Sets up instance data.
ObjParticleList_SetScale(obj, scale * mul_scale, scale * mul_scale, 1);
ObjParticleList_SetAngle(obj, 0, 0, z_angle);
ObjParticleList_SetPosition(obj, x, y, 1);
//Submits the current data to an instance, cleared every frame.
ObjParticleList_AddInstance(obj);
x += x_speed;
y += y_speed;
z_angle += z_add;
yield;
}
}
}

View file

@ -0,0 +1,75 @@
#TouhouDanmakufu[Stage]
#ScriptVersion[3]
#Title["SampleRC02"]
#Text["SampleRC02: Particle Rendering (Custom Shader)"]
@Initialize {
TSample();
}
@MainLoop {
yield;
}
task TSample() {
let dir = GetCurrentScriptDirectory();
let obj = ObjParticleList_Create(OBJ_PARTICLE_LIST_2D);
Obj_SetRenderPriorityI(obj, 21);
ObjPrim_SetTexture(obj, dir ~ "Effect01.png");
ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
//You may also treat a 2D particle list object as a 2D sprite object.
ObjSprite2D_SetSourceRect(obj, 140, 39, 186, 86);
ObjSprite2D_SetDestCenter(obj);
//This is absolutely necessary, rendering will not be performed otherwise.
ObjPrim_SetVertexIndex(obj, [0, 1, 2, 3]);
ObjShader_SetShaderF(obj, dir ~ "SampleRC02_HLSL.txt");
ObjShader_SetTechnique(obj, "Render");
loop {
CreateParticle();
yield;
}
task CreateParticle() {
let x = rand(0, 384);
let y = rand(0, 448);
let x_speed = rand(-1, 1);
let y_speed = rand(-1, 1);
let z_angle = rand(0, 360);
let z_add = rand(-5, 5);
let scale = rand(0.3, 0.7);
let timer_begin = floor(rand(10, 30 + 1));
ascent (i in 0..timer_begin) Update(Interpolate_Smooth(0, 1, i / (timer_begin - 1)));
loop (rand(30, 90)) Update(1);
let timer_end = floor(rand(10, 30 + 1));
descent (i in 0..timer_end) Update(Interpolate_Smooth(0, 1, i / (timer_end - 1)));
function Update(mul_scale) {
//Sets up instance data.
ObjParticleList_SetScale(obj, scale * mul_scale, scale * mul_scale, 1);
ObjParticleList_SetAngle(obj, 0, 0, z_angle);
ObjParticleList_SetPosition(obj, x, y, 1);
//Three slots are provided. You may put anything here, as long as they are floats.
ObjParticleList_SetExtraData(obj, y / 448, 0, 0);
//Submits the current data to an instance, cleared every frame.
ObjParticleList_AddInstance(obj);
x += x_speed;
y += y_speed;
z_angle += z_add;
yield;
}
}
}

View file

@ -0,0 +1,81 @@
sampler samp0_ : register(s0);
//The 4-by-4 matrix linked to WORLDVIEWPROJ semantic is provided by the engine.
// It is used to transform world coordinates to device coordinates.
float4x4 g_mWorldViewProj : WORLDVIEWPROJ : register(c0);
struct VS_INPUT {
//Vertex data
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
//Instance data
float4 i_color : COLOR1;
float4 i_xyz_pos_x_scale : TEXCOORD1; //Pack: (x pos, y pos, z pos, x scale)
float4 i_yz_scale_xy_ang : TEXCOORD2; //Pack: (y scale, z scale, x angle, y angle)
float4 i_z_ang_extra : TEXCOORD3; //Pack: (z angle, extra 1, extra 2, extra 3)
};
struct PS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
float exAlpha : FOG;
};
PS_INPUT mainVS(VS_INPUT inVs) {
PS_INPUT outVs;
float3 t_scale = float3(inVs.i_xyz_pos_x_scale.w, inVs.i_yz_scale_xy_ang.xy);
float2 ax = float2(sin(inVs.i_yz_scale_xy_ang.z), cos(inVs.i_yz_scale_xy_ang.z));
float2 ay = float2(sin(inVs.i_yz_scale_xy_ang.w), cos(inVs.i_yz_scale_xy_ang.w));
float2 az = float2(sin(inVs.i_z_ang_extra.x), cos(inVs.i_z_ang_extra.x));
//Creates the transformation matrix.
float4x4 matInstance = float4x4(
float4(
t_scale.x * (ay.y * az.y - ax.x * ay.x * az.x),
t_scale.x * (-ax.y * az.x),
t_scale.x * (ay.x * az.y + ax.x * ay.y * az.x),
0
),
float4(
t_scale.y * (ay.y * az.x + ax.x * ay.x * az.y),
t_scale.y * (ax.y * az.y),
t_scale.y * (ay.x * az.x - ax.x * ay.y * az.y),
0
),
float4(
t_scale.z * (-ax.y * ay.x),
t_scale.z * (ax.x),
t_scale.z * (ax.y * ay.y),
0
),
float4(inVs.i_xyz_pos_x_scale.x, inVs.i_xyz_pos_x_scale.y, inVs.i_xyz_pos_x_scale.z, 1)
);
outVs.diffuse = inVs.diffuse * inVs.i_color;
outVs.texCoord = inVs.texCoord;
outVs.position = mul(inVs.position, matInstance);
outVs.position = mul(outVs.position, g_mWorldViewProj);
outVs.position.z = 1.0f;
outVs.exAlpha = saturate(inVs.i_z_ang_extra.y);
return outVs;
}
float4 mainPS(PS_INPUT inPs) : COLOR0 {
float4 color = tex2D(samp0_, inPs.texCoord) * inPs.diffuse;
color.a *= inPs.exAlpha;
return color;
}
technique Render {
pass P0 {
VertexShader = compile vs_2_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
}

View file

@ -0,0 +1,87 @@
#TouhouDanmakufu[Stage]
#ScriptVersion[3]
#Title["SampleRC03"]
#Text["SampleRC03: Particle Rendering (Custom Shader, 3D)"]
@Initialize {
SetFogParam(256, 1000, 0, 0, 0);
TSample();
}
@MainLoop {
yield;
}
task TSample() {
let dir = GetCurrentScriptDirectory();
let obj = ObjParticleList_Create(OBJ_PARTICLE_LIST_3D);
Obj_SetRenderPriorityI(obj, 21);
ObjPrim_SetTexture(obj, dir ~ "Effect01.png");
ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
//You may treat a 3D particle list object as either a 3D primitive object or a 3D sprite object.
ObjSprite3D_SetSourceRect(obj, 140, 39, 186, 86);
ObjSprite3D_SetDestRect(obj, -46 / 2, -47 / 2, 46 / 2, 47 / 2);
//This is absolutely necessary, rendering will not be performed otherwise.
ObjPrim_SetVertexIndex(obj, [0, 1, 2, 3]);
ObjShader_SetShaderF(obj, dir ~ "SampleRC03_HLSL.txt");
ObjShader_SetTechnique(obj, "Render");
loop {
loop (7) CreateParticle();
yield;
}
task CreateParticle() {
let x = rand(-700, 700);
let y = rand(-700, 700);
let z = rand(-700, 700);
let x_speed = rand(-2, 2);
let y_speed = rand(-2, 2);
let z_speed = rand(-2, 2);
let x_angle = rand(0, 360);
let y_angle = rand(0, 360);
let z_angle = rand(0, 360);
let x_add = rand(-5, 5);
let y_add = rand(-5, 5);
let z_add = rand(-5, 5);
let scale = rand(0.3, 0.7);
let timer_begin = floor(rand(10, 30 + 1));
ascent (i in 0..timer_begin) Update(Interpolate_Smooth(0, 1, i / (timer_begin - 1)));
loop (rand(30, 90)) Update(1);
let timer_end = floor(rand(10, 30 + 1));
descent (i in 0..timer_end) Update(Interpolate_Smooth(0, 1, i / (timer_end - 1)));
function Update(mul_scale) {
//Sets up instance data.
let tmp_sc = scale * mul_scale;
ObjParticleList_SetScale(obj, tmp_sc, tmp_sc, tmp_sc);
ObjParticleList_SetAngle(obj, x_angle, y_angle, z_angle);
ObjParticleList_SetPosition(obj, x, y, z);
//Submits the current data to an instance, cleared every frame.
ObjParticleList_AddInstance(obj);
x += x_speed;
y += y_speed;
z += z_speed;
x_angle += x_add;
y_angle += y_add;
z_angle += z_add;
yield;
}
}
}

View file

@ -0,0 +1,108 @@
sampler samp0_ : register(s0);
//The following semantic-linked global variables are provided by the engine.
// WORLD (float4x4)
// The camera matrix. This can be ignored when the particle lists are not intended to be billboarded.
// VIEW (float4x4)
// The view matrix. Used to transform world coordinates to camera coordinates.
// PROJECTION (float4x4)
// The projection matrix. Used to transform camera coordinates to device coordinates.
// FOGENABLE (bool)
// A boolean indicating whether fog was enabled for the particle list object.
// FOGCOLOR (float4)
// The color of the fog set with SetFogParam. The packing format is (r, g, b, a).
// FOGDIST (float2)
// The ranges of the fog set with SetFogParam. The packing format is (fog start, fog end).
float4x4 g_mCamera : WORLD : register(c0);
float4x4 g_mView : VIEW : register(c4);
float4x4 g_mProj : PROJECTION : register(c8);
bool g_bUseFog : FOGENABLE : register(b0) = false;
float4 g_vFogColor : FOGCOLOR : register(c12) = float4(0.0f, 0.0f, 0.0f, 0.0f);
float2 g_vFogDist : FOGDIST : register(c13) = float2(0.0f, 256.0f);
struct VS_INPUT {
//Vertex data
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
//Instance data
float4 i_color : COLOR1;
float4 i_xyz_pos_x_scale : TEXCOORD1; //Pack: (x pos, y pos, z pos, x scale)
float4 i_yz_scale_xy_ang : TEXCOORD2; //Pack: (y scale, z scale, x angle, y angle)
float4 i_z_ang_extra : TEXCOORD3; //Pack: (z angle, extra 1, extra 2, extra 3)
};
struct PS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
float fogBlend : FOG;
};
PS_INPUT mainVS(VS_INPUT inVs) {
PS_INPUT outVs;
float3 t_scale = float3(inVs.i_xyz_pos_x_scale.w, inVs.i_yz_scale_xy_ang.xy);
float2 ax = float2(sin(inVs.i_yz_scale_xy_ang.z), cos(inVs.i_yz_scale_xy_ang.z));
float2 ay = float2(sin(inVs.i_yz_scale_xy_ang.w), cos(inVs.i_yz_scale_xy_ang.w));
float2 az = float2(sin(inVs.i_z_ang_extra.x), cos(inVs.i_z_ang_extra.x));
//Creates the transformation matrix.
//Calculate positions later after transformation with g_mCamera. Necessary for billboarded sprites to render correctly.
float4x4 matInstance = float4x4(
float4(
t_scale.x * (ay.y * az.y - ax.x * ay.x * az.x),
t_scale.x * (-ax.y * az.x),
t_scale.x * (ay.x * az.y + ax.x * ay.y * az.x),
0
),
float4(
t_scale.y * (ay.y * az.x + ax.x * ay.x * az.y),
t_scale.y * (ax.y * az.y),
t_scale.y * (ay.x * az.x - ax.x * ay.y * az.y),
0
),
float4(
t_scale.z * (-ax.y * ay.x),
t_scale.z * (ax.x),
t_scale.z * (ax.y * ay.y),
0
),
float4(0, 0, 0, 1)
);
outVs.diffuse = inVs.diffuse * inVs.i_color;
outVs.texCoord = inVs.texCoord;
outVs.position = mul(inVs.position, matInstance);
outVs.position = mul(outVs.position, g_mCamera);
//After billboarding has been accounted for, add the instance positions.
outVs.position.xyz += inVs.i_xyz_pos_x_scale.xyz;
outVs.position = mul(outVs.position, g_mView);
//Compute fog while the position is in camera space.
if (g_bUseFog)
outVs.fogBlend = saturate((g_vFogDist.y - outVs.position.z) / (g_vFogDist.y - g_vFogDist.x));
outVs.position = mul(outVs.position, g_mProj);
return outVs;
}
float4 mainPS(PS_INPUT inPs) : COLOR0 {
float4 color = tex2D(samp0_, inPs.texCoord);
if (g_bUseFog)
color.rgb = lerp(g_vFogColor.rgb, color.rgb, inPs.fogBlend);
return (color * inPs.diffuse);
}
technique Render {
pass P0 {
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
}

View file

@ -0,0 +1,64 @@
#TouhouDanmakufu[Stage]
#ScriptVersion[3]
#Title["SampleVS01"]
#Text["SampleVS01: Basic Vertex Shaders"]
@Initialize {
TSample();
}
@MainLoop {
if (GetKeyState(KEY_Q) == KEY_PUSH)
CloseStgScene();
yield;
}
task TSample() {
let dir = GetCurrentScriptDirectory();
let path = dir ~ "../default_system/img/Default_Background_IceMountain_Spell01.png";
let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
Obj_SetRenderPriorityI(obj, 23);
ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
ObjPrim_SetTexture(obj, path);
//Please do not actually use 10000 vertices
let VC = 5000;
ObjPrim_SetVertexCount(obj, VC * 2);
ObjRender_SetPosition(obj, 192, 224, 1);
ascent (i in 0..VC) {
let v_angle = 360 / (VC - 1) * i;
let tex_v = 1 / (VC - 1) * i;
ObjPrim_SetVertexPosition(obj, i * 2, 0, 0, 1);
ObjPrim_SetVertexPosition(obj, i * 2 + 1, 240 * cos(v_angle), 240 * sin(v_angle), 1);
ObjPrim_SetVertexUV(obj, i * 2, 0, tex_v);
ObjPrim_SetVertexUV(obj, i * 2 + 1, 1, tex_v);
}
//Enables vertex shader rendering.
//If this is set to true and a vertex+pixel shader isn't used, rendering will always fail.
ObjRender_SetVertexShaderRenderingMode(obj, true);
ObjShader_SetShaderF(obj, dir ~ "SampleVS01_HLSL.txt");
ObjShader_SetTechnique(obj, "Render");
let t = 0;
while (true) {
ObjShader_SetFloat(obj, "frame_", t);
/*
//Equivalent to these
ascent(i in 0..VC){
let tex_v = 1 / (VC - 1) * i;
ObjPrim_SetVertexUV(obj, i * 2, 0 - t, tex_v);
ObjPrim_SetVertexUV(obj, i * 2 + 1, 1 - t, tex_v);
}
*/
t += 0.006;
t %= 1;
yield;
}
}

View file

@ -0,0 +1,53 @@
sampler samp0_ : register(s0);
//2 top-level semantics are provided by the engine in the case of 2D render objects:
// WORLD:
// Contains the transformation matrix of the render object.
// VIEWPROJECTION:
// Contains the projection*camera matrix, used for correctly tranforming vertices to screen-space coordinates.
float4x4 g_mWorld : WORLD;
float4x4 g_mViewProj : VIEWPROJECTION;
float frame_;
struct VS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
};
struct PS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
};
struct PS_OUTPUT {
float4 color : COLOR0;
};
PS_INPUT mainVS(VS_INPUT inVs) {
PS_INPUT outVs;
outVs.diffuse = inVs.diffuse;
outVs.texCoord = inVs.texCoord;
outVs.position = mul(inVs.position, g_mWorld);
outVs.position = mul(outVs.position, g_mViewProj);
outVs.position.z = 1.0f;
return outVs;
}
PS_OUTPUT mainPS(PS_INPUT inPs) {
PS_OUTPUT outPs;
outPs.color = tex2D(samp0_, inPs.texCoord - float2(frame_, 0)) * inPs.diffuse;
return outPs;
}
technique Render {
pass P0 {
VertexShader = compile vs_2_0 mainVS();
PixelShader = compile ps_2_0 mainPS();
}
}

View file

@ -0,0 +1,164 @@
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["SampleVS02"]
#Text["SampleVS02: Vertex Shader-Based Distortion Effect"]
#Background["script/default_system/Default_Background_IceMountain.txt"]
#include "script/default_system/Default_ShotConst.txt"
let objEnemy;
let objPlayer;
let frame = 0;
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(500);
}
}
@Initialize {
objPlayer = GetPlayerObjectID();
objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objEnemy);
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objEnemy, imgExRumia);
ObjSprite2D_SetSourceRect(objEnemy, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objEnemy);
let cx = GetStgFrameWidth() / 2;
ObjMove_SetDestAtFrame(objEnemy, cx, 180, 60);
TWaveCircle();
TFinalize();
}
@MainLoop {
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
if (frame == 120) {
let px = GetPlayerX();
ObjMove_SetDestAtFrame(objEnemy, rand(192 - 80, 192 + 80), rand(100, 230), 40);
//ObjMove_SetDestAtFrame(objEnemy, 0, rand(120, 300), 40);
frame = 0;
}
ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);
frame++;
yield;
}
task TWaveCircle() {
wait(60);
let color = [1, 0.065, 0.065];
let renderTexture = GetReservedRenderTargetName(0);
let stripWave = [];
let countEdge = 32;
let countStrip = 4;
let maxRadius = 128;
let frameLeft = GetStgFrameLeft();
let frameTop = GetStgFrameTop();
let objWave = ObjPrim_Create(OBJ_PRIMITIVE_2D);
Obj_SetRenderPriorityI(objWave, 26);
ObjPrim_SetPrimitiveType(objWave, PRIMITIVE_TRIANGLELIST);
ObjPrim_SetTexture(objWave, renderTexture);
ObjPrim_SetVertexCount(objWave, countEdge * countStrip * 6);
ascent (i in 0..countStrip) {
let stripWidth = maxRadius / (countStrip - 1);
let rInEdge = stripWidth * i;
FillRingVertex(i * countEdge * 6, rInEdge, rInEdge + stripWidth);
}
ObjRender_SetVertexShaderRenderingMode(objWave, true);
ObjShader_SetShaderF(objWave, GetCurrentScriptDirectory() ~ "SampleVS02_HLSL.txt");
ObjShader_SetTechnique(objWave, "Render");
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
let nowRadius = 0;
let t = 0;
while (!Obj_IsDeleted(objEnemy)) {
ex = ObjMove_GetX(objEnemy);
ey = ObjMove_GetY(objEnemy);
if(nowRadius < maxRadius){
let tmp = sin((t + 1) / 50 * 90);
nowRadius = maxRadius * tmp;
}
Update();
}
{
let _radius = nowRadius;
descent(i in 0..30){
let tmp = sin((i + 1) / 30 * 90);
nowRadius = _radius * tmp;
Update();
}
}
Obj_Delete(objWave);
function Update() {
RenderToTextureA1(renderTexture, 20, 25, true);
ObjShader_SetFloat(objWave, "frame_", t);
ObjShader_SetFloat(objWave, "waveSine_", 0.8 + sin(t * 5) * 0.5);
ObjShader_SetFloatArray(objWave, "waveRadius_", [nowRadius, maxRadius]);
ObjShader_SetFloatArray(objWave, "enemyPos_", [ex + frameLeft, ey + frameTop]);
ObjShader_SetFloatArray(objWave, "waveColor_", color);
//ObjRender_SetPosition(objWave, ex, ey, 1);
t++;
yield;
}
function FillRingVertex(vi_start, r_inner, r_outer) {
ascent (i in 0..countEdge) {
let vi = vi_start + i * 6;
let v_angle = 360 / (countEdge - 1);
let s1 = sin(v_angle * i);
let c1 = cos(v_angle * i);
let s2 = sin(v_angle * (i + 1));
let c2 = cos(v_angle * (i + 1));
ObjPrim_SetVertexPosition(objWave, vi + 0, r_inner * c1, r_inner * s1, 1);
ObjPrim_SetVertexPosition(objWave, vi + 1, r_outer * c1, r_outer * s1, 1);
ObjPrim_SetVertexPosition(objWave, vi + 2, r_inner * c2, r_inner * s2, 1);
ObjPrim_SetVertexPosition(objWave, vi + 3, r_outer * c1, r_outer * s1, 1);
ObjPrim_SetVertexPosition(objWave, vi + 4, r_inner * c2, r_inner * s2, 1);
ObjPrim_SetVertexPosition(objWave, vi + 5, r_outer * c2, r_outer * s2, 1);
ObjPrim_SetVertexUVT(objWave, vi + 0, r_inner * c1, r_inner * s1);
ObjPrim_SetVertexUVT(objWave, vi + 1, r_outer * c1, r_outer * s1);
ObjPrim_SetVertexUVT(objWave, vi + 2, r_inner * c2, r_inner * s2);
ObjPrim_SetVertexUVT(objWave, vi + 3, r_outer * c1, r_outer * s1);
ObjPrim_SetVertexUVT(objWave, vi + 4, r_inner * c2, r_inner * s2);
ObjPrim_SetVertexUVT(objWave, vi + 5, r_outer * c2, r_outer * s2);
}
}
}
task TFinalize(){
while (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) { yield; }
Obj_Delete(objEnemy);
wait(120);
CloseScript(GetOwnScriptID());
}

View file

@ -0,0 +1,80 @@
sampler samp0_ : register(s0);
//2 top-level semantics are provided by the engine in the case of 2D render objects:
// WORLD:
// Contains the transformation matrix of the render object.
// VIEWPROJECTION:
// Contains the projection*camera matrix, used for correctly tranforming vertices to screen-space coordinates.
float4x4 g_mViewProj : VIEWPROJECTION;
float frame_;
float2 waveRadius_;
float waveSine_;
float2 enemyPos_;
float2 framePos_;
float3 waveColor_;
static const float RENDER_LEFT = 32.5f / 1024.0f; //mininum render width
static const float RENDER_TOP = 16.5f / 512.0f; //maximum render width
static const float RENDER_RIGHT = 415.5f / 1024.0f; //mininum render height
static const float RENDER_BOTTOM = 463.5f / 512.0f; //maximum render height
static const float2 SCREEN_SPACE = float2(1024.0f, 512.0f);
struct VS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
};
struct PS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
float blend : FOG;
};
struct PS_OUTPUT {
float4 color : COLOR0;
};
PS_INPUT mainVS(VS_INPUT inVs) {
PS_INPUT outVs;
float mul_scale = waveRadius_.x / waveRadius_.y;
float2 posVertex = inVs.position.xy * mul_scale;
float dist = length(inVs.position.xy * mul_scale);
outVs.blend = saturate((waveRadius_.x - dist) / waveRadius_.x);
float2 cos_sin = posVertex.xy / dist;
float2 distortPos = cos_sin.xy * waveRadius_.x * min(outVs.blend, 0.22f) * 0.5f * waveSine_;
distortPos.x += (cos_sin.x * outVs.blend) * 16.0f;
distortPos.y += (cos_sin.y * outVs.blend) * 16.0f;
outVs.texCoord = inVs.texCoord * mul_scale + enemyPos_ / SCREEN_SPACE;
outVs.position = mul(float4(posVertex + enemyPos_ + distortPos, inVs.position.zw), g_mViewProj);
outVs.position.zw = (float2)1.0f;
outVs.diffuse = inVs.diffuse;
return outVs;
}
PS_OUTPUT mainPS(PS_INPUT inPs) {
PS_OUTPUT outPs;
inPs.texCoord.x = clamp(inPs.texCoord.x, RENDER_LEFT, RENDER_RIGHT);
inPs.texCoord.y = clamp(inPs.texCoord.y, RENDER_TOP, RENDER_BOTTOM);
float3 colorRGB = tex2D(samp0_, inPs.texCoord).rgb;
colorRGB.rgb -= (1.0f - waveColor_.xyz) * inPs.blend;
outPs.color = float4(colorRGB, 1.0f) * inPs.diffuse;
return outPs;
}
technique Render {
pass P0 {
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
}

View file

@ -0,0 +1,74 @@
#TouhouDanmakufu[Stage]
#ScriptVersion[3]
#Title["SampleVS03"]
#Text["SampleVS03: Basic Vertex Shaders (3D)"]
@Initialize {
SetCameraFocusX(0);
SetCameraFocusY(0);
SetCameraFocusZ(0);
SetCameraRadius(800);
SetCameraElevationAngle(35);
SetCameraAzimuthAngle(0);
SetFogParam(0, 768, 64, 0, 0);
TSample();
}
@MainLoop {
if (GetKeyState(KEY_Q) == KEY_PUSH)
CloseStgScene();
yield;
}
task TSample() {
let dir = GetCurrentScriptDirectory();
let path = dir ~ "../default_system/img/Default_Background_IceMountain_Spell01.png";
let obj = ObjPrim_Create(OBJ_PRIMITIVE_3D);
Obj_SetRenderPriorityI(obj, 22);
ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
ObjPrim_SetTexture(obj, path);
let VC = 5000;
ObjPrim_SetVertexCount(obj, VC * 2);
ObjRender_SetPosition(obj, 320, 240, 1);
ascent (i in 0..VC) {
let v_angle = 360 / (VC - 1) * i;
let tex_v = 1 / (VC - 1) * i;
ObjPrim_SetVertexPosition(obj, i * 2, 0, 0, 1);
ObjPrim_SetVertexPosition(obj, i * 2 + 1, 256 * cos(v_angle), 256 * sin(v_angle), 1);
ObjPrim_SetVertexUV(obj, i * 2, 0, tex_v);
ObjPrim_SetVertexUV(obj, i * 2 + 1, 1, tex_v);
}
//Enables vertex shader rendering.
//If this is set to true and a vertex+pixel shader isn't used, rendering will always fail.
ObjRender_SetVertexShaderRenderingMode(obj, true);
ObjShader_SetShaderF(obj, dir ~ "SampleVS03_HLSL.txt");
ObjShader_SetTechnique(obj, "Render");
let t = 0;
while (true) {
ObjRender_SetAngleX(obj, -90);
ObjRender_SetAngleZ(obj, t * 70);
ObjShader_SetFloat(obj, "frame_", t);
/*
//Equivalent to these
ascent(i in 0..VC){
let tex_v = 1 / (VC - 1) * i;
ObjPrim_SetVertexUV(obj, i * 2, 0 - t, tex_v);
ObjPrim_SetVertexUV(obj, i * 2 + 1, 1 - t, tex_v);
}
*/
t += 0.003;
yield;
}
}

View file

@ -0,0 +1,64 @@
sampler sampler0_ : register(s0);
//The following semantic-linked global variables are provided by the engine.
// WORLD (float4x4)
// The transformation matrix of the render object.
// VIEW (float4x4)
// The view matrix. Used to transform world coordinates to camera coordinates.
// PROJECTION (float4x4)
// The projection matrix. Used to transform camera coordinates to device coordinates.
// FOGENABLE (bool)
// A boolean indicating whether fog was enabled for the render object.
// FOGCOLOR (float4)
// The color of the fog set with SetFogParam. The packing format is (r, g, b, a).
// FOGDIST (float2)
// The ranges of the fog set with SetFogParam. The packing format is (fog start, fog end).
float4x4 g_mWorld : WORLD : register(c0);
float4x4 g_mView : VIEW : register(c4);
float4x4 g_mProj : PROJECTION : register(c8);
float4 g_vFogColor : FOGCOLOR : register(c12);
float2 g_vFogDist : FOGDIST : register(c13);
float frame_;
struct VS_INPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
};
struct VS_OUTPUT {
float4 position : POSITION;
float4 diffuse : COLOR0;
float2 texCoord : TEXCOORD0;
float fog : FOG;
};
VS_OUTPUT mainVS(VS_INPUT InVs) {
VS_OUTPUT OutVs;
OutVs.diffuse = InVs.diffuse;
OutVs.texCoord = InVs.texCoord - float2(frame_, 0);
OutVs.position = mul(InVs.position, g_mWorld);
OutVs.position = mul(OutVs.position, g_mView);
OutVs.fog = saturate((g_vFogDist.y - OutVs.position.z) / (g_vFogDist.y - g_vFogDist.x));
OutVs.position = mul(OutVs.position, g_mProj);
return OutVs;
}
float4 mainPS(VS_OUTPUT InPs) : COLOR0 {
float4 color = tex2D(sampler0_, InPs.texCoord);
color.rgb = lerp(g_vFogColor.rgb, color.rgb, InPs.fog);
return color * InPs.diffuse;
}
technique Render {
pass P0 {
VertexShader = compile vs_3_0 mainVS();
PixelShader = compile ps_3_0 mainPS();
}
}