2011年03月30日のツイート

遅延print

NScripterで、任意の画面Aから任意の画面Bへの遷移を行う場合、Aのルーチンが終了する時にAで使われているスプライトを全て始末し、printをせずにBのルーチンを開始して必要なスプライトを揃え、そこからはじめてprintを行うのがセオリーと考えられる。
Aが使ったスプライトはAが完全に始末する、以下同様。これを鉄則として守れば、画面間の遷移でスプライトの消し忘れ等による問題は、原理的に発生しえないことになる。
しかしここでもう一つの問題が発生する。すなわち、どのエフェクトでもって画面Bを表示すべきかである。print 1だけ使っていればそりゃあ問題はないが味気ない。しかし、遷移前の画面Aによっては、Bで使われるエフェクトの種類を変えたいと言うことも有り得る。

具体例

イベント絵のサムネイルが並べられたギャラリーモードを画面Aとする。そして、一つ一つのイベント絵を全体表示するのを画面Bとする。
この時、AからBへの遷移エフェクトは特別なもので、A→Bは「Aで選択されたサムネイルが拡大されてBになる」とし、B→Aは「Bが縮小してAの一部に収まる」と言う動作であるとする。
この二つの間の遷移関係では、A→Bは使用すべきエフェクトは一意に決定されるが、逆ではそうはならない。と言うのは、ギャラリーモードへは、通常タイトル画面から、あるいはちょっとひねたシステムなら、ゲーム中からでも遷移できるものの場合が多い。
仮に、タイトル画面をTとするならば、T→AはB→Aとは違うエフェクトを使用することが自然だとわかるだろう。
そこで必要になるのは、TやBのルーチンが終了する時に、Aを表示するのに使われるエフェクトを指定する仕組みである。

解決策

print_delay命令とprint_resolve命令を考案する。
print_delay命令は、通常のprintと同じ引数を取るが、それはすぐには実行されずにLua領域内の変数に保管される。
print_resolve命令はprint_delayによって保管された引数を実行する。実行された変数は消去される。もし、エフェクト番号等が保管されていなかった場合(print_resolveの空撃ち)は、print 1を実行するとする。
後、念のため、print_clearも作成しておこう。

スクリプト

do
	local arg = {}
	NSExec("luasub print_clear")
	function NSCOM_print_clear()
		arg = {}
	end
	NSExec("luasub print_delay")
	function NSCOM_print_delay()
		arg = {} -- 初期化
		arg[1] = NSPopInt()
		if NSCheckComma() then
			NSPopComma()
			arg[2] = NSPopInt()
		end
		if NSCheckComma() then
			NSPopComma()
			arg[3] = NSPopStr() -- 三つ目の引数があるとしたら、それは文字列。
		end
	end
	NSExec("luasub print_resolve")
	function NSCOM_print_resolve()
		if arg[1] then -- 引数がある場合
			local stuck = {} -- 一時退避用
			local exec = "_print "

			-- 第一引数
				stuck[1] = NSGetIntValue(1) -- 退避
				NSSetIntValue(1, arg[1]) -- 保存
				exec = exec .. "%1"
			-- 第二引数
			if arg[2] then
				stuck[2] = NSGetIntValue(2) -- 退避
				NSSetIntValue(2, arg[2]) -- 保存
				exec = exec .. ",%2"
			end
			if arg[3] then
				stuck[3] = NSGetStrValue(3) -- 退避
				NSSetStrValue(3, arg[3]) -- 保存
				exec = exec .. ",$3"
			end
			NSExec(exec) -- 実行
			
			-- 復帰
			if stuck[1] then NSSetIntValue(1, stuck[1]) end
			if stuck[2] then NSSetIntValue(2, stuck[2]) end
			if stuck[3] then NSSetStrValue(3, stuck[3]) end
			
			-- 引数を削除
			arg = {}
		else -- 引数がない場合
			NSUpdate() -- print 1 相当
		end
	end
end

注意点

print_delayによって保管されたprintへの引数は、Lua領域に保管されるため、間にsave&loadを挟んだ場合の動作は保証できない。print_delayからprint_resolveの間にセーブができるようにはしないように心がけること。

遅延print

NScripterで、任意の画面Aから任意の画面Bへの遷移を行う場合、Aのルーチンが終了する時にAで使われているスプライトを全て始末し、printをせずにBのルーチンを開始して必要なスプライトを揃え、そこからはじめてprintを行うのがセオリーと考えられる。
Aが使ったスプライトはAが完全に始末する、以下同様。これを鉄則として守れば、画面間の遷移でスプライトの消し忘れ等による問題は、原理的に発生しえないことになる。
しかしここでもう一つの問題が発生する。すなわち、どのエフェクトでもって画面Bを表示すべきかである。print 1だけ使っていればそりゃあ問題はないが味気ない。しかし、遷移前の画面Aによっては、Bで使われるエフェクトの種類を変えたいと言うことも有り得る。

具体例

イベント絵のサムネイルが並べられたギャラリーモードを画面Aとする。そして、一つ一つのイベント絵を全体表示するのを画面Bとする。
この時、AからBへの遷移エフェクトは特別なもので、A→Bは「Aで選択されたサムネイルが拡大されてBになる」とし、B→Aは「Bが縮小してAの一部に収まる」と言う動作であるとする。
この二つの間の遷移関係では、A→Bは使用すべきエフェクトは一意に決定されるが、逆ではそうはならない。と言うのは、ギャラリーモードへは、通常タイトル画面から、あるいはちょっとひねたシステムなら、ゲーム中からでも遷移できるものの場合が多い。
仮に、タイトル画面をTとするならば、T→AはB→Aとは違うエフェクトを使用することが自然だとわかるだろう。
そこで必要になるのは、TやBのルーチンが終了する時に、Aを表示するのに使われるエフェクトを指定する仕組みである。

解決策

print_delay命令とprint_resolve命令を考案する。
print_delay命令は、通常のprintと同じ引数を取るが、それはすぐには実行されずにLua領域内の変数に保管される。
print_resolve命令はprint_delayによって保管された引数を実行する。実行された変数は消去される。もし、エフェクト番号等が保管されていなかった場合(print_resolveの空撃ち)は、print 1を実行するとする。
後、念のため、print_clearも作成しておこう。

スクリプト

do
	local arg = {}
	NSExec("luasub print_clear")
	function NSCOM_print_clear()
		arg = {}
	end
	NSExec("luasub print_delay")
	function NSCOM_print_delay()
		arg = {} -- 初期化
		arg[1] = NSPopInt()
		if NSCheckComma() then
			NSPopComma()
			arg[2] = NSPopInt()
		end
		if NSCheckComma() then
			NSPopComma()
			arg[3] = NSPopStr() -- 三つ目の引数があるとしたら、それは文字列。
		end
	end
	NSExec("luasub print_resolve")
	function NSCOM_print_resolve()
		if arg[1] then -- 引数がある場合
			local stuck = {} -- 一時退避用
			local exec = "_print "

			-- 第一引数
				stuck[1] = NSGetIntValue(1) -- 退避
				NSSetIntValue(1, arg[1]) -- 保存
				exec = exec .. "%1"
			-- 第二引数
			if arg[2] then
				stuck[2] = NSGetIntValue(2) -- 退避
				NSSetIntValue(2, arg[2]) -- 保存
				exec = exec .. ",%2"
			end
			if arg[3] then
				stuck[3] = NSGetStrValue(3) -- 退避
				NSSetStrValue(3, arg[3]) -- 保存
				exec = exec .. ",$3"
			end
			NSExec(exec) -- 実行
			
			-- 復帰
			if stuck[1] then NSSetIntValue(1, stuck[1]) end
			if stuck[2] then NSSetIntValue(2, stuck[2]) end
			if stuck[3] then NSSetStrValue(3, stuck[3]) end
			
			-- 引数を削除
			arg = {}
		else -- 引数がない場合
			NSUpdate() -- print 1 相当
		end
	end
end

注意点

print_delayによって保管されたprintへの引数は、Lua領域に保管されるため、間にsave&loadを挟んだ場合の動作は保証できない。print_delayからprint_resolveの間にセーブができるようにはしないように心がけること。

2011年03月30日のツイート

遅延print

NScripterで、任意の画面Aから任意の画面Bへの遷移を行う場合、Aのルーチンが終了する時にAで使われているスプライトを全て始末し、printをせずにBのルーチンを開始して必要なスプライトを揃え、そこからはじめてprintを行うのがセオリーと考えられる。
Aが使ったスプライトはAが完全に始末する、以下同様。これを鉄則として守れば、画面間の遷移でスプライトの消し忘れ等による問題は、原理的に発生しえないことになる。
しかしここでもう一つの問題が発生する。すなわち、どのエフェクトでもって画面Bを表示すべきかである。print 1だけ使っていればそりゃあ問題はないが味気ない。しかし、遷移前の画面Aによっては、Bで使われるエフェクトの種類を変えたいと言うことも有り得る。

具体例

イベント絵のサムネイルが並べられたギャラリーモードを画面Aとする。そして、一つ一つのイベント絵を全体表示するのを画面Bとする。
この時、AからBへの遷移エフェクトは特別なもので、A→Bは「Aで選択されたサムネイルが拡大されてBになる」とし、B→Aは「Bが縮小してAの一部に収まる」と言う動作であるとする。
この二つの間の遷移関係では、A→Bは使用すべきエフェクトは一意に決定されるが、逆ではそうはならない。と言うのは、ギャラリーモードへは、通常タイトル画面から、あるいはちょっとひねたシステムなら、ゲーム中からでも遷移できるものの場合が多い。
仮に、タイトル画面をTとするならば、T→AはB→Aとは違うエフェクトを使用することが自然だとわかるだろう。
そこで必要になるのは、TやBのルーチンが終了する時に、Aを表示するのに使われるエフェクトを指定する仕組みである。

解決策

print_delay命令とprint_resolve命令を考案する。
print_delay命令は、通常のprintと同じ引数を取るが、それはすぐには実行されずにLua領域内の変数に保管される。
print_resolve命令はprint_delayによって保管された引数を実行する。実行された変数は消去される。もし、エフェクト番号等が保管されていなかった場合(print_resolveの空撃ち)は、print 1を実行するとする。
後、念のため、print_clearも作成しておこう。

スクリプト

do
	local arg = {}
	NSExec("luasub print_clear")
	function NSCOM_print_clear()
		arg = {}
	end
	NSExec("luasub print_delay")
	function NSCOM_print_delay()
		arg = {} -- 初期化
		arg[1] = NSPopInt()
		if NSCheckComma() then
			NSPopComma()
			arg[2] = NSPopInt()
		end
		if NSCheckComma() then
			NSPopComma()
			arg[3] = NSPopStr() -- 三つ目の引数があるとしたら、それは文字列。
		end
	end
	NSExec("luasub print_resolve")
	function NSCOM_print_resolve()
		if arg[1] then -- 引数がある場合
			local stuck = {} -- 一時退避用
			local exec = "_print "

			-- 第一引数
				stuck[1] = NSGetIntValue(1) -- 退避
				NSSetIntValue(1, arg[1]) -- 保存
				exec = exec .. "%1"
			-- 第二引数
			if arg[2] then
				stuck[2] = NSGetIntValue(2) -- 退避
				NSSetIntValue(2, arg[2]) -- 保存
				exec = exec .. ",%2"
			end
			if arg[3] then
				stuck[3] = NSGetStrValue(3) -- 退避
				NSSetStrValue(3, arg[3]) -- 保存
				exec = exec .. ",$3"
			end
			NSExec(exec) -- 実行
			
			-- 復帰
			if stuck[1] then NSSetIntValue(1, stuck[1]) end
			if stuck[2] then NSSetIntValue(2, stuck[2]) end
			if stuck[3] then NSSetStrValue(3, stuck[3]) end
			
			-- 引数を削除
			arg = {}
		else -- 引数がない場合
			NSUpdate() -- print 1 相当
		end
	end
end

注意点

print_delayによって保管されたprintへの引数は、Lua領域に保管されるため、間にsave&loadを挟んだ場合の動作は保証できない。print_delayからprint_resolveの間にセーブができるようにはしないように心がけること。

2011年03月30日のツイート