今週は移動やカメラ操作、落下中のアニメーション作業を行いました。
前後移動時は手や足を振り、体を少し左右に捻るようにしました。左右同時も手足を振り、体をわずかに移動方向へ傾けるようにしました。
カメラでの視点移動が速い場合は、体の向きの追従を少しずらしました。
今週の作業予定には無かったのですが、ジャンプ後の落下中は手足がだんだん開くようにしました!
全体的に、そこそこ良い感じになったと思います。
今週は移動やカメラ操作、落下中のアニメーション作業を行いました。
前後移動時は手や足を振り、体を少し左右に捻るようにしました。左右同時も手足を振り、体をわずかに移動方向へ傾けるようにしました。
カメラでの視点移動が速い場合は、体の向きの追従を少しずらしました。
今週の作業予定には無かったのですが、ジャンプ後の落下中は手足がだんだん開くようにしました!
全体的に、そこそこ良い感じになったと思います。
デアゴ管理とは、デアゴスティーニに習って1日(1回)のアプリ制作作業量を少なくすることによって、恐ろしいほど飽き性のアプリ制作者(私です)の作業を毎日継続させ易くするプロジェクト管理手法です。
デアゴ管理による10週目の作業予定です。
64日目:移動方向キーの操作性向上
65日目:前後移動時のアニメーション その1
66日目:前後移動時のアニメーション その2
67日目:左右移動時のアニメーション その1
68日目:左右移動時のアニメーション その2
69日目:カメラ移動時のアニメーション
70日目:予備日(次の週の予定を立てる)
先週までで以下動画のように自由自在にフィールドを動き回れるようになりましたが、プレーヤーが突っ立ったまま動きがありません。
今週は移動やカメラ操作に合わせてプレーヤーにアニメーションを付けていきます。
この3日間で、垂直方向の衝突判定作業を終えました。
文字やコードでグダグダ説明してもわかりづらいので、動画にしました。
ご覧の動画のように、もうマップ内を自由自在に動き回れます!
マイクラみたい!
もういっそマイクラ作りたい!
いや、作らないけど。
この3日間で、iPadでの動作不正対策とマルチタッチ対応を完璧に対処できました!
iPadでの動作不正の原因は、iPadOSになってからブラウザのユーザーエージェント情報がPCに近いものになっていたためでした。
以下のような判定で問題なくPCとそれ以外を判定することが出来ました。
const ua = navigator.userAgent;
const isIOS = ua.indexOf("iPhone") >= 0 || ua.indexOf("iPad") >= 0 || navigator.userAgent.indexOf("iPod") >= 0;
const isIPadOS = (navigator.platform == "MacIntel" &&
navigator.userAgent.indexOf("Safari") != -1 &&
navigator.userAgent.indexOf("Chrome") == -1 &&
navigator.standalone !== undefined);
const isAndroid = ua.indexOf("Android") >= 0;
const isPC = !(isIOS || isIPadOS || isAndroid);
マルチタッチ対応は上記のisPCフラグを利用して、PCとそれ以外(スマホやタブレット)で処理を分岐し、マウスポイントやタップ情報を共通の配列に流し込んでうまく処理することが出来るようになりました。
function changedTouches(event) {
let touches = [];
if (isPC) {
// PCはマウスポイント1点だけ
touches.push({id:0, x:event.pageX - _canvasOffsetX, y:event.pageY - _canvasOffsetY});
} else {
// スマホやタブレットは複数
for (let i = 0; i < event.changedTouches.length; i++) {
touches.push({id:event.changedTouches[i].identifier, x:event.changedTouches[i].pageX - _canvasOffsetX, y:event.changedTouches[i].pageY - _canvasOffsetY});
}
}
return touches;
}
これで懸念事項が全て解決し、明日からの垂直方向の障害物判定にスッキリした気分で進めます!
(⋈◍>◡<◍)。✧♡
デアゴスティーニ商法作業管理とは、1日のアプリ制作作業量を少なくすることによって、恐ろしいほど飽き性のアプリ制作者(私です)の作業を毎日継続させ易くする手法です。
デアゴスティーニ商法作業管理による9週目の作業予定です。
57日目:マルチタッチ対応
58日目:iPadでアプリが動作しない原因の特定
59日目:iPadでアプリが動作しない原因を解消
60日目:垂直方向の障害物判定 その1 接触判定用変数用意
61日目:垂直方向の障害物判定 その2 下方向の移動制限
62日目:垂直方向の障害物判定 その3 上方向の移動制限
63日目:予備日(次の週の予定を立てる)
今作っているアプリはベースがWebGLなので、PCでもスマホでもタブレットでも動きます。
スマホで動かそうとしたらマルチタッチに対応しておらず、移動とジャンプが同時に出来なかったためその対処をまず行います。また、なぜかiPadで動作しなかったため原因の特定と解決を行います。
それらを終えてから、いよいよ垂直方向の障害物判定を行なっていく予定です。
はやくブロックに乗ったり、ジャンプで飛び越えたりしてみたい!
o(゚ー゚*o)ワクワク
ブロックにめり込まないようになりました。
とりあえず水平方向のみの判定です。今後、垂直方向も判定を入れていきます。
垂直方向を判定出来れば、ジャンプでブロックを超えることが可能になるので楽しみです。
ちなみに衝突判定処理は以下のコードのようになりました。斜め方向にぶつかった際、移動が止まらずにブロックを避ける方向にプレーヤーがうまくずれて動き続けるようにしています。
ブロックの1辺の長さは 1.0 です。_land.isBlockはx/y/z軸方向の位置を整数で指定すると、その位置にブロックがあるか判定してくれる関数です。見ての通り垂直方向のy軸には0しか指定していません。
ちょっと長いな・・・もう少し短くしたいな・・・
// 衝突判定
const DISTANCE_TO_BLOCK = 0.45;
const BOUND_DIFF = 0.0001;
if (moveX < 1.0 && moveZ < 1.0) { // ←ラグでのブロック抜けを防ぐ
// x方向のチェック
if (0 != moveX) {
let nextBX = Math.floor(0.5 + _objs.player.basePos.x + moveX + DISTANCE_TO_BLOCK * (0 < moveX ? 1 : -1));
let nextBZ = Math.floor(0.5 + _objs.player.basePos.z);
let posOfBlock = _objs.player.basePos.z - Math.floor(_objs.player.basePos.z);
if (0.5 <= posOfBlock && posOfBlock <= 0.5 + DISTANCE_TO_BLOCK) {
// 1個奥もチェック
if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX, 0, nextBZ - 1)) {
_objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
moveX = 0;
}
} else if (0.5 - DISTANCE_TO_BLOCK <= posOfBlock && posOfBlock <= 0.5) {
// 1個手前もチェック
if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX, 0, nextBZ + 1)) {
_objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
moveX = 0;
}
} else {
if (_land.isBlock(nextBX, 0, nextBZ)) {
_objs.player.basePos.x = nextBX + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveX ? -1 : 1);
moveX = 0;
}
}
}
// z方向のチェック
if (0 != moveZ) {
let nextBX = Math.floor(0.5 + _objs.player.basePos.x);
let nextBZ = Math.floor(0.5 + _objs.player.basePos.z + moveZ + DISTANCE_TO_BLOCK * (0 < moveZ ? 1 : -1));
let posOfBlock = _objs.player.basePos.x - Math.floor(_objs.player.basePos.x);
if (0.5 <= posOfBlock && posOfBlock <= 0.5 + DISTANCE_TO_BLOCK) {
// 1個左もチェック
if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX - 1, 0, nextBZ)) {
_objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
moveZ = 0;
}
} else if (0.5 - DISTANCE_TO_BLOCK <= posOfBlock && posOfBlock <= 0.5) {
// 1個右もチェック
if (_land.isBlock(nextBX, 0, nextBZ) || _land.isBlock(nextBX + 1, 0, nextBZ)) {
_objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
moveZ = 0;
}
} else {
if (_land.isBlock(nextBX, 0, nextBZ)) {
_objs.player.basePos.z = nextBZ + (0.5 + DISTANCE_TO_BLOCK + BOUND_DIFF) * (0 < moveZ ? -1 : 1);
moveZ = 0;
}
}
}
} else {
moveX = 0;
moveZ = 0;
}
// 加算
_objs.player.basePos.x += moveX;
_objs.player.basePos.z += moveZ;
いやー面白くなってきました。
この3日間で画面の上下左右ドラッグによる視点変更と視点に合わせての移動方向修正を実装完了しました。
これで世界を自由自在に動いたり、見たい方向を見渡せるようになりました。
カメラ位置はプレーヤーを中心として球面座標系で動きます。
openGLは垂直方向がy、奥行きがzなので、プレーヤーとカメラの距離をrとすると、
x = r * sinθ * cosφとなります。θはx軸周りの傾き、φはy軸周りの傾きとなります。
尚、地面にめり込まないよう、カメラのy座標位置はマイナスにならないように制限をかけました。
ゲームプレイするより作る方が面白いですね。
特定の部分を作っている時だけかもしれないけど・・・
デアゴスティーニ商法作業管理とは、1日のアプリ制作作業量を少なくすることによって、恐ろしいほど飽き性のアプリ制作者(私です)の作業を毎日継続させ易くする手法です。
デアゴスティーニ商法作業管理による第8号(8週目)の作業予定です。
50日目:画面ドラッグによる視点変更 その1 上下
51日目:画面ドラッグによる視点変更 その2 左右
52日目:画面ドラッグによる視点変更 その3 視点に合わせて移動方向修正
53日目:移動による障害物判定 その1 接触判定用変数用意
54日目:移動による障害物判定 その2 ブロック接触判定
55日目:移動による障害物判定 その3 移動制限
56日目:予備日(次の週の予定を立てる)
ここら辺の処理が山場な気がします。ここを越えればあとは比較的単純作業だと思われるので頑張ります!
‹‹(´ω` )/››
スマホが主な提供対象の予定ですが、PCでも操作出来るようにキーボード対応しました。
WebGLなので、ブラウザがあれば動きます。
ASDWで移動、スペースでジャンプです。
来週はご覧の画像のようにならないよう、壁の当たり判定や視点変更などを行なっていきます。
1mジャンプ出来るようになりました。
背面飛びしてみました。
ジャンプするためのy座標を求める式は以下の通りです。
y = v0 * t – g * t * t / 2;
ここで、tは時間、gは重力加速度(9.80665m/s2)、v0は初速で、1m飛ぶため4.42869m/sをセットしています。
初速の計算は
√2gh / sinθ (※ルートは2ghの全体にかかります。)
で可能です。hが高さ(m)です。真上なのでsinθは1です。
1m飛びたいならば、2 * 9.80665 * 1 のルートです。
数学大好きです。
(⋈◍>◡<◍)。✧♡