ブラウザゲームを作る時にブラウザのサイズに合わせて画面を拡大/縮小する方法

##概要
HTML5とJavaScriptの組み合わせでモバイル向けブラウザゲームを作りたいときの小技です。
この解説ではadobe社が開発したCreateJSというフレームワークを使ってCanvasを操作します。

https://www.createjs.com/


##HTML５ソース

HTML5のサンプルを以下の通りに示します。

今回はcanvasの大きさは幅320px,高さ480pxにします。
これはiPhone3Gでブラウザを開いたときの縦横比で、iPhoneの後継機は総じてこれよりも縦長になります。できるだけ多くのモバイル端末でプレイすることを考え、ベースはこの縦横比にしながら、これより縦に長い端末では余った高さを余白にします。

CreateJSのライブラリを読み込み、ゲーム本体について書いているソースコードgame.jsへもリンクします。

```html

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<canvas id="myGame" width="320" height="480" ></canvas>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="game.js"></script>
</body>
</html>
```

##ゲーム画面サンプル

さて、CreateJSを使って、円形と四角だけで、ゲームのオープニング画面ぽく見えるサンプルを簡単にここで作ってみましょう。この画面を拡大/縮小してみましょう。

```javascript

//idが"myGame"のcanvas上にステージを作成する
var stage = new createjs.Stage("myGame");

//背景を真っ黒にする
var shape = new createjs.Shape();//図形を宣言する
shape.graphics.beginFill("black"); // 図形を塗りつぶす色を黒にする
shape.graphics.drawRect(0, 0, 320, 480); // 図形の形状を横320,縦480の四角形に設定する
stage.addChild(shape); // 完成させた図形をステージに加える

//ゲーム画面の上の方に円を加える
var shape2 = new createjs.Shape(); //図形を宣言する
shape2.graphics.beginFill("darkred"); //図形を塗りつぶす色を暗めの赤にする
shape2.graphics.drawCircle(150, 130, 100); //左から150,上から130の位置に半径100の円を描く
stage.addChild(shape2); //完成させた図形をステージに加える

//ゲーム画面の下の方に適当にゲームのオープニングっぽい雰囲気の文章を書く
var text = new createjs.Text("", "24px serif", "white"); //サイズ24のセリフ体,文字色が白のテキストを宣言する
text.y = 100; //上から100の位置に文字を配置する
text.text = "アメリカ大陸にかつて存在し\nていた古代アステカ文明では\n太陽神が信仰されていた。\n人々は太陽エネルギーによる\n魔法を使い、文明は栄華を極\nめていた。だが・・・";
stage.addChild(text);//完成させた文章をステージに加える


stage.update();//完成したステージをcanvas上に表示する
```

<img width="329" alt="スクリーンショット 2018-01-05 12.01.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/78116/81df956e-e832-dbdf-837d-dfb4f593d9cc.png">



##Canvasのサイズを変えてみると
それではcanvasのサイズを以下のように半分にしてみましょう。

```html

<canvas id="myGame" width="160" height="240" ></canvas>
```

<img width="176" alt="スクリーンショット 2018-01-05 12.07.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/78116/625f3b67-a285-df89-8ea0-20e53a6a67ee.png">

画面の一部が切り取られたような形になりました。これではゲームになりません。

逆に　画面サイズを1.5倍に拡大してみると

```html

<canvas id="myGame" width="480" height="720" ></canvas>
```

<img width="329" alt="スクリーンショット 2018-01-05 12.01.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/78116/81df956e-e832-dbdf-837d-dfb4f593d9cc.png">

見た目の画面サイズが以前と変わりません。これでは、もし、大きなブラウザで遊んだとしても大きな画面でゲームをプレイできません。


##拡大/縮小サイズを取得する

そこで、画面全体を拡大縮小するわけですが、2倍に拡大するのか半分に縮小するのか、拡大の倍率を取得しないといけません。変数『scale』として以下のように取得します。

```javascript

//ブラウザの幅(screenWidth)と高さ(screenHeight)をJavaScriptの機能を使って取得する
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;


//もしも、画面が320:480よりも縦長だった場合
if(screenHeight/screenWidth > 480/320){
   //横幅のサイズを基準に倍率を決める
   var scale = screenWidth / 320;
//もしも、画面が320:480よりも横長だった場合
}else{
   //縦幅のサイズを基準に倍率を決める
   var scale = screenHeight / 480;
}
```


##Canvasのサイズの拡大/縮小

以下の方法でcanvasの大きさを変えることができます。ただし、まだこれで完成ではありません。

```javascript

//canvas要素を取得
var canvas = document.getElementById("myGame");
// キャンバスの描画領域の横幅を320*scaleに変更する
canvas.width = 320 * scale;
// キャンバスの描画領域の縦幅を480*scaleに変更する
canvas.height = 480 * scale;
```





##コンテナを拡大/縮小する

開発環境の機能に拡大縮小の機能があれば、それを利用して拡大/縮小します。

CreateJSには、コンテナという機能があります。
複数の図形や文字、画像などを一つのまとまりとしてレイヤーのように扱うことができる機能です。四角形、円、文字をコンテナの上に配置し、さらにコンテナをステージの上に配置します。そして、コンテナのサイズをscale倍にします。

```javascript

var stage = new createjs.Stage("myGame");//idが"myGame"のcanvas上にステージを作成する

var container = new createjs.Container();//コンテナを作成する
container.scaleX = scale;//コンテナを横にscale倍にする
container.scaleY = scale;//コンテナを縦にscale倍にする

stage.addChild(container);//ステージにコンテナを追加する

//背景を真っ黒にする
var shape = new createjs.Shape();//図形を宣言する
shape.graphics.beginFill("black"); // 図形を塗りつぶす色を黒にする
shape.graphics.drawRect(0, 0, 320, 480); // 図形の形状を横320,縦480の四角形に設定する
container.addChild(shape); // 完成させた図形をコンテナに加える

//ゲーム画面の上の方に円を加える
var shape2 = new createjs.Shape(); //図形を宣言する
shape2.graphics.beginFill("darkred"); //図形を塗りつぶす色を暗めの赤にする
shape2.graphics.drawCircle(150, 130, 100); //左から150,上から130の位置に半径100の円を描く
container.addChild(shape2); //完成させた図形をコンテナに加える

//ゲーム画面の下の方に適当にゲームのオープニングっぽい雰囲気の文章を書く
var text = new createjs.Text("", "24px serif", "white"); //サイズ24のセリフ体,文字色が白のテキストを宣言する
text.y = 100; //上から100の位置に文字を配置する
text.text = "アメリカ大陸にかつて存在し\nていた古代アステカ文明では\n太陽神が信仰されていた。\n人々は太陽エネルギーによる\n魔法を使い、文明は栄華を極\nめていた。だが・・・";
container.addChild(text);//完成させた文章をコンテナに加える

stage.update();//完成したステージをcanvas上に表示する
```
縮小成功
<img width="160" alt="スクリーンショット 2018-01-05 12.01.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/78116/81df956e-e832-dbdf-837d-dfb4f593d9cc.png">

拡大成功
<img width="534" alt="スクリーンショット 2018-01-05 13.07.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/78116/fd16f5e6-474b-eb32-bf94-77bb5f30a123.png">



##リアルタイムでリサイズ

ゲームをプレイしている途中でユーザーがブラウザの大きさを変更したくなることがあります。そういった場合でも変更後、すぐにリアルタイムでcanvasとコンテナを拡大縮小する機能を追加してみても便利かもしれません。

```javascript

//リサイズ処理を行う関数
function update(){
	var screenWidth = window.innerWidth;
	var screenHeight = window.innerHeight;
	if(screenHeight/screenWidth > 480/320){
	 	var scale = screenWidth / 320;
	}else{
     	var scale = screenHeight / 480;
	}
	canvas.width = 320 * scale;
	canvas.height = 480 * scale;
	container.scaleX = scale;
	container.scaleY = scale;
	stage.update();

}

//1秒間に24回の頻度で指定した関数を実行するCreateJSの機能。
//JavaScriptのsetIntervalとほぼ同じ機能。
createjs.Ticker.addEventListener("tick", update);

```






##あとがき
CreateJSのコンテナの使い方についてはネット上にいくつか解説ページはありますし、画像の拡大方法についても、解説しているページはたくさんありますが、コンテナの拡大について解説しているページは見当たらなかったので記事にしてみました。

また、ブラウザのサイズを取得する解説サイトはありますし、canvasのサイズを変更する解説サイトもありますし、iPhoneのブラウザの縦横比について解説しているサイトもありましたが、それを一連の流れを包括的に解説しているページはないので、それについても触れてみました。

Androidについては、あらゆるメーカーの端末の種類を網羅しはじめると、きりがないと思って割愛しましたが、調べた限りでは、iPhoneとサイズはそう大きく変わりはないと思います。