ゲームコントローラのサンプル
次は、WebカメラとARマーカーを使って、ゲームのコントローラーを簡易的に作るサンプルを紹介します。
「crocro.jscam」では、配列を引数にして、Webページ上にARマーカーを作成する機能もあります。ここでは、この機能を使い、Webページ上にARマーカーを表示します。このARマーカーをWebカメラで撮影して、動かすことで、Canvas上の仮想コントローラーの向きや長さを変えます。
この方法を応用することで、楽しいWebカメラゲームを作ることができます。
それでは実際にソースコードを見てもらいます。
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>「crocro.jscam」 - サンプル ゲームコントローラ - クロノス・クラウン</title>
<script
type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"
></script>
<script type="text/javascript" src="jscam.js"></script>
<script language="javascript">
// 変数
var cap;
// 起動時処理
$(document).ready(function() {
// JSカメラ初期化
crocro.jscam.initSwfCam();
crocro.jscam.setFilter(["bin", "label", "detectMarker", "drawMarker"]);
// ………【1】フィルタ設定
cap = crocro.jscam.makeCaptureObject("cnvsCap");
// コールバックの設定
cap.setBackDataType(["markerData"]); // ………【2】コールバック設定
// マーカーの設定
viewMarker();
crocro.jscam.ready(function() { // 準備ができたら開始
cntrl(); // コントロール
});
});
// 画像取得
function cntrl() {
cap.capture(function(resObj){ // 各戻り値ごとの処理
var resArr = [];
if ("markerData" in resObj) { // ………【3】マーカーデータ
// 出力
var s = "";
var md = resObj.markerData;
$.each(md, function(k, v) {s += k + ":" + v + ", "});
s += "<br>"
s += "lt(" + md.ltX + ", " + md.ltY + ") / "
+ "rt(" + md.rtX + ", " + md.rtY + ")<br>";
s += "lb(" + md.lbX + ", " + md.lbY + ") / "
+ "rb(" + md.rbX + ", " + md.rbY + ")";
resArr.push("<hr>markerData : " + s);
// 中心からのコーン
var ctx = cap.cntxtObj; // 2Dコンテクストを取得
ctx.clearRect(0, 0, cap.w, cap.h);
drawLine(ctx, "#ff0000", 3, [
[md.ltX, md.ltY]
,[md.rtX, md.rtY]
,[md.rbX, md.rbY]
,[md.lbX, md.lbY]
]);
drawLine(ctx, "#ff0000", 3, [
[md.ltX - 2, md.ltY - 2]
,[md.ltX + 2, md.ltY - 2]
,[md.ltX + 2, md.ltY + 2]
,[md.ltX - 2, md.ltY + 2]
]);
drawLine(ctx, "#8f0000", 1, [
[cap.w / 2, cap.h / 2]
,[md.ltX, md.ltY]
]);
drawLine(ctx, "#8f0000", 1, [
[cap.w / 2, cap.h / 2]
,[md.rtX, md.rtY]
]);
drawLine(ctx, "#8f0000", 1, [
[cap.w / 2, cap.h / 2]
,[md.rbX, md.rbY]
]);
drawLine(ctx, "#8f0000", 1, [
[cap.w / 2, cap.h / 2]
,[md.lbX, md.lbY]
]);
// 傾きと大きさ
var cntrX = (md.ltX + md.rtX + md.rbX + md.lbX) / 4;
var cntrY = (md.ltY + md.rtY + md.rbY + md.lbY) / 4;
var dirX = ((md.ltX + md.rtX) / 2 - cntrX);
var dirY = ((md.ltY + md.rtY) / 2 - cntrY);
drawLine(ctx, "#0000ff", 5, [
[cap.w / 2, cap.h / 2]
,[cap.w / 2 + dirX, cap.h / 2 + dirY]
]);
}
$("#resData").html(resArr.join("<br>"));
});
setTimeout(cntrl, 50);
}
// 線描画
function drawLine(ctx, col, width, arr) {
ctx.strokeStyle = col;
ctx.lineWidth = width;
ctx.beginPath();
ctx.moveTo(arr[0][0], arr[0][1]);
for (var i = 1; i < arr.length; i ++) {
ctx.lineTo(arr[i][0], arr[i][1]);
}
ctx.lineTo(arr[0][0], arr[0][1]);
ctx.closePath();
ctx.stroke();
}
// キャプチャ
function captureImg() {
cap.capture(); // キャプチャ
}
// マーカー設定
var mrkrArr = crocro.jscam.util.swapXY(16, 16, [ // ………【4】マーカー配列
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,1],
[1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,1],
[1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]);
// マーカー表示
function viewMarker() {
// マーカーの作成
crocro.jscam.util.makeMarker("marker", mrkrArr, 13, true,
// ………【5】マーカー作成
function(x, y, prm){
mrkrArr[x][y] = prm;
crocro.jscam.setMarker(mrkrArr);
}
);
}
</script>
</head>
<body bgcolor="#ffffff">
<div id="jscamAS" class="boxOut">
<table border=0><tr><td valign="top">
<script language="javascript">
crocro.jscam.write();
</script>
</td><td valign="top" style="padding-left: 32px;">
●マーカー形式<br>
<br>
<div id="marker"></div>
</td></tr></table>
</div>
<div id="jscamJS" style="">
<table border=0><tr><td valign="top">
<canvas id="cnvsCap" width="320" height="240"></canvas>
</td><td valign="top">
<div id="resData"></div>
</td></tr></table>
</div>
</body>
</html>
それでは簡単な解説を行います。まずは【1】の setFilter です。ここでは、 ["bin", "label", "detectMarker", "drawMarker"] と指定することで、「2値化」「ラベリング」「マーカー検出」「マーカー表示」を設定しています。
次に【2】の setBackDataType です。ここでは ["markerData"] だけを指定しています。画像のデータを取得しないことで、高速に、そして少ないメモリーの消費で、マーカーのデータを取得しています。このように、必要なデータに絞ってコールバックさせることで、処理を最適化することができます。
【3】の部分では、受け取ったデータを元に、仮想コントローラーの値を計算しています。描画は、一般的なHTML5のCanvasを利用した方法です。
【4】【5】では、配列データを元に、ARマーカーをWebページ上に生成しています。
ここでは、 makeMarker メソッドの第4引数(編集が可能かのフラグ)を true にしています。そのため、マーカーをクリックすれば、マーカーの形をドット絵のように編集することができます。

