memo

ゲーム制作やデザインについての個人的メモ

【ティラノスクリプト】実行環境の判定方法

自分用メモです。

ティラノスクリプトを使っていて、プレイヤーのゲーム実行環境がブラウザ版なのかPC版なのか判定したいときが(自分は)あります。

自分のホームページで公開するならブラウザ向けとPC向けのゲームファイルをそれぞれ用意すれば良いのかもしれませんが、単純に容量が倍になってしまいます。
また、ノベルゲームコレクション等の投稿サイトはブラウザ版もPC版もひとつのゲームファイルから生成するみたいなのでこの手は使えません。

ということで、どちらかだけに適用したい内容があるときは実行環境を判定するコードを書いて条件分岐させるのが良さそうです。

☆コメント欄で情報をいただきました
ティラノスクリプトでは予めPC版かブラウザ版か判定するための関数が定義されているので、それを利用すると簡単に実行環境の判定と条件分岐ができます。

ここでは例として「PC版(node-webkitで動作している場合)のみ、右上の×(閉じるボタン)を押したときに本当に終了するかの確認ダイアログを出す」という内容のコードを書いてみます。

[iscript]
if ($.isNWJS()) {
	var win = require('nw.gui').Window.get();
	win.on("close",function() {
		$.confirm($.lang("exit_game"), function() {
			win.close(true);
		}, function() {
			that.kag.ftag.nextOrder();
		});
	});
}
[endscript]

同じゲームファイルでもブラウザ版ではif内のコードは実行されません。

***

以下は判定方法から書いたコードです。参考のために残しておきます。

// Node.js で動作しているか
var isNode = (typeof process !== "undefined" && typeof require !== "undefined");
// ブラウザ上(非Node.js)で動作しているか
var isBrowser = !isNode
// node-webkitで動作しているか
var isNodeWebkit;
try {
    isNodeWebkit = isNode ? (typeof require('nw.gui') !== "undefined") : false;
} catch(e) {
    isNodeWebkit = false;
}

コード引用元:javascript - JavaScript実行環境の判定方法について - スタック・オーバーフロー

これで条件分岐させるための準備ができました。
ここでは例として「PC版(node-webkitで動作している場合)のみ、右上の×(閉じるボタン)を押したときに本当に終了するかの確認ダイアログを出す」という内容のコードを書いてみます。

if (isNodeWebkit) {
	var win = require('nw.gui').Window.get();
	win.on("close",function() {
		$.confirm($.lang("exit_game"), function() {
			win.close(true);
		}, function() {
			that.kag.ftag.nextOrder();
		});
	});
}

同じゲームファイルでもブラウザ版ではif内のコードは実行されません。

注意点

KSファイルに書く場合は判定コードと条件分岐コートを同じ[iscript]内に書いてください。別の[iscript]に記載したい場合はティラノスクリプトの変数に代入すると使えるようになります。

[iscript]
// Node.js で動作しているか
var isNode = (typeof process !== "undefined" && typeof require !== "undefined");
// ブラウザ上(非Node.js)で動作しているか
var isBrowser = !isNode
// node-webkitで動作しているか
var isNodeWebkit;
try {
    isNodeWebkit = isNode ? (typeof require('nw.gui') !== "undefined") : false;
} catch(e) {
    isNodeWebkit = false;
}

sf.isNode = isNode;
sf.isBrowser = isBrowser ;
sf.isNodeWebkit = isNodeWebkit;
[endscript]

[iscript]
if (sf.isNodeWebkit) {
	var win = require('nw.gui').Window.get();
	win.on("close",function() {
		$.confirm($.lang("exit_game"), function() {
			win.close(true);
		}, function() {
			that.kag.ftag.nextOrder();
		});
	});
}
[endscript]

※自分の環境(Windows10/Chrome)でしか動作確認していないので、コードを使用される際は十分検討の上テストプレイを必ず行ってください。

【ティラノスクリプト】マウスカーソルが載ったときに何かする

ティラノスクリプトというかjQeryの話です。最近めっちゃ使うようになったのでメモがてらまとめておきます。
いろんな方法があると思いますが、ここではhoverメソッドを使ってマウスカーソルが載ったときの処理を実装してみます。他はなるべくタグを使って頑張ります。

f:id:onigirimgmg:20170605004103g:plain

DEMO(Chrome推奨)
hover_sample.ks(※Dropbox

サンプルに収録されてる素材しか使っていないのでコピペすれば動く……はず。
以下ざっくりとした解説です。

[button graphic="../fgimage/chara/akane/normal.png" target="*character_select" name="character_icon,akane_icon" x=500 y=50 width=150 height=150 fix=true]
[button graphic="../fgimage/chara/yamato/normal.png" target="*character_select" name="character_icon,yamato_icon" x=700 y=50 width=150 height=150 fix=true]

[anim name="character_icon" opacity=0 time=0]
[anim name="character_icon" opacity=255 time=500]

この部分でボタンを表示しています。ボタン画像は立ち絵をベースにCSS(後述)でトリミングやら背景色やら角丸やらを設定しました。なのでgraphicには立ち絵のパスを指定しています。
今回はボタンをクリックしても何も起きないようにしたかったので、fixをtrueにしてジャンプ先のラベル(*character_select)で[return]しています。
[anim]タグはボタンをふわっと表示させるためのものです。透明にした直後に500ミリ秒かけて不透明にしています。

[image layer=0 name="akane_select,back" storage="../image/config/c_btn.png" x=0 y=230 width=960 height=250]
[image layer=0 name="akane_select" storage="chara/akane/normal.png" x=50 y=40]
[ptext layer=0 name="akane_select,select_text" text="【あかね】" x=380 y=250 size=42 time=0]
[ptext layer=0 name="akane_select,select_text" text="なぜかゲーム制作に詳しい女の子。<br>楽して儲けようとする人には厳しい。<br>※個人の見解によるものです" x=400 y=320 size=32 time=0]
[anim name="akane_select" opacity=0 time=0]

ここの部分でマウスカーソルが載ったときに表示する要素を記述しています。
上から順番に、

  • 半透明の黒い帯(configの透明画像を再利用してCSSで背景色を指定してる)
  • キャラクター画像(立ち絵をそのまま表示)
  • キャラクター名(timeパラメータを指定しないと[anim]が効かないっぽい)
  • 説明文(同上)
  • 要素をいったん透明にするための[anim]

です。全部透明な状態で表示されています。

$(".akane_icon").hover(
	function(e) {
		$(".akane_select").css("opacity","1")
	},
	function(e) {
		$(".akane_select").css("opacity","0")
	}
);

この部分でマウスカーソルが載ったときの動きを設定しています。載ったときは要素を不透明にして、離れたときは要素を透明に戻しています。

参考:jQuery: マウスポインターが要素に出入りした時の処理を実装するには?(mouseover、mouseout、mouseenter、mouseleave、hover) - Build Insider


最後にCSSで色々見た目の設定をしました。以下のコードをtyrano.cssの最後とかにコピペしてください。

.character_icon {
	object-fit:none;
	border-radius:10px;
	box-shadow:5px 5px 5px rgba(0,0,0,0.5);
	-webkit-filter:grayscale(100%);
	filter:grayscale(100%);
}
.character_icon:hover {
	-webkit-filter:grayscale(0%);
	filter:grayscale(0%);
}
.akane_icon {
	object-position:50% 25%;
	background-color:#ffa500;
}
.yamato_icon {
	object-position:35% 25%;
	background-color:#1e90ff;
}

.select_text {
	cursor:default;
	text-shadow:2px 2px 5px black, -2px 2px 5px black, 2px -2px 5px black, -2px -2px 5px black;<feff>
}
.back {
	background:rgba(0,0,0,0.5);
}

別に画像を用意しなくて良いのでCSSは本当に便利だ。でもローカルとChromeでしか動作確認してないから使うときは気をつけてね。

動かないよ!まちがってるよ!等々ありましたらお気軽にご連絡ください~。

【ティラノスクリプト】クリック待ち画像を透過PNGにする+アニメーションさせる

クリック待ち画像(デフォルトでは文章の最後でぴょんぴょんしている水色のGIF画像)を透過PNGにしてCSSでアニメーションさせてみます。すこーしだけ本体部分を書き換えているので、バージョンアップに対応する際はご注意ください。

①画像を用意する

f:id:onigirimgmg:20170525010326p:plain
↑この画像を「nextpage.png」という名前で保存して、tyrano/images/system に入れます。「nextpage.gif」と同じフォルダです。
f:id:onigirimgmg:20170525180552p:plain:w300

②kag.tag.jsを書き換える

tyrano/plugins/kag/kag.tag.js を開いて、「nextpage.gif」を「nextpage.png」に書き換えます。テキストエディタの置換機能を使うと簡単にできます。
f:id:onigirimgmg:20170525181134p:plain:w300
Meryの場合:Ctrl+Rで「置換」を表示して、上のボックスに「nextpage.gif」を、下のボックスに「nextpage.png」を入力して「すべて置換」をクリックすると書き換えられます。

CSSを設定する

tyrano/tyrano.cssを開いてCSSを設定します。変更するのは170行目あたりにある「次へのクリックを促すアイコン」の下にある「.img_next」から始まる部分です。
f:id:onigirimgmg:20170525181714p:plain:w300
いくつかサンプルを載せておきます。CSSアニメーションについて詳しく知りたい場合は各自でググってください。

点滅する

f:id:onigirimgmg:20170525183257g:plain

.img_next{
	-webkit-animation: next 1s ease-in-out infinite alternate;
	animation: next 1s ease-in-out infinite alternate;
}
@-webkit-keyframes next {
	0% { opacity:1; }
	100% { opacity:0; }
}
@keyframes next {
	0% { opacity:1; }
	100% { opacity:0; }
}
上下に動く

f:id:onigirimgmg:20170525190923g:plain

.img_next{
	-webkit-animation: next 1s ease-in-out infinite alternate;
	animation: next 1s ease-in-out infinite alternate;
}
@-webkit-keyframes next {
	0% {-webkit-transform: translateY(0px);}
	100% {-webkit-transform: translateY(3px);}
}
@keyframes next {
	0% {transform: translateY(0px);}
	100% {transform: translateY(3px);}
}
Y軸で回転する

f:id:onigirimgmg:20170525184418g:plain

.img_next{
	-webkit-animation: next 1s ease-in-out infinite alternate;
	animation: next 1s ease-in-out infinite alternate;
}
@-webkit-keyframes next {
	0% { -webkit-transform:rotateY(0deg); }
	100% { -webkit-transform:rotateY(180deg); }
}
@keyframes next {
	0% { transform:rotateY(0deg); }
	100% { transform:rotateY(180deg); }
}
360°回転する

f:id:onigirimgmg:20170525190245g:plain
f:id:onigirimgmg:20170525190222p:plain ←この画像を使いました

.img_next{
	-webkit-animation: next 2s linear infinite;
	animation: next 2s linear infinite;
}
@-webkit-keyframes next {
	0% {-webkit-transform: rotate(0deg);}
	100% {-webkit-transform: rotate(360deg);}
}
@keyframes next {
	0% {transform: rotate(0deg);}
	100% {transform: rotate(360deg);}
}
拡大・縮小する

f:id:onigirimgmg:20170525185229g:plain
f:id:onigirimgmg:20170525185250p:plain ←この画像を使用しました

.img_next{
	-webkit-animation: next 1s ease-in-out infinite alternate;
	animation: next 1s ease-in-out infinite alternate;
}
@-webkit-keyframes next {
	0% { -webkit-transform:scale(1.0); }
	100% { -webkit-transform:scale(0.8); }
}
@keyframes next {
	0% { transform:scale(1.0); }
	100% { transform:scale(0.8); }
}

その他「こんなのできる?」というのがありましたらリクエストしてみてください。オリジナルのクリック待ち画像の制作も承ってます。お気軽にどーぞ。

【ティラノスクリプト】名前入力画面サンプル

主人公の名前等を入力させたいときに使う名前入力画面のサンプルをつくってみました。自分なりにすこーしだけ親切仕様にしたつもりです。

サンプル

別窓で表示する

ポイント
  • デフォルト名の表示
  • 入力欄をクリックすると全選択状態になる
  • RESETボタンでデフォルト名に戻す
  • 確認画面を出す(ここでRESETボタンを押すと最初に戻る)
  • 空欄でOKボタンを押すと警告を出す
ダウンロード

name_entry.zip(※Dropbox

おまけ

本編シナリオで主人公名を表示するときのマクロです。毎回[emb]タグを書くのは大変だし見づらい気がするので、マクロ化してみます。

名前表示欄

[macro name="主人公"]
#&f.player_name
[endmacro]

テキスト中

[macro name="主人公名"]
[emb exp="f.player_name"]
[endmacro]

実際に使用するときはこんな感じで。

[主人公]
わたしの名前は[主人公名]だ。[p]

※見やすいように日本語でマクロ名をつけていますが、最終的には全部置換で半角英数字にした方が無難かもしれません。

【ティラノスクリプト】[ptext]で表示した文字を中央寄せにしたい

小ネタといえば小ネタなんですが……[ptext]で表示した文字を中央寄せにしたいことってありませんか?私はセンタリング大好き人間なので、寄せたい!とよく思います。そんなとき、xで位置を見ながら何度も調整する……というのは面倒だなあ、なんとかしたいなあ、と思って色々試してみました。

①簡単に中央寄せにする

tyrano.cssCSSファイルならなんでも大丈夫だと思いますが、ここではわかりやすくこれを使います)の最後に以下のコードを追加するだけです。

.ptext_center {
	text-align:center;
}

使うときは[ptext]のxパラメータに0を、nameパラメータにptext_centerを指定してください。yはお好みの数値で。

[ptext layer=0 text="[ptext]で表示した文字を中央寄せにしたい!" x=0 y=300 size=30 color=black bold=bold name="ptext_center"]

実行結果
f:id:onigirimgmg:20170519001232p:plain:w250
使い方としては、nameパラメータは複数指定できるので、固有のnameの他にptext_centerを付け足すのがいい感じかなあ、と思います。以下[ptext]に固有のnameを指定しつつ中央寄せにした例です。

[ptext layer=0 text="ゲームタイトル!" x=0 y=300 size=60 color=blue bold=bold name="game_title,ptext_center" time=0]
[anim name="game_title" opacity=0 time=0]
[anim name="game_title" opacity=255 top=250 time=1000]

実行結果
f:id:onigirimgmg:20170519002336g:plain:w250
ちなみに上下左右中央寄せにしたいときはこんな感じのコードで。640pxはゲーム画面の縦のサイズです。

.ptext_center {
	height:640px;
	display:flex;
	align-items:center;
	justify-content:center;
}

参考:【CSS】要素やテキストを上下左右に中央寄せする簡単な方法 | KuzLog
使うときはyパラメータも0にしてください。

[ptext layer=0 text="ど真ん中!" x=0 y=0 size=30 color=black bold=bold name="ptext_center"]

実行結果
f:id:onigirimgmg:20170519002948p:plain:w250

②[ptext]タグを改造する

困ったことがあるとすぐタグ改造に走っちゃうせっかちな君のためのコードも書いておくよ。もちろん改造は自己責任だよ。アップデートで仕様が変わる可能性もあるので気をつけてね。
kag.tag.js

tyrano.plugin.kag.tag.ptext = {
// 変更ここから
//vital: ["layer", "x", "y"],

vital: ["layer"],
// 変更ここまで
pm: {
"layer": "0",
"page": "fore",
"x": 0,
"y": 0,
"vertical": "false",
"text": "",
"size": "",
"face": "",
"color": "",
"italic": "",
"bold": "",
"name": "",
"time": "",
"zindex": "9999",
"overwrite": "false", // カンマ忘れない
// 追加ここから
"center":"false"
// 追加ここまで
},
start: function(pm) {
var that = this;
if (pm.face == "") pm.face = that.kag.stat.font.face;
if (pm.color == "") pm.color = $.convertColor(that.kag.stat.font.color);
else pm.color = $.convertColor(pm.color);
var font_new_style = {
"color": pm.color,
"font-weight": pm.bold,
"font-style": pm.fontstyle,
"font-size": pm.size + "px",
"font-family": pm.face,
"z-index": "999",
"text": ""
};
var target_layer = this.kag.layer.getLayer(pm.layer, pm.page);
if (pm.overwrite == "true" && pm.name != "")
if ($("." + pm.name).size() > 0) {
$("." + pm.name).html(pm.text);
this.kag.ftag.nextOrder();
return false
}
var tobj = $("

");
/* 削除ここから
tobj.css("position", "absolute");
tobj.css("top", pm.y + "px");
tobj.css("left", pm.x + "px");
tobj.css("width", "100%");
削除ここまで */
// 追加ここから

if (pm.center == "true") {
tobj.css("position", "absolute");
tobj.css("top", pm.y + "px");
tobj.css("width", "100%");
tobj.css("text-align", "center");
} else {
tobj.css("position", "absolute");
tobj.css("top", pm.y + "px");
tobj.css("left", pm.x + "px");
tobj.css("width", "100%");
}
// 追加ここまで
if (pm.vertical == "true") tobj.addClass("vertical_text");
$.setName(tobj, pm.name);
tobj.html(pm.text);
this.kag.setStyles(tobj,
font_new_style);
if (pm.layer == "fix") tobj.addClass("fixlayer");
if (pm.time != "") {
tobj.css("opacity", 0);
target_layer.append(tobj);
tobj.animate({
"opacity": 1
}, parseInt(pm.time), function() {
that.kag.ftag.nextOrder()
})
} else {
this.kag.ftag.nextOrder();
target_layer.append(tobj)
}
}
};

centerというパラメータを追加して、trueを指定したときのみ中央寄せにしています。使うときはこんな感じ。

[ptext layer=0 text="[ptext]で表示した文字を中央寄せにしたい!<br>複数行にも対応してるよ!" y=300 size=30 color=green bold=bold center=true]

実行結果
f:id:onigirimgmg:20170519005240p:plain:w250
動かないんだけど?とか、もっといい方法あるよ!などなどありましたらぜひお知らせください。これからもせっせとセンタリングライフです!