ゲーム製作でHTML5-Canvasを勉強するぞ!! 第12回

| コメント(0) | トラックバック(0)

シューティングといえばレーザー!!

12-1.png レーザーの表現は、昔は細い線一本でしたが、今では極太レーザーやホーミングでクネクネするものなど、いろいろあります。
どうせ作るなら一本線だとつまらないので、ホーミングレーザーを作ってみます。

まずはホーミング弾を

12-2.png 作成します。 移動速度と方向を極座標として持たせ、自機との角度によって移動方向を補正します。
これで徐々に自機の方に近づいていくホーミング弾ができます。

var ax = this.x - this.previous.x;
var ay = this.y - this.previous.y;
var bx1 = myShip.x - this.previous.x;
var bx2 = myShip.x + WIDTH - this.previous.x;
var bx3 = myShip.x - WIDTH - this.previous.x;
var bx;
if (Math.abs(bx1) < Math.abs(bx2))
{
	if (Math.abs(bx1) < Math.abs(bx3))
		bx = bx1;
	else
		bx = bx3;
}
else
{
	if (Math.abs(bx2) < Math.abs(bx3))
		bx = bx2;
	else
		bx = bx3;
}
var by = myShip.y - this.previous.y;
var ep = ax * by - bx * ay;
if (0 < ep)
	this.theta += 0.1;
else
	this.theta -= 0.1;

直交座標での右端と左端は繋がっているので、ちょっとソースが長くなっていますが、ようするに進もうとしている方向よりも右側だったら、右に曲がるように、左側だったら左に曲がるようにしているだけです。

レーザーっぽくするには

12-3.png過去の位置を保存しておいてそれをつなぎます。
今回は10点分記録しておくようにしました。
ちゃんとしたゲームでは各点にそって画像をコピーしますが、処理速度的に厳しいので今回は直線で結びました。
これでも雰囲気は出ていると思います。

まとめると

以下のようになりました。

var EnemyHomingLaser = function (x, y)
{
	this.move = function ()
	{
		this.x = (this.x + this.speed * Math.cos(this.theta) + WIDTH) % WIDTH;
		this.y += this.speed * Math.sin(this.theta);

		if (this.y < HEIGHT * 3 / 4)
		{
			var ax = this.x - this.pos[this.pos.length - 1][0];
			var ay = this.y - this.pos[this.pos.length - 1][1];
			var bx1 = myShip.x - this.pos[this.pos.length - 1][0];
			var bx2 = myShip.x + WIDTH - this.pos[this.pos.length - 1][0];
			var bx3 = myShip.x - WIDTH - this.pos[this.pos.length - 1][0];
			var bx;
			if (Math.abs(bx1) < Math.abs(bx2))
			{
				if (Math.abs(bx1) < Math.abs(bx3))
					bx = bx1;
				else
					bx = bx3;
			}
			else
			{
				if (Math.abs(bx2) < Math.abs(bx3))
					bx = bx2;
				else
					bx = bx3;
			}
			var by = myShip.y - this.pos[this.pos.length - 1][1];
			var ep = ax * by - bx * ay;
			if (0 < ep)
				this.theta += 0.1;
			else
				this.theta -= 0.1;
		}

		this.speed += 0.2;
		
		this.pos.push([this.x, this.y]);
		if (10 < this.pos.length) this.pos.shift();

		var out = true;
		for (var n = 0; n < this.pos.length; n++)
		{
			if (this.pos[n][1] < HEIGHT + 5) out = false;
		}
		if (out) return false;
		return true;
	}

	this.drawPolar = function (ctx)
	{
		var offset = 0;
	
		ctx.save();
		ctx.beginPath();
		ctx.moveTo(this.pos[0][0], this.pos[0][1]);
		for (var n = 1; n < this.pos.length; n++)
		{
			if (WIDTH / 2 < Math.abs(this.pos[n][0] - this.pos[n - 1][0]))
				offset = this.pos[n][0] < this.pos[n - 1][0] ? WIDTH : -WIDTH;
			ctx.lineTo(offset + this.pos[n][0], this.pos[n][1]);
		}
		ctx.strokeStyle = "rgb(192, 0, 128)";
		ctx.lineWidth = 4;
		ctx.lineCap = "round";
		ctx.stroke();

		ctx.strokeStyle = "rgb(255, 192, 255)";
		ctx.lineWidth = 2;
		ctx.stroke();
		ctx.restore();
	}
	
	this.initialize(x, y, 2);

	this.speed = 1;
	this.theta = Math.PI / 2 * 3;
	this.pos = [[x, y]];
}
EnemyHomingLaser.prototype = new BaseObject();

自機にある程度近づいても追尾すると絶対によけられないので、直交座標上で画面の3/4になるまで追尾するようにしています。

12-4.png
Play

トラックバック(0)

トラックバックURL: http://murakya.net/mt/mt-tb.cgi/41

コメントする

オリジナルゲーム

オンラインツール