【JavaScript】オブジェクトを伸縮させる【ゲーム制作】

JavaScriptで画像を大きくしたり、小さくしたりする処理を作る。ゲームでボタンを押した時、押し広がるアニメーションなどに使える。

まず、ボタン画像を表示するクラスを用意。button.jsは画像を読み込んで表示する簡単なクラス。さらに必要最低限のゲッターとセッターを実装。

/**
 * ボタン画像を表示
 */
export class Button {
	constructor(parent = undefined, x = 0, y = 0) {
		if (parent !== undefined) {
			this._parent = parent;
		}
		this._x = x;
		this._y = y;
		this._scaleX = 1;
		this._scaleY = 1;
		this._img;

		this._init();
	}

	//////////////////////////////////
	// Private and protected
	//////////////////////////////////

	_init() {
		if (this._parent !== undefined) {
			this._ctx = this._parent;
		}
		this._img = new Image();
		this._img.src = "./button.png";
		this.draw();
	}

	//////////////////////////////////
	// Public
	//////////////////////////////////

	draw() {
		// 現在の描画状態を保存
		this._ctx.save();
		// コンテキストの座標を変更し、キャンバス中央に移動
		this._ctx.translate(this._x, this._y);
		// コンテキストのスケールを指定
		this._ctx.scale(this._scaleX, this._scaleY);
		this._ctx.drawImage(this._img, -(this._img.width / 2), -(this._img.height / 2));
		// save()で保存した描画状態を復元
		// 変形情報(translate、scale)を描画前に戻している
		this._ctx.restore();
	}

	//////////////////////////////////
	// Getters/Setters
	//////////////////////////////////

	get x() {
		return this._x;
	}
	set x(x) {
		this._x = x;
	}

	get y() {
		return this._y;
	}
	set y(y) {
		this._y = y;
	}

	get scaleX() {
		return this._scaleX;
	}
	set scaleX(scalex) {
		this._scaleX = scalex;
	}
	get scaleY() {
		return this._scaleY;
	}
	set scaleY(scaley) {
		this._scaleY = scaley;
	}
}

stretch.jsはbuttonクラスを使いボタン画像を表示、タイマーでスケール値を加減して画像を伸縮させる。requestAnimationFrameを使ったゲームループの実装は、「【JavaScript】requestAnimationFrameでゲームループを作る」を参照。

import { Button } from "./button.js";

/**
 * stretch.js
 */
export class Stretch {
	constructor() {
		this._cvs = document.getElementById('canvas');
		this._ctx = this._cvs.getContext('2d');
		this._button;
		this._angle = 0;	// 角度
		this._centerScale = 1;	// 基準となる元のスケール
		this._range = 0.5;	// 伸縮する範囲
		this._speed = 0.05;	// 伸縮する速度
		// タイマー関連
		this._animID;
		this._isAnim = 0;
		this._FPS = 60;
		this._frame = 0;
		this._startTime;
		this._nowTime;
		
		this._init();
	}

	//////////////////////////////////
	// Private and protected
	//////////////////////////////////

	_init() {
		this._cvs.style.backgroundColor = "#ccc";
		this._button = new Button(this._ctx, this._cvs.width / 2, this._cvs.height / 2);

		this._startTime = performance.now();
		this._mainLoop();
	}

	_mainLoop() {
		this._nowTime = performance.now();
		let elapsedTime = this._nowTime - this._startTime;
		let idealTime = this._frame * (1000 / this._FPS);
		if (idealTime < elapsedTime) {
                        this._ctx.clearRect(0, 0, this._cvs.width, this._cvs.height);
                        // ①図形が伸縮する処理部分
                        this._button.scaleX = this._button.scaleY = this._centerScale + Math.sin(this._angle) * this._range;
                        this._angle += this._speed;
                        this._button.draw();

                        this._frame++;

                        if (elapsedTime >= 1000) {
                            this._startTime = this._nowTime;
	        	    this._frame = 0;
		        }
	        }
	
		this._animID = requestAnimationFrame(this._mainLoop.bind(this));
	}
}

画像を伸縮させているのはコード①の箇所。Math.sin()を使い、三角関数のサイン波の動きを伸縮する動きに応用している。

三角関数に関しては「【JavaScript】オブジェクトを回転させる」参照。

以下はhtml。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JavaScriptでcanvasの画像を伸縮させる</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="module">
import { Stretch } from "./stretch.js";
window.onload = function () {
let s = new Stretch();
}
</script>
</html>

コメント

タイトルとURLをコピーしました