2014-07-26 3 views
2

저는 그립에 도달하고 HTML5 캔버스로 볼을 충돌하고 사용하는 방법을 이해하려고합니다. 예제에서는 많은 자바 스크립트가 있지만 예제를 얻으려면 훨씬 더 작은 덩어리로 나누어야합니다 무슨 일이 벌어지고 있는지 더 잘 이해할 수 있습니다.HTML5 캔버스 이해

Example에서 캔버스에 40 밀리 초마다 원을 다시 그리며 매번 애니메이션 기능을 호출한다는 점만 이해했습니다. 내가

1을 달성하고자하는 내 원 객체 배열에 따라서

circles[0].x+=1; 
circles[0].y+=-1.5; 

로 변경하고로이 때마다 원의 변경의 위치라고하며, 2 가지가있다)하지 않음 공이 캔버스 영역에서 벗어나게하려면

2) 볼이 충돌하면 서로 튀어 나와 반대 방향으로 튀어 나옵니다.

그래도 볼이 캔버스를 탈출시키는되지 않고, 나는 내가 window.width에 액세스 할 수 있으며 이해의 window.height 그래서 그 경우

을 그 밖으로 작업에 대한 갈 것이라고 어떻게 첫번째 해결하기 위해 원하는 것은 배열에서 각 공의 위치를 ​​얻고 그 경계를 넘지 않는지 확인하는 방법

누구든지이 점을 설명하는 데 도움이된다면 크게 도움이 될 것입니다. 무슨 일이 일어나고

고마워요

+0

[이 질문 (http://stackoverflow.com/questions/20885297/collision-detection- in-html5-canvas)는 볼과 컨테이너 사이의 충돌을 감지하는 방법과 볼 사이의 [this one] (http://stackoverflow.com/questions/8331243/circle-collision-javascript)을 보여줍니다. 충돌이 발생하면 공의 방향을 바꾸어 바운스를 다시 만들어야합니다. – undefined

+0

[다음은 전체 자습서입니다.] (http://www.exeneva.com/2012/06/multiple-balls-bouncing-and-colliding-example/). – undefined

답변

2
circles[0].x+=1; 
circles[0].y+=-1.5; 

http://jsfiddle.net/3tfUN/5/을 수행 할 수있는 원 사이에 감지합니다. 대신 X와 Y 속도에 대한 속성을 제안합니다 (예제에서는 moveXmoveY을 사용했습니다).

다음으로 볼의 위치와 반경 보정이 캔버스 가장자리에 닿아 있는지 확인해야합니다. 그렇다면 속도 값을 반대로합니다. 예를 들어 볼의 X 속도는 4이고 이제는 왼쪽 또는 오른쪽 캔버스 egde에 도달합니다. 이제 X 속도는 -4가됩니다.

이것은 간단히 말해서, 그것은이다 http://jsfiddle.net/3tfUN/8/

같은 원칙은 공 사이의 충돌을 적용

  var c = circles[i]; 

      // check rebounds 
      if (c.x - c.radius <= 0 || c.x + c.radius >= canvas.width) 
       c.moveX = -c.moveX; // flip the horizontal speed component 
      if (c.y - c.radius <= 0 || c.y + c.radius >= canvas.height) 
       c.moveY = -c.moveY; // flip the vertical speed component 

      // Yellow Circle 
      c.x += c.moveX; // here we don't have to worry 
      c.y += c.moveY; // about directions anymore 

여기 내 예를 참조하십시오. 각도 변경없이 간단한 충돌을 원한다고 가정합니다.

실제 볼 충돌을 시뮬레이트하고 싶다면 픽셀 완전 충돌이 정확히 발생했을 때를 계산하고 새로운 X 및 Y 속도 구성 요소를 계산하려면 좀 더 심각한 삼각법이 필요합니다.


UPDATE

볼 사이 약간 향상 충돌 검출 및 전송 속도를 갖춘 예 : http://jsfiddle.net/3tfUN/12/

+0

답장을 보내 주셔서 감사합니다. 그렇습니다. 단순한 충돌이 올 것입니다. 그러나 먼저 여기에서 무슨 일이 일어나고 그 위로 움직이는 지 생각해보십시오. – Richlewis

+2

도 반경/2를 할 필요가 없습니다. 단지 반경이어야합니다. – geedubb

+0

환영합니다. 단순한 충돌을 포함하도록 마지막 피들을 확장하려고합니다. 하지만 기본적으로 canvas egde collisions를 탐지하는 것과 같은 일이 될 것입니다. – Shomz

1

캔버스는 원을 그리는 단지 "캔버스"입니다. 원하는 것을 달성하기 위해 필요한 것은 원이 너비와 높이 치수 및 현재 위치가있는 객체이고 경계가 잘 정의 된 "세계"를 모델링하는 것입니다. 각 원의 너비와 높이 및 위치를 확인한 후 설정 한 경계를 기준으로 위치를 계산하고 방향을 변경하거나 계속 진행해야하는지 확인합니다.

충돌은 똑같은 원리에서 유래하지만 "현실적"이 되길 원한다면 모델링하기가 다소 어렵습니다 (경계 문제는 경계 영역이 상자 모양이기 때문에 원의 너비와 높이에만 관심이 있습니다. 두 원이 충돌 할 때 주위의 "경계 상자"대신 각 원의 반경을 고려해야합니다.

지금은 시간이 없습니다. 예를 들어이 개념을 보여주기 위해, 그러나 바른 길로 당신을 보냈습니다 :).

3

이것은 캔버스의 경계에서 충돌을 검사합니다. vx 및 vy (속도)를 저장하기 위해 객체를 업데이트하고 draw() 함수를 사용하여 이러한 속성을 기반으로 이동했습니다. 나는 동그라미가 바운드 바깥으로 갈 때 속도를 뒤집는 checkBounds()을 추가했습니다.

수정 : 너무 수정되어 서클의 반경도 고려합니다.충돌을하는

비슷한 패턴

var canvas = document.getElementById('ball-canvas'); 
    var context = canvas.getContext('2d') 
    var radius = 50; 
    var strokewidth = 2; 
    var strokestyle = '#666'; 
    var frameCount = 0; 
    var w = canvas.width; 
    var h = canvas.height; 

    // Circle Objects 
    var yellowCircle = { 
     x: 50, 
     y: h/2, 
     radius: radius, 
     color: 'yellow', 
     vx: 1, 
     vy: 1.5 
    } 

    var redCircle = { 
     x: 450, 
     y: h/2, 
     radius: radius, 
     color: 'red', 
     vx: 1, 
     vy: -1 
    } 

    var blueCircle = { 
     x: 850, 
     y: h/2, 
     radius: radius, 
     color: 'blue', 
     vx: -1, 
     vy: -1.5 
    } 

    // Create empty array and then push cirlce objects into array 
    var circles = []; 
    circles.push(yellowCircle, blueCircle, redCircle); 

    function checkBounds() { 
     for (var i = 0; i < circles.length; i++) { 
      var c = circles[i]; 
      if (c.x > w - c.radius || c.x < c.radius) { 
       c.vx = -c.vx; 
      } 
      if (c.y > h - c.radius || c.y < c.radius) { 
       c.vy = -c.vy; 
      } 
     } 
    } 

    // Clear last circle and draw again 
    function draw() { 
     context.clearRect(0, 0, canvas.width, canvas.height); // Clear the circle from the from page 
     for (var i = 0; i < circles.length; i++) { 
      var c = circles[i]; 
      context.beginPath(); 
      context.fillStyle = c.color // Set the color of the circle using key:valuecontext.fill(); 
      context.lineWidth = strokewidth; 
      context.strokeStyle = strokestyle; 
      context.stroke(); 
      context.arc(c.x, c.y, c.radius, 0, Math.PI * 2); // X-axis Position, y-axis Position, radius, % of fill, ? 
      context.closePath(); 
      context.fill(); 
     } 
    } 

    function animate() { 
     for (i = 0; i <= 2; i++) { 
      circles[i].x += circles[i].vx; 
      circles[i].y += circles[i].vy; 
     } 
     checkBounds(); 
     draw(); 
    } 

    var canvas = document.getElementById('ball-canvas'); 
    var context = canvas.getContext('2d') 
    var radius = 50; 
    setInterval(animate, 40); 
유지하기 꽤 힘든