はじめに
こちらのQiitaは勝手連載「ジャンプ&ランゲームを作ろう」になります。
初回の記事はこちらです。
【連載】ジャンプ&ランゲームを作ろう(1) プロジェクト作成
※お断り※ 毎日お昼休みに15分程度で執筆していおり細切れになりましてすみません
今日の内容
前回のボールの処理は床の位置(Y座標)が0である前提の手抜きコードでした。
次回以降、床ブロックを上下に移動させたり、床ブロックのない穴を実装したいので、床とボールの判定をちゃんと実装します。
床とボールの判定をする理由は次の2つです
- 床に設置していない時は重力加速度を適用する
- ジャンプするのは床に設置しているときだけにする。
今回のソースコード
コミット内容(前回との差分):
https://github.com/liberapp-inc/h5g-qiita-jump-and-run/commit/0ba7b9045f070afec054803047fbce7303660317
解説
毎フレームのBallの更新処理を行うupdateBall
関数が今回の変更点です
private updateBall() {
this.ball.x += this.ballVx;
this.ball.y += this.ballVy;
let isBallOnBlock: boolean;
const ballRect = this.ball.getTransformedBounds(this.world);
const bottom = this.ball.y;
const blockRect= new egret.Rectangle();
this.platforms.forEach(e => {
e.getTransformedBounds(this.world,blockRect);
if (blockRect.intersects(ballRect)) {
const blockCenterY = (blockRect.top + blockRect.bottom) / 2;
if (bottom <= blockCenterY) {
isBallOnBlock = true;
this.ball.y = blockRect.top;
this.ballVy = 0;
}
}
});
if (isBallOnBlock) {
this.jumpCount = 0;
} else {
this.ballVy += 0.1;
}
if ((isBallOnBlock || this.jumpCount < 2) && this.tapped) {
this.ballVy -= 5;
this.jumpCount ++;
}
this.tapped = false;
}
isBallOnBlock
変数で、BallがBlockの上に乗っているか、空中に浮いているかを管理します。
let isBallOnBlock: boolean;
getTransformedBounds
メソッド(API)で、Ballの表示領域の矩形を取得します。
引数で渡したthis.world
に対しての相対の位置になります。
const ballRect = this.ball.getTransformedBounds(this.world);
こちらのイディオムですべての床ブロックについて処理をくりかえします。
this.platforms.forEach(e => {
:
});
intersects
でBallの領域矩形ballRect
とblockRect
の領域矩形に接するところがあるかを判定します。
もし矩形が接する場合に、ブロックの重心Y座標(blockCenterY)よりボールの底辺が上にある場合は、ボールは床ブロックの上に接地していると判断します。
if (blockRect.intersects(ballRect)) {
const blockCenterY = (blockRect.top + blockRect.bottom) / 2;
if (bottom <= blockCenterY) {
:
}
}
もし設置していた場合は、フラグisBallOnBlock
をオンにします。次にめりこみを解消するために、ボールのY座標を調整します。また接地したことからボールのY方向の速度は0にします。
isBallOnBlock = true;
this.ball.y = blockRect.top;
this.ballVy = 0;
今回は二段ジャンプ流派ということで、空中ジャンプは一回目までOKとします。
そのために床に接地している場合は、ジャンプカウントをリセットし、空中でももう一回ジャンプできるようにします。
床に接地していない場合は、ボールに重力加速度を適用します。
床に接地している、もしくはジャンプカウントが1回以下の場合に、タップした場合は、上方向の加速度を適用して、ジャンプします。
if (isBallOnBlock) {
this.jumpCount = 0;
} else {
this.ballVy += 0.1;
}
if ((isBallOnBlock || this.jumpCount < 2) && this.tapped) {
this.ballVy -= 5;
this.jumpCount ++;
}
this.tapped = false;