Detecting javascript conflicts between highlighted circles


First of all, don't be too critical with my English. I am not a native speaker. Hope I can explain myself nonetheless! Moreover, I read that I must show that I made some efforts to solve this problem. To show this, my post has become relatively long.

What I want to do:

I am new (three weeks) in javascript and I am trying to create a pool pool table through html5 canvas and javascript. As a result, the user should be able to present a specific game situation on a virtual pool by moving sixteen balls around. I found many tips here about stackoverflow regarding paths and drag and drop.

What is already working:

By then, the circles were almost like pool balls, and I can move them with the mouse. So far so good.

What is the problem:

Of course, pool balls collide in reality and do not overlap. Regarding collision detection, I found a useful post that told me to do this using Pythagorean therm a * a + b * b = c * c. I understand this concept. I definitely don't understand where I need to implement detection in my code. My script has a function (moveBall00 (e)) that calculates the new x and y coordinates if the balls move around (dragok = true). But how can the distance between the balls be calculated while the new coordinates of the shuffled ball are calculated simultaneously? This can easily be a novice question!

I tried this:

  • new variable "x"

    var x = true;

  • new function for determining the distance between balls

    Function collision () {if ((Math.pow (bp [1] [0] - bp [1] [1], 2)) + (Math.pow (bp [2] [0] - bp [2] [ 1], 2)) <= 576) {x = false; }}

  • call "collision ()" every 10 milliseconds

    (function isIntersecting () {return setInterval (collision, 10);}) ();

  • just drag the ball if "x = true"

    function moveBall00 (e) {if (dragok & x) {bp [1] [0] = e.pageX - canvas.offsetLeft; bp [2] [0] = e.pageY - canvas.offsetTop; }}

As a result, circles (balls) are superimposed until they calm down. They overlapped, the faster the ball dragged me. Will this be the first seam after the problem ?!

For experienced developers, this is most likely a walk in the park, but not for me.

I am a persistent type and will learn to do it in javascript, but at the moment I do not know how to solve this problem.

I would be grateful for any help in this, and I will post the future result here!

Here is what I have done so far:

(To simplify, only a white ball can be made possible.)

<!doctype html> <html> <head> <meta charset="UTF-8" /> <title>Collision detection</title> </head> <body> <canvas id="pooltable" width="1200" height="660">This text is displayed if your browser does not support HTML5 Canvas</canvas> <script> var canvas; var ctx; var width = 1200; var height = 660; var dragok = false; var bp = new Array(); // color of balls "ballColor" bp[0] = new Array("rgba(255,255,255,1)","rgba(231,214,8,1)"); // x-position of balls "xBallPosition" bp[1] = new Array(20,50); // y-position of balls "yBallPosition" bp[2] = new Array(50,50); // color of stripes "stripe" bp[3] = new Array("rgba(255,255,255,0)","rgba(231,214,8,1)"); // color of stripe strokes "stripeStroke" bp[4] = new Array("rgba(255,255,255,0)","rgba(231,214,8,1)"); // ball numbers "ballNumber" bp[5] = new Array(" ","1"); // position of ball numbers "positionBallNumber" bp[6] = new Array(); function init() { canvas = document.getElementById("pooltable"); ctx = canvas.getContext("2d"); return setInterval(draw, 1); } function clear() { ctx.clearRect(0, 0, width, height); } function rect(x,y,w,h) { ctx.beginPath(); ctx.rect(x,y,w,h); ctx.closePath(); ctx.fill(); } function ball(ballColor, xBallPosition, yBallPosition, ballRadius, angle, stripe, stripeStroke, circleRadius, ballNumber, positionBallNumber) { ctx.fillStyle = ballColor; ctx.shadowBlur = 5; ctx.shadowColor = "rgba(0,0,0,1)"; ctx.beginPath(); ctx.arc(xBallPosition, yBallPosition, ballRadius, angle, Math.PI * 2, true); ctx.closePath(); ctx.fill(); ctx.fillStyle = stripe; ctx.strokeStyle = stripeStroke; ctx.shadowColor = "rgba(0,0,0,0)"; ctx.beginPath(); ctx.moveTo(xBallPosition - 7, yBallPosition - 8); ctx.bezierCurveTo(xBallPosition - 8, yBallPosition - 13, xBallPosition + 8, yBallPosition - 13, xBallPosition + 7, yBallPosition - 8); ctx.lineTo(xBallPosition + 7, yBallPosition + 8); ctx.bezierCurveTo(xBallPosition + 8, yBallPosition + 13, xBallPosition - 8, yBallPosition + 13, xBallPosition - 7, yBallPosition + 8); ctx.closePath(); ctx.stroke(); ctx.fill(); ctx.fillStyle = "rgba(255,255,255,1)"; ctx.shadowColor = "rgba(0,0,0,0)"; ctx.beginPath(); ctx.arc(xBallPosition, yBallPosition, circleRadius, angle, Math.PI * 2, true); ctx.closePath(); ctx.fill(); ctx.fillStyle = "rgba(0,0,0,1)"; ctx.font = "normal normal lighter 7px Helvetica"; ctx.textBaseline = "middle"; ctx.fillText(ballNumber, xBallPosition - positionBallNumber, yBallPosition + 1); var gradient = ctx.createRadialGradient(xBallPosition, yBallPosition, 1, xBallPosition + 3, yBallPosition + 3, 12); gradient.addColorStop(0, "rgba(255,255,255,0.6)"); gradient.addColorStop(1, "rgba(0,0,0,0.2)"); ctx.fillStyle = gradient; ctx.strokeStyle = "rgba(0,0,0,0.4)"; ctx.shadowColor = "rgba(0,0,0,0)"; ctx.beginPath(); ctx.arc(xBallPosition, yBallPosition, ballRadius, angle, Math.PI * 2, true); ctx.closePath(); ctx.stroke(); ctx.fill(); } function draw() { clear(); table = new rect(0,0,width,height); ball00 = new ball(bp[0][0], bp[1][0], bp[2][0], 12, 0, bp[3][0], bp[4][0], 6, bp[5][0], 0); ball01 = new ball(bp[0][1], bp[1][1], bp[2][1], 12, 0, bp[3][0], bp[4][1], 6, bp[5][1], 2); } function myDown(e) { if (e.pageX < bp[1][0] + 6 + canvas.offsetLeft && e.pageX > bp[1][0] - 6 + canvas.offsetLeft && e.pageY < bp[2][0] + 6 + canvas.offsetTop && e.pageY > bp[2][0] - 6 + canvas.offsetTop) { bp[1][0] = e.pageX - canvas.offsetLeft; bp[2][0] = e.pageY - canvas.offsetTop; dragok = true; canvas.onmousemove = moveBall00; } else { dragok = false; } } function myUp() { dragok = false; canvas.onmousemove = null; } function moveBall00(e) { if (dragok) { bp[1][0] = e.pageX - canvas.offsetLeft; bp[2][0] = e.pageY - canvas.offsetTop; } } init(); canvas.onmousedown = myDown; canvas.onmouseup = myUp; </script> </body> </html> 
+8
javascript html5 collision canvas drag-and-drop
source share
1 answer

The problem you are facing is not completely related to the basic rendering technique. This is just a math problem.

What you basically want to do for your situation is to calculate the distance between the ball you drag and any ball on the table. If the distance is too short, a collision has occurred.

For two objects it is simple, you need three values: the x and y coordinates of the balls and their radii.

 var ball = { x: 100, y: 100 r: 10 }; 

To calculate the distance, you will do this:

 var squareX = Math.pow(Math.abs(ballA.x - ballB.x), 2); var squareY = Math.pow(Math.abs(ballA.y - ballB.y), 2); var hypothenuse = Math.sqrt(squareX + squareY); var distance = hypothenuse - ballA.r - ballB.r; if (distance >= 0) { // new position is valid } 

Since you have several balls in the pool table, you need to call this code once for each ball on the table that does not move in order to compare all of them.

 function canMove(ballA, ballB) { var squareX = Math.pow(Math.abs(ballA.x - ballB.x), 2); var squareY = Math.pow(Math.abs(ballA.y - ballB.y), 2); var hypothenuse = Math.sqrt(squareX + squareY); var distance = hypothenuse - ballA.r - ballB.r; if (distance >= 0) { return true; } return false; } function canDrag(ball, balls) { var isMovable = true; for (var i = balls.length-1; i >= 0; i--) { isMovable = canMove(ball, balls[i]); if (!isMovable) { return false; } } return true; } 

In the last fragment, I suggested that your ball objects are stored in an array of balls. Hope this helps.

+5
source share

All Articles