2017-10-27 3 views
0

私はジャバスクリプトが初めてで、パドルの衝突検出を学びたいと思っています。パドルの衝突検出(ポン/ブレイクブロックゲーム)

これは簡単かもしれませんが、作成したパドルの衝突検出器の作成方法はわかりません。これはどのように機能し、衝突検出を作成するためには何が必要ですか?

(私は。私は単純なアニメーション/ゲームjavascriptのページを作成する必要があり、レンガについて知る必要はありません)

ああ、あなたは私がジャバスクリプトの種類を使用しています知っていますか?時々それはまったく異なるコーディングであるので、私が従うコーディングのタイプを見つけることは本当に難しいです。

ありがとうございました!

var canvas = document.getElementById("myCanvas"); 
var ctx = canvas.getContext("2d"); 
var ballRadius = 10; 
var x = canvas.width/2; 
var y = canvas.height-50; 
var dx = 2; 
var dy = -2; 
var ball = drawBall 
var paddleHeight = 10; 
var paddleWidth = 50; 
var paddleX = (canvas.width-paddleWidth)/2; 
var rightPressed = false; 
var leftPressed = false; 

document.addEventListener("keydown", keyDownHandler, false); 
document.addEventListener("keyup", keyUpHandler, false); 

function keyDownHandler(e) { 
    if (e.keyCode == 39) { 
    rightPressed = true; 
    } else if (e.keyCode == 37) { 
    leftPressed = true; 
    } 
} 

function keyUpHandler(e) { 
    if (e.keyCode == 39) { 
    rightPressed = false; 
    } else if (e.keyCode == 37) { 
    leftPressed = false; 
    } 
} 

function drawBall() { 
    ctx.beginPath(); 
    ctx.arc(x,y, ballRadius, 0, Math.PI*2); 
    ctx.fillStyle = "coral"; 
    ctx.fill(); 
    ctx.closePath(); 
} 

function drawPaddle() { 
    ctx.beginPath(); 
    ctx.rect(paddleX, 400, 50, 10); 
    ctx.fillStyle = "lightcoral"; 
    ctx.fill(); 
    ctx.closePath(); 
} 

function collisionDetector(){ 

} 

function draw() { 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    drawBall(); 
    drawPaddle(); 

    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { 
     dx = -dx; 
    } 
    if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { 
     dy = -dy; 
    } 

    if(rightPressed && paddleX < canvas.width-paddleWidth) { 
     paddleX += 7; 
    } 
    else if(leftPressed && paddleX > 0) { 
     paddleX -= 7; 
    } 
    x += dx; 
    y += dy; 
} 
setInterval(draw, 10); 
+4

!!! ** java!= javascript ** !!! – ParkerHalo

答えて

0

まず、四角形と円の間の距離を評価する必要があります。中心間の距離は、長方形やボールの半径の半分の幅の合計よりも大きい場合 - 衝突はありません。
ピクセルの完全な評価を気にしない場合は、円を四角形として扱う方が簡単です。その場合、上記の距離が合計よりも小さい場合 - あなたは衝突しています。
スペースインベーダーのクローンを書いているだけです(私はアマチュアです、私はこれを楽しんでいます):Codepen link、ここでは完全なピクセルの衝突、例/抜粋の蛇を書きました(衝突は2人の俳優コードの他の場所で定義された - 詳細についてCodepenリンク)確認:私は上記のように長方形が(重なっているかどうかを確認した後)、この例の場合

collision: function(actor1, actor2) { 
    var X = Math.abs(actor1.x - actor2.x); 
    var Y = Math.abs(actor1.y - actor2.y); 
    if (Y >= INI.COLLISION_SAFE) return false; 
    if (X >= INI.COLLISION_SAFE) return false; 
    var w1 = parseInt(actor1.width/2, 10); 
    var w2 = parseInt(actor2.width/2, 10); 
    var h1 = parseInt(actor1.height/2, 10); 
    var h2 = parseInt(actor2.height/2, 10); 
    var T = Math.sqrt((h1 + h2) ** 2 + (w1 + w2) ** 2); 
    if (
     MIN(X, Y) === 0 && 
     MAX(X, Y) >= MAX(actor1.width, actor1.height, actor2.width, actor2.height) 
    ) 
     return false; 
    var D = Math.sqrt(X ** 2 + Y ** 2); 
    if (D > T) return false; // not close enough 
    var minWH = MIN(w1, w2, h1, h2); 
    if (D <= minWH) return true; //ultra close 
    ///////// pixel perfect evaluation //////////// 
    var act1 = new Vector(actor1.x, actor1.y); 
    var act2 = new Vector(actor2.x, actor2.y); 
    var direction = act1.direction(act2); 
    var point1 = new Vector(
     actor1.x + direction.x * w1, 
     actor1.y + direction.y * h1 
    ); 
    var point2 = new Vector(
     actor2.x - direction.x * w2, 
     actor2.y - direction.y * h2 
    ); 
    var x = MIN(point1.x, point2.x); 
    var y = MIN(point1.y, point2.y); 
    var w = MAX(point1.x, point2.x) - MIN(point1.x, point2.x); 
    var h = MAX(point1.y, point2.y) - MIN(point1.y, point2.y); 
    if (w === 0 && h === 0) return false; 
    if (w === 0) { 
     w = MIN(w1, w2); 
     x = x - w; 
     w = w * 2; 
    } 
    if (h === 0) { 
     h = MIN(h1, h2); 
     y = y - h; 
     h = h * 2; 
    } 
    var area = new Square(x, y, w, h); 
    var area1 = new Square(
     (area.x - actor1.x) * direction.x + w1 * direction.x, 
     (area.y - actor1.y) * direction.y + h1 * direction.y, 
     area.w, 
     area.h 
    ); 
    var area2 = new Square(
     (area.x - actor2.x) * direction.x * -1 + w2 * direction.x * -1, 
     (area.y - actor2.y) * direction.y * -1 + h2 * direction.y * -1, 
     area.w, 
     area.h 
    ); 
    var CTX1 = LAYER.temp; 
    var CTX2 = LAYER.temp2; 
    ENGINE.draw("temp", 0, 0, SPRITE[actor1.name]); 
    ENGINE.draw("temp2", 0, 0, SPRITE[actor2.name]); 
    var data1 = CTX1.getImageData(area1.x, area1.y, area1.w, area1.h); 
    var data2 = CTX2.getImageData(area2.x, area2.y, area2.w, area2.h); 
    var DL = data1.data.length; 
    var index; 
    for (index = 3; index < DL; index += 4) { 
     if (data1.data[index] > 0 && data2.data[index] > 0) return true; 
    } 
    return false; 
}, 

を、私はスプライトの部分は実際には、各かどうかをチェック重なる計算スプライトの非透明ピクセルが同じ場所(オーバーラップする矩形内)にある
setInterval()の代わりにrequestAnimationFrame()を使用することをお勧めします。
私はこれがあなたの出発点になることを願っています。