Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

JavaScript JavaScript: how to keep track of the circle in canvas on specific path?

Hi, everyone I have following code I want the filled circle to remain within the drawn path or dont slip out of the curved (although it can) if it happens the game ends, (I don't want to bound it to the path) I have been working on this can't help myself finding a solution.

Code:
<html>
<head>
    <style>
        #canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <div>
        <canvas id="canvas" width="500" height="500"></canvas>
    </div>
    <script>
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        var x = 0;
        var y = 250;
        var radius = 10;
        var pathWidth = 200;
        var pathHeight = 100;
        var pathStartX = 100;
        var pathStartY = 200;
        var pathEndX = 400;
        var pathEndY = 200;
        var pathControlX = 250;
        var pathControlY = 100;
        var pathControlX2 = 250;
        var pathControlY2 = 300;
        var pathColor = "black";
        var circleColor = "red";
        var score = 0;
        var startTime = new Date().getTime();
        var endTime = startTime + 60000;
        var path = new Path2D();
        path.moveTo(pathStartX, pathStartY);
        path.bezierCurveTo(pathControlX, pathControlY, pathControlX2, pathControlY2, pathEndX, pathEndY);
        context.stroke(path);
        context.beginPath();
        context.arc(x, y, radius, 0, 2 * Math.PI, false);
        context.fillStyle = circleColor;
        context.fill();
        canvas.addEventListener("mousemove", function (event) {
            var rect = canvas.getBoundingClientRect();
            x = event.clientX - rect.left;
            y = event.clientY - rect.top;
        });
        function draw() {
            context.clearRect(0, 0, canvas.width, canvas.height);
            context.stroke(path);
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI, false);
            context.fillStyle = circleColor;
            context.fill();
            if (x > pathEndX - radius && x < pathEndX + radius && y > pathEndY - radius && y < pathEndY + radius) {
                score++;
                pathStartX = pathEndX;
                pathStartY = pathEndY;
                pathEndX = Math.floor(Math.random() * (canvas.width - pathWidth)) + pathWidth;
                pathEndY = Math.floor(Math.random() * (canvas.height - pathHeight)) + pathHeight;
                pathControlX = Math.floor(Math.random() * canvas.width);
                pathControlY = Math.floor(Math.random() * canvas.height);
                pathControlX2 = Math.floor(Math.random() * canvas.width);
                pathControlY2 = Math.floor(Math.random() * canvas.height);
                path = new Path2D();
                path.moveTo(pathStartX, pathStartY);
                path.bezierCurveTo(pathControlX, pathControlY, pathControlX2, pathControlY2, pathEndX, pathEndY);
                context.stroke(path);
                x = pathStartX;
                y = pathStartY;
            }
            if (new Date().getTime() > endTime) {
                alert("Game Over! Your score is " + score);
                clearInterval(interval);
            }
        }
        var interval = setInterval(draw, 10);
    </script>
</body>
</html>

one more thing I want the filled circle initial position right on either end of the curved path thanks any input or help is appreciated thanks
 
Hi.

If you dont want to use third party libraries, then i guess your best shot is to store coordinates of the shape somehow in array etc. By that, you can do collision detection.

You can also read pixels from canvas from the area where the "ball" is and if there is not black pixel inside the ball, then the ball is out of bounds.
 
I had a peek at the code but I don't quite understand what exactly the rules of the game are.
I get that you need the timer to detect the game timeout, but redrawing the whole thing every 10ms even if there's no mouse activity seems a bit wasteful. Maybe an idea to only do that when a mouse move was detected. Or let the mouse move handler do the redraw ?
 
A little update I managed to do what was required initially,

Code:
<style>
  #canvas {
    border: 1px solid black;
  }
</style>
<div id="msg"> Waiting</div>
<div>
  <canvas id="canvas" width="500" height="300"></canvas>
</div>
<script>
  var gameStarted = false,
    negscore = 0;
  var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");
  var x = 0;
  var y = 0;
  var radius = 20;
  var pathWidth = 200;
  var pathHeight = 100;
  var pathStartX = 100;
  var pathStartY = 200;
  var pathEndX = 400;
  var pathEndY = 200;
  var pathControlX = 250;
  var pathControlY = 100;
  var pathControlX2 = 250;
  var pathControlY2 = 300;
  var pathColor = "black";
  var circleColor = "red";
  var score = 0;
  var startTime = new Date().getTime();
  var endTime = startTime + 20000;
  var path = new Path2D();
  path.moveTo(pathStartX, pathStartY);
  path.bezierCurveTo(
    pathControlX,
    pathControlY,
    pathControlX2,
    pathControlY2,
    pathEndX,
    pathEndY
  );
  context.stroke(path);
  context.lineWidth = 10;
  x = pathStartX;
  y = pathStartY;
  context.beginPath();
  context.arc(x, y, radius, 0, 2 * Math.PI, false);
  context.fillStyle = circleColor;
  context.fill();
  var mouseTravelDistance = 0;
  var prevMouseX = x;
  var prevMouseY = y;

  function draw() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.stroke(path);
    context.beginPath();
    context.arc(x, y, radius, 0, 2 * Math.PI, false);
    context.fillStyle = circleColor;
    context.fill();
    if (gameStarted) {
      if (
        x > pathEndX - radius &&
        x < pathEndX + radius &&
        y > pathEndY - radius &&
        y < pathEndY + radius
      ) {
        score++;
        pathStartX = pathEndX;
        pathStartY = pathEndY;
        pathEndX =
          Math.floor(Math.random() * (canvas.width - pathWidth)) + pathWidth;
        pathEndY =
          Math.floor(Math.random() * (canvas.height - pathHeight)) +
          pathHeight;
        pathControlX = Math.floor(Math.random() * canvas.width);
        pathControlY = Math.floor(Math.random() * canvas.height);
        pathControlX2 = Math.floor(Math.random() * canvas.width);
        pathControlY2 = Math.floor(Math.random() * canvas.height);
        path = new Path2D();
        path.moveTo(pathStartX, pathStartY);
        path.bezierCurveTo(
          pathControlX,
          pathControlY,
          pathControlX2,
          pathControlY2,
          pathEndX,
          pathEndY
        );
        context.stroke(path);
        x = pathStartX;
        y = pathStartY;
      }
      if (context.isPointInPath(path, x, y) === true || context.isPointInPath(path, x + radius, y) === true || context.isPointInPath(path, x - radius, y) === true || context.isPointInPath(path, x, y + radius) === true || context.isPointInPath(path, x, y - radius) === true) {
        if (new Date().getTime() > endTime) {
          alert(
            "Time Up! Your score is " +
            score +
            ". Mouse travel distance: " +
            mouseTravelDistance.toFixed(2) +
            "px" + " | Negative : " + negscore
          );
          gameStarted = false;
          clearInterval(interval);
          context.clearRect(0, 0, canvas.width, canvas.height);
        }
      } else {
        alert(
          "Game Over! Your score is " +
          score +
          ". Mouse travel distance: " +
          mouseTravelDistance.toFixed(2) +
          "px" + " | Negative : " + negscore
        );
        gameStarted = false;
        clearInterval(interval);
        context.clearRect(0, 0, canvas.width, canvas.height);
      }
    }
  }
  var interval = setInterval(draw, 10);
  canvas.addEventListener("click", function(event) {
    
    var distance = Math.sqrt((event.offsetX - x) ** 2 + (event.offsetY - y) ** 2);
    
    if ( distance <= radius) {
      gameStarted = true;
      canvas.style.cursor = "default";
      canvas.removeEventListener("click", arguments.callee);
      document.getElementById("msg").innerHTML = "Game Started";
    }
  });
  canvas.addEventListener("mousemove", function(event) {
    if (gameStarted) {
      var rect = canvas.getBoundingClientRect();
      x = event.clientX - rect.left;
      y = event.clientY - rect.top;
      mouseTravelDistance += Math.sqrt(
        Math.pow(x - prevMouseX, 2) + Math.pow(y - prevMouseY, 2)
      );
      prevMouseX = x;
      prevMouseY = y;
    } else if (!gameStarted) {
      var distance = Math.sqrt((event.offsetX - x) ** 2 + (event.offsetY - y) ** 2);
    
    if ( distance <= radius) {
        canvas.style.cursor = "pointer";
      } else {
        canvas.style.cursor = "default";
      }
    }
  });
</script>
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom