Webエンジニア susumuis の技術ブログ

このブログの内容は個人の見解であり、所属する組織の公式見解ではありません

HTML5 Canvasを試してみた。

ちょっと前ですが、ブラウザ上で動くゲームを作るプラットフォームにならないか実験してみましたので、ソースを貼ります。

以下の通りに書いて実行すると、画面上をたくさんの"■"が飛びはね、端っこに言ったらバウンドします。

html_canvas.html

<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Canvas DEMO</title>

</head>
<body>
<canvas id="mainCanvas" width="640" height="480">
</canvas>
<script src="canvas.js" type="text/javascript"></script>
</body>
</html>

canvas.js

(function() { 
	
	var WIDTH = 300;
	var HEIGHT = 200;

	window.onload = function() {initCanvas();};
	var canvas;
	var context;
	var x, y, dx, dy;
	var balls;
	
	var Ball = function(x, y, dx, dy, color) {
		this.color = color;
		this.x = x;
		this.y = y;
		this.dx = dx;
		this.dy = dy;
		
		this.move = function() {
			this.x += this.dx;
			this.y += this.dy;
			
			if (this.x < 0 || this.x > WIDTH) {
				this.dx = -this.dx;
			}
			
			if (this.y < 0 || this.y > HEIGHT) {
				this.dy = -this.dy;
			}
		};
		
		this.draw = function() {
			context.fillStyle = color;
			context.fillRect(this.x, this.y, 10, 10);
		};
	};

	function initCanvas() {
		
		canvas = document.getElementById('mainCanvas');
		if(!canvas.getContext) {
			alert('unsupported browser');
			return;
		}
		
		context = canvas.getContext('2d');
		balls = [new Ball(100, 100, rndVelocity(), rndVelocity)];
		for (var i = 0; i < 30; i++) {
			balls[i] = new Ball(100, 100, rndVelocity(), rndVelocity(), rndColor());
		}
		setInterval(next, 50);
	}
	
	function rndVelocity() {
		return (Math.random() - 0.5) * 30;
	}
	
	function rndColor() {
		return '#' + ((Math.floor((Math.random()) * 0xFFFFFF)));
	}
	
	function move() {
		for (var i = 0; i < balls.length; i++) {
			balls[i].move();
		}
	}

	function draw() {
		context.clearRect(0,0,640,480);
  		context.beginPath();
  		for (var i = 0; i < balls.length; i++) {
			balls[i].draw();
		}
	}
	
	function next() {
		move();
		draw();
	}

})();

普段はJavaScriptでオブジェクトを作ろうとは思わないのですが、
こういうゲームっぽいものを作ろうと思うと自然とオブジェクト指向
になるみたいです。

モデル化しやすいからかな。

目下の課題はこんなところですね。

  • タイマーが、setInterval(またはsetTimeout)くらいしかない
    • 本当はsleep+無限ループで動かしたい。
    • 模擬的にsleepを作っても、今度はrefreshがない(?)から再描画されない。(ループを抜けるまで何も描かれない)
  • そのため、FPS60で固定するのが難しい。
    • コマ落ちしたときの扱いとか不安
  • IEだとexcanvasを使えばできるけどゲームとしては使い物にならないくらい遅い。
  • ランダムに色を与えてるはずなのに、同じような色になる。JavaScriptのMath.random()の仕様?

contextを2Dではなく、今後実装されるであろう3Dを使えばならもっと描画速度が速いかもしれませんね。