memo

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

【ティラノスクリプト?】プレイヤーに背景色や背景画像を変更してもらう

ティラノスクリプトというか、HTML5jQueryの話です。

先日更新した拙作「おばけアタック!」ですが、どこが変わったのかというと、コンフィグ(音量調節等ゲームの各種設定)が追加されたのです。

novelgame.jp

よかったら遊んでみてね。バッジもゲットできるよ。

(宣伝ですか?)
(宣伝だよ!)

私は環境設定マニアでして、ゲームを買ったりDLしたりすると必ず最初にコンフィグを開いてじっくり確認、自分の好みにいじりまくって設定しています。
プレイしやすさの向上という目的もありますが、単純に好きなんですね、コンフィグを見るのが。

といっても、「おばけアタック!」は性質上そんなに細かい設定は必要ありません。ノベルにお約束の文字速度設定もいらないし、スキップ機能も使ってないし……。
音量調節と確認ダイアログ設定の他に、なにか追加できる設定はないかな?と考えて思いついたのが……

背景色と背景画像の設定

です。ざっくり言うと「自分の好きな背景でゲームをプレイできるよ!」という謎機能です。

f:id:onigirimgmg:20171123155052g:plain

こんな感じで背景色と背景画像の設定ができます。背景画像は表示の仕方も変更できるよ。「デフォルトのオレンジが目に痛すぎてオレの実力が発揮できねえ!」と思っていた人も安心だね。

自分の環境以外でテストしていないので、不具合とかあったら教えてください。
というわけで、以下は技術的な話です。興味のある人はどーぞ。

背景色の設定

まずは背景色の設定です。
最初はいくつか候補を用意して、そこから選んでもらうようにしようかな~と思っていたのですが、どうせなら完全に自由に設定できる方が良いよね!と考え直し、色々調べていました。

すると、HTML5ではinputタグのtypeにcolorを指定できるという情報を入手。
参考:jQuery で色選択。input type=”color” を使ってみる

これやりたかったやつや!ありがてえありがてえ。

背景画像の設定

ローカル画像の表示についてはこちらを参考にさせていただきました。
参考:JavaScriptでローカル画像を表示する方法

2種類の方法があるのですが、Blob URLはページ移動するとアドレスが無効になってしまうので、今回はData URIを使いました。ティラノスクリプトでもサムネイル表示に使用されていますね。

やり方が分かったのでゲームに実装していきます。
直接スクリプトを見てもらった方がわかりやすいので置いときますね。

bg_change.ks(※Dropbox

以下ざっくりと解説。

今回は背景画像をレイヤー0に表示して、bg_imgという名前で管理してみました。bg_imgのbackground-colorを変更することで、背景色が変更できます。

[layopt layer=0 visible=true]
[image layer=0 name="bg_img" storage="base.png" x=0 y=0 width=960 height=640]

[iscript]
$(".bg_img").css({
	"background-color":sf.bg_color,
	"background-image":"url('" + sf.bg_img + "')",
	"background-position":"center"
});
[endscript]

背景色はsf.bg_color、背景画像はsf.bg_imgというシステム変数にしました。デフォルトではbg.pngというオバケくんのパターン背景が設定されています。
base.pngというのは1px×1pxの透明な画像です。これを差し替えることで背景画像を変更しています。

[iscript]
tf.bg_option = function bg_option() {
	if (sf.yoko == true) {
		$(".bg_img").css({
			"background-repeat":"no-repeat",
			"background-size":"100% auto"
		})
	};
	if (sf.tate == true) {
		$(".bg_img").css({
			"background-repeat":"no-repeat",
			"background-size":"auto 100%"
		})
	};
	if (sf.ippai == true) {
		$(".bg_img").css({
			"background-repeat":"no-repeat",
			"background-size":"100% 100%"
		})
	};
	if (sf.naraberu == true) {
		$(".bg_img").css({
			"background-repeat":"repeat",
			"background-size":"auto auto"
		})
	}
};

tf.bg_option();
[endscript]

tf.bg_optionというのは背景画像の表示設定です。デフォルトでは「並べて表示する(sf.naraberu=true)」になってます。
これは後でも使うので、関数にして「tf.bg_option()」と書くだけで使えるようにしました。これ最近知ったんですけど超便利ですね。

参考:background-size-CSS3リファレンス
参考:変数関係(3ページ目) - ティラノスクリプト 製作テクニックwiki

[iscript]
$(".layer_free").append('<input id="color-list" type="color" value="'+sf.bg_color+'" list="colors"><datalist id="colors"><option value="#f7931e"></option><option value="#9b72b0"></option></datalist>');

$("#color-list").css({
	"display":"block",
	"position":"absolute",
	"left":"265px",
	"top":"110px"
});

$("#color-list").on("change", function(){
	var val = $('#color-list').val();
	$(".bg_img").css("background-color",val);
	sf.bg_color = val;
	TG.kag.ftag.startTag("eval",{exp:"sf.bg_color = sf.bg_color"})
});
[endscript]

背景色の変更部分です。layer_free(クリック可能なレイヤー)にinputを挿入しています。optionでオレンジと紫を予めリストに追加しておきました。
$("#color-list").on("change", function(){~がリストをクリックしたときの動作です。valが選択した色(たぶん#○○○○○○で入ってる)です。
ゲームを終了して再起動したときもここで選んだ色が適用されるように、ここでシステム変数に代入しています(システム変数がどこで完全に代入されるかよくわかってなくて、evalをわざわざ入れてますが、動いたのでオッケーということで……)。

[iscript]
$(".layer_free").append('<input id="bg_img" type="file" accept="image/*">');

$("#bg_img").css({
	"display":"block",
	"position":"absolute",
	"left":"465px",
	"top":"110px"
});

$("#bg_img").on("change", function(){
	var fileList = this.files;
	var fileReader = new FileReader();
	fileReader.onload = function() {
		var dataUri = this.result;
		sf.bg_img = dataUri;
		TG.kag.ftag.startTag("eval",{exp:"sf.bg_img = sf.bg_img"});
		$(".bg_img").css("background-image","url('"+ sf.bg_img +"')");
		$(".bg_thumb").css("background-image","url('" + sf.bg_img + "')");
		tf.bg_thumb();
		tf.bg_option();
	};
	fileReader.readAsDataURL(fileList[0]);
});
[endscript]

背景画像の変更部分です。ほとんど参考サイトのまんまですが、今回は一つしかファイルが選択できないようにしてあります。また、背景画像の変更と同時にサムネイルも更新されるようにしてあります。ふかくかんがえない

[button fix=true target="*yoko" graphic="yoko.png" x=465 y=150 name="yoko"]
[button fix=true target="*tate" graphic="tate.png" x=515 y=150 name="tate"]
[button fix=true target="*ippai" graphic="ippai.png" x=565 y=150 name="ippai"]
[button fix=true target="*naraberu" graphic="naraberu.png" x=615 y=150 name="naraberu"]

[iscript]
if (sf.yoko == true) $(".yoko").attr("src","data/image/yoko_set.png");
if (sf.tate == true) $(".tate").attr("src","data/image/tate_set.png");
if (sf.ippai == true) $(".ippai").attr("src","data/image/ippai_set.png");
if (sf.naraberu == true) $(".naraberu").attr("src","data/image/naraberu_set.png");
[endscript]

背景画像の表示方法のボタンです。我ながら変数とかファイル名とかのネーミングセンスがちょっとアレだと思います。
現在有効な設定のボタンだけ色が変わるようになってます。ここら辺はデフォルトのコンフィグを参考につくりました。

[image layer=1 name="bg_thumb" storage="base.png" x=700 y=70 width=180 height=120]
[iscript]

tf.bg_thumb = function bg_thumb() {
	$(".bg_thumb").css("background-image","url('" + sf.bg_img + "')");
	
	var img = new Image();
	img.src = sf.bg_img;
	
	img.onload = function () {
		var img_width = img.width;
		var img_height = img.height;
		if (img_width <= 180 && img_height <= 120) {
			$(".bg_thumb").css("background-size","auto auto")
		} else {
			$(".bg_thumb").css("background-size","contain")
		}
	}
};

tf.bg_thumb();

$(".bg_thumb").css({
	"border":"1px #603813 solid",
	"background-repeat":"no-repeat",
	"background-position":"center"
});
[endscript]

背景画像のサムネイル表示部分です。確かスペースが余ったので入れました。ここでも関数使ってますね。
var img = new Image();~あたりでなにをやっているのかというと、サムネイルの背景画像の表示方法(原寸表示にするか、縮小表示にするか)を決めるために現在の背景画像のサイズを取得してifで分岐しています。無駄に色々やってる。

参考:JavaScriptで画像のサイズを取得する方法

動かないよ!間違ってるよ!等々ありましたら教えていただけると有難いです。