0

I'm new to using Canvas so I'm having a few issues. I have this little game set up where circles are falling at a consistent rate, but I'm having issues determining if a falling circle was selected.

So basically I need help determining how a moving circle can be selected. Can you add event listeners on the ctx elements?? Also I don't want to use jQuery for this if at all possible.

Thanks for any help!!

var myGamePiece;
var range = document.getElementById("myRange");
var rangeValue = document.getElementById("sliderValue");
var score = document.getElementById("score");
var canvas = document.getElementById("canvasElement");

var speedValue = 1;
var counter = 0;
canvas.width = 480;
canvas.height = 350;


canvas.addEventListener("click", function(){
    counter += 1;
    score.innerHTML = counter;
});

range.onchange = function(){
    rangeValue.innerHTML = this.value;
    speedValue = this.value;
};

function startGame() {
    var randomXCord = Math.random() * (450 - 100) + 100;
    var randomSize = Math.random()* (50 - 10) + 10; //random dot size between 100px - 10px

    //check to make sure dots will not go off the side of the screen
    if(randomSize >= 30){
        if(randomXCord >= 400){
            randomXCord -= 50;
        }
    }
    myGamePiece = new component(10, 10, "red", randomXCord, 10, randomSize);
    console.log(randomSize);
    console.log(randomXCord);

    myGameArea.start();
};

var myGameArea = {

    start : function() {
        document.body.insertBefore(canvas, document.body.childNodes[0]);
        this.context = canvas.getContext("2d");
        var interval = setInterval(updateGameArea, 20);
    },
    clear : function() {
        this.context.clearRect(0, 0, canvas.width, canvas.height);
    }
};

function component(width, height, color, x, y, size) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    console.log(this.width);
    this.radius = size;
    this.update = function(){
        ctx = myGameArea.context;
        ctx.beginPath();
        ctx.fillStyle = color;
        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
        ctx.fill();
    };
};

function updateGameArea() {
    myGameArea.clear();
    //makes the dot go vertically down then calls update
    myGamePiece.y += speedValue;
    //check to see if dot if off the page
    if(myGamePiece.y >= canvas.height){
        myGameArea.clear();
        //  startGame();
        //setTimeout(function() { startGame(); }, 1000);

    }
    myGamePiece.update();
};
menix
  • 168
  • 1
  • 1
  • 7

2 Answers2

0

You could use this answer to find out the position of the mouse when clicked and use this:

(mouseXpos - circleXpos)^2 + (mouseYpos - circleYpos)^2 < circleRadius^2

to check if the position of the mouse is inside the circle. This is assuming that the x and y coordinates of your circle is at the center.

This check should be done in your updateGameArea() function.

Community
  • 1
  • 1
George Hanna
  • 382
  • 2
  • 15
0

The canvas is an element you draw on. The stuff you draw on it aren't elements and thus events can't be added them. You can think of your canvas as an image that you draw on using JavaScript. When you run functions on your context (which you named ctx), you are drawing on your canvas, not adding elements. Once you've drawn your circle, it's a part of the image.

You can add an event listener to the canvas itself and get the coordinates of your click event and then calculate to see if the click hit inside the circle (since you know the location and size of the circle, it can be calculated). To do this, you should have your current location of the circle stored.

//save your circle somewhere before drawing

var myGameAreaRect = myGameArea.getBoundingClientRect();

myGameArea.addEventListener("click", event => {

  var click = {
    x: event.pageX - window.scrollX - myGameAreaRect.left,
    y: event.pageY - window.scrollY - myGameAreaRect.top
  }

  var clickHitCircle = 
    Math.sqrt(
      Math.pow((click.x - circle.x), 2) + 
      Math.pow((click.y - circle.y), 2)
    ) < circle.radius
  ;

  //clickHitCircle === true if click was inside the circle
  if( clickHitCircle ) {
    //do stuff
  }

});

If you have multiple circles at once, just put them all in an array and loop over them with Array.prototype.forEach() for instance.

Okku
  • 7,468
  • 4
  • 30
  • 43
  • The mouse coordinates need to also include the scroll offset `window.scrollX` and `window.scrollY` eg `x: event.pageX - myGameAreaRect.left - scrollX` and same for y – Blindman67 May 19 '17 at 17:14