enchant.jsでキャラ表示してタップした位置まで移動させる。
見下ろし型の2Dゲーム作る時の雛形用に備忘録的な書き殴り。
ちなみに今回定義しているキャラクタの画像はenchant.jsに標準で入ってるサンプル(だったはず)。
HTML5
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>title</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<script src="enchant.js"></script>
<script src="game.js"></script>
<style>
body {
padding: 0;
margin: 0;
background-color: #000;
}
</style>
</head>
<body>
<!-- ゲーム画面 -->
</body>
</html>
ざっくりと。
ポイントはmeta。width=device-widthで端末幅に最適化し、user-scalable=noでユーザによる拡大縮小を出来なくしている。
game.js
enchant();
window.onload = function() {
var game = new Game(320, 320); // ゲーム画面の領域指定
game.fps = 120; // FPS(1秒あたりの描画回数)設定
game.preload('./img/chara5.png'); // 素材の事前読み込み
game.onload = function() {
// 今回動かすキャラクターを定義
var knight = new Sprite(32, 32); // キャラクター用にスプライト指定
knight.image = game.assets['./img/chara5.png']; // 事前に読み込んだ画像をセット
knight.x = 100; // 横座標指定
knight.y = 120; // 縦座標指定
game.rootScene.addChild(knight); // キャラクターの表示
game.rootScene.backgroundColor = '#fff'; // 背景色を指定(16進数)。
var xspeed = 0;// 横移動のスピードを定義
var yspeed = 0;// 縦移動のスピードを定義
var xposition;// クリック座標(横)保存用の変数
var yposition;// クリック座標(縦)保存用の変数
// シーンに「毎フレーム実行イベント」を追加します。
game.rootScene.addEventListener(Event.ENTER_FRAME, function() {
if (knight.x == xposition){
xspeed = 0;
}
if (knight.y == yposition){
yspeed = 0;
}
knight.x += xspeed; // キャラクターの横座標を右にxspeedずつずらす
knight.y += yspeed;
});
// タッチすると発動
game.rootScene.addEventListener(Event.TOUCH_END, function(e) {
// タッチイベントは、タッチした座標をe.x , e.y として取ることができます。
xposition = Math.round(e.x);
yposition = Math.round(e.y);
if (e.x > knight.x) { // タッチした横位置が当たり判定よりも右側
xspeed = 1; // キャラクターのスピードを1にする
} else {
xspeed = -1; // キャラクターのスピードを-1(左方向に1)にする
}
if (e.y > knight.y) { // タッチした縦位置が当たり判定よりも下側
yspeed = 1; // キャラクターのスピードを1にする
} else {
yspeed = -1; // キャラクターのスピードを-1(上方向に1)にする
}
});
}
game.start(); // ゲーム開始
};
以下、部分別
var game = new Game(320, 320); // ゲーム画面の領域指定
game.fps = 120; // FPS(1秒あたりの描画回数)設定
game.preload('./img/chara5.png'); // 素材の事前読み込み
game.onload = function() {
}
game.start(); // ゲーム開始
gameという変数に画面範囲(今回は320x320の正方形)を指定。
game.fpsではFPS(Frames Per Second)の設定、単純に考えると1秒間に何回処理するか(今回は秒間120回)。
game.preloadではゲームに使う素材(画像とか)を読み込んでおく。
game.onloadでゲームの中の処理を書く(この後説明)。
最後のgame.start()は上で書いた条件でゲームを開始しますよ、と。
game.onload = function() {
// 今回動かすキャラクターを定義
var knight = new Sprite(32, 32); // キャラクター用にスプライト指定
knight.image = game.assets['./img/chara5.png']; // 事前に読み込んだ画像をセット
knight.x = 100; // 横座標指定
knight.y = 120; // 縦座標指定
game.rootScene.addChild(knight); // キャラクターの表示
game.rootScene.backgroundColor = '#fff'; // 背景色を指定(16進数)。
var xspeed = 0;// 横移動のスピードを定義
var yspeed = 0;// 縦移動のスピードを定義
var xposition;// クリック座標(横)保存用の変数
var yposition;// クリック座標(縦)保存用の変数
}
今回はサンプルで使った画像が2等身の騎士みたいなキャラだったためknightという変数名で動かすキャラを扱っています。
サンプル画像を開くと一目瞭然、色んな方向を向いたキャラがびっしり描かれた画像が1ファイルになってます。
Sprite(32, 32)はキャラの大きさ(32x32)を定義して、用意した画像から32x32の単位で切り取って表示するよという意味。
画像をあてはめ、座標を決めたらrootScene.addChild(knight)でキャラを表示。
rootScene.backgroundColorで背景を白地に。
ここから先に使う変数だが、キャラの移動用に縦横それぞれxspeed, yspeedを、
タップ位置保存用にxposition, ypositionをそれぞれ用意
// シーンに「毎フレーム実行イベント」を追加します。
game.rootScene.addEventListener(Event.ENTER_FRAME, function() {
if (knight.x == xposition){
xspeed = 0;
}
if (knight.y == yposition){
yspeed = 0;
}
knight.x += xspeed; // キャラクターの横座標を右にxspeedずつずらす
knight.y += yspeed;
});
毎フレームの処理。書いていることといえば、
①縦横それぞれタップされた位置に着いたらその方向への移動を停止する。
②毎フレームxspeed, yspeed分キャラを移動させる。
これだけ。じゃあspeedとかpositionってどこで決まるのかというと次。
// タッチすると発動
game.rootScene.addEventListener(Event.TOUCH_END, function(e) {
// タッチイベントは、タッチした座標をe.x , e.y として取ることができます。
xposition = Math.round(e.x);
yposition = Math.round(e.y);
if (e.x > knight.x) { // タッチした横位置が当たり判定よりも右側
xspeed = 1; // キャラクターのスピードを1にする
} else {
xspeed = -1; // キャラクターのスピードを-1(左方向に1)にする
}
if (e.y > knight.y) { // タッチした縦位置が当たり判定よりも下側
yspeed = 1; // キャラクターのスピードを1にする
} else {
yspeed = -1; // キャラクターのスピードを-1(上方向に1)にする
}
});
ここでタッチされた座標を定義している。Event.TOUCH_ENDにしておくとタップされてから指を離した時がスタートになる(TOUCH_STARTだとタップ直後の座標、指を離す前から動き出す)。
コメントにある通り、タップ座標はe.x, e.yとして取得できるので、これを縦横のposition変数に入れる。が、小数点以下を許容すると判定が面倒なのでMath.roundを使っている。
あとはシンプルに、キャラとタップ座標を比較して、縦横のspeedを加減している。ここで決定したpositionとspeedに従って毎フレーム描画されてキャラが動き出す。
移動中のキャラが歩くようなアニメーションを用意したりもできるけどとりあえず基本的な動きだけ。