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, 픽셀 완전 충돌, 예제/발췌문 작성 (충돌은 두 배우 코드의 다른 정의 - 자세한 Codepen 링크) 확인 : I가 상기 한 바와 같이 직사각형 (중복 여부를 확인 후) 예 경우

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()을 사용하는 것이 좋습니다.
도움이되기를 바랍니다.