Question

I am working a building a simple Javascript Whack-a-mole game. I believe the issue is when by the time the "co-ordinates" for the mouse are read, the picture's X and Y values change.

When playing the game, you click on the picture, and the text that should come up when you successful click does not appear. This will not allow me to change to the picture to the "hit" picture, to let the players know they hit the object.

This is the code:

$(document).ready(function() {
document.body.onmousedown = function() {
    return false;
} //so page is unselectable
//Canvas stuff
var canvas = $("#canvas")[0];
var ctx = canvas.getContext("2d");
var w = $("#canvas").width();
var h = $("#canvas").height();
var mx, my;


var player;
var mC;
var mR;

var smackSound = new Audio("audio/boing.wav");
var smackSound2 = new Audio("audio/boing2.wav");
var smackSound3 = new Audio("audio/boing3.wav");

var mel = new Image();
var melHit = new Image();

var melX;
var melY;
var melXref;
var melYref;
/////////////////////////////////
////////////////////////////////
////////    GAME INIT
/////// Runs this code right away, as soon as the page loads.
//////  Use this code to get everything in order before the game starts 
//////////////////////////////
/////////////////////////////

function init() {
    //////////
    ///STATE VARIABLES
    mel.src = "images/mel.jpg";
    melHit.src = "images/melCrazy.jpg";
    //////////////////////
    ///GAME ENGINE START
    //  This starts the game/program
    //  "paint is the piece of code that runs over and over again.
    //  "60" sets how fast things should go
    if (typeof game_loop != "undefined") clearInterval(game_loop);
    game_loop = setInterval(paint, 1000);
}
init();

function generate() {
    var random;
    random = Math.floor(Math.random() * 4);
    while (random == 3) {
        random = Math.floor(Math.random() * 4);
    }
    return random;
}


function posDisplay() {
    ctx.fillStyle = "black"
    ctx.fillText("Mouse Column: " + mC, 10, 10);
    ctx.fillText("Mouse Row: " + mR, 10, 20);
}
///////////////////////////////////////////////////////
//////////////////////////////////////////////////////
////////    Main Game Engine
////////////////////////////////////////////////////
///////////////////////////////////////////////////

function paint() {
    ctx.clearRect(0, 0, w, h);

    melX = generate() * w / 3;
    melY = generate() * h / 3;

    //melXref = generate() / w / 3;
    //melYref = generate() / h / 3;
    //ctx.fillStyle = 'white';

    posDisplay()


    ctx.drawImage(mel, melX, melY, 200, 200);

    if (melXref == mR && melYref == mC && clicker = true) {

        ctx.fillStyle = "black";
        ctx.fillText("It works!!!!!", 200, 200);
    }

    if (melX < w / 3 && clicker = true) { // First Column (Mel)

        if (melY < h / 3) {
            melXref = 1
            melYref = 1
            //  clicker = true;

        } else if (melY > h / 3 && melY < h / 1.5) {
            melXref = 1
            melYref = 2
            // clicker = true;

        } else if (melY > h / 1.5) {
            melXref = 1
            melYref = 3
            //  clicker = true;
        }

  } else if (melX > w / 3 && melX < w / 1.5 && clicker = true) { // Second Column (Mel)

        if (melY < h / 3) {

            melXref = 2
            melYref = 1
            // clicker = true;

        } else if (melY > h / 3 && melY < h / 1.5) {

            melXref = 2
            melYref = 2
            //  clicker = true;

        } else if (melY > h / 1.5) {

            melXref = 2
            melYref = 3
            // clicker = true;
        }

    } else if (melX > w / 1.5 && clicker = true) { // Third Column (Mel)

        if (melY < h / 3) {
            melXref = 3
            melYref = 1
            //  clicker = true;

        } else if (melY > h / 3 && melY < h / 1.5) {
            melXref = 3
            melYref = 2
            //  clicker = true;

        } else if (melY > h / 1.5) {
            melXref = 3
            melYref = 3
            // clicker = true;
        }
        if (melXref == mR && melYref == mC) {
            ctx.fillStyle = "black";
            ctx.fillText("IT WORKS", 200, 200);
        }
        ctx.drawImage(mel, melX, melY, 200, 200);
        if (melX == mx && melY == my) {
            ctx.fillStyle = "black";
            ctx.fillText("YESSSSSSSSS", 250, 250);
            //ctx.drawImage(melHit,(generate()*200),(generate()*200),200,200);
        }
    } ////////////////////////////////////////////////////////////////////////////////END PAINT/ GAME ENGINE
}
////////////////////////////////////////////////////////
///////////////////////////////////////////////////////
/////   MOUSE LISTENER 
//////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////
// Mouse Click
///////////////
canvas.addEventListener('click', function(evt) {
    if (mx < w && my < h) {
        clicker = true;
    } else {
        clicker = false;
    }
    if (clicker = true && mx < w && my < h) { // Randomizes the sound && only allows audio to be played if it is within the canvas
        if (generate() == 1) {
            smackSound.play();
        } else if (generate() == 2) {
            smackSound2.play();
        } else if (generate() == 3) {
            smackSound3.play();
        }
    }
}, false);
canvas.addEventListener('mouseout', function() {
    pause = true;
}, false);
canvas.addEventListener('mouseover', function() {
    pause = false;
}, false);
canvas.addEventListener('mousemove', function(evt) {
    var mousePos = getMousePos(canvas, evt);
    mx = mousePos.x;
    my = mousePos.y;
    if (mx < w / 3) { // First Column
        if (my < h / 3) {
            mC = 1
            mR = 1
            // clicker = true;
        } else if (my > h / 3 && my < h / 1.5) {
            mC = 1
            mR = 2
            //clicker = true;
        } else if (my > h / 1.5) {
            mC = 1
            mR = 3
            // clicker = true;
        }
    } else if (mx > w / 3 && mx < w / 1.5) { // Second Column
        if (my < h / 3) {
            mC = 2
            mR = 1
            // clicker = true;
        } else if (my > h / 3 && my < h / 1.5) {
            mC = 2
            mR = 2
            // clicker = true;
        } else if (my > h / 1.5) {
            mC = 2
            mR = 3
            //  clicker = true;
        }
    } else if (mx > w / 1.5) { // Third Column
        if (my < h / 3) {
            mC = 3
            mR = 1
            //  clicker = true;
        } else if (my > h / 3 && my < h / 1.5) {
            mC = 3
            mR = 2
            // clicker = true;
        } else if (my > h / 1.5) {
            mC = 3
            mR = 3
            //  clicker = true;
        }
    }
}, false);

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}
///////////////////////////////////
//////////////////////////////////
////////    KEY BOARD INPUT
////////////////////////////////
window.addEventListener('keydown', function(evt) {
    var key = evt.keyCode;
    //p 80
    //r 82
    //1 49
    //2 50
    //3 51
}, false);

})

No correct solution

OTHER TIPS

This is a bit of a shot in the dark (and its too much to put in a comment), but from what I can tell, while you are recording the mouse position in the mousemove event, you are not doing so in the click event. I believe its not so much that the picture's X and Y have changed, it is probably that the last recorded mouse's X and Y have changed due to the mousemove event firing after the click.

A general solution (because it can be solved many different ways) might be to record the mouse's row and column in the click event, and then suppress any mouse position updates in the mousemove event if your clicker variable is true. So maybe something like the following:

canvas.addEventListener('mousemove', function(evt) {
    if(!clicker){
        // happily record the mouse position, because user hasn't clicked anything

In the paint method, you can check if clicker is true and do the text thing using the last known mouse position previously recorded in the click event, and then reset it back to false when you're done processing. Your paint method is fairly large, and clicker seems to be used throughout so I won't post a full blown code block in the interests of brevity, but I think you get the idea.

ALSO: I notice in your if statements, you're checking the clicker variable using && clicker = true. Notice the single equal sign? That's extremely bad! Instead of checking its value, you're assigned its value. Remember single equals is for assignment, double equals is for equivalence.

You can solve that error a couple of ways; the simplest is to simply make sure you change it to == instead, and anywhere else you might have made that error. Or, since its a boolean, you can simple do && clicker or && !clicker, depending on the condition.

Alternatively, from the looks of your logic, since every if and if else is dependent on whether clicker is true, you can get rid of the redundant checking in each condition and simply wrap the entire thing in oneif`, like so:

if(clicker){
    if (melXref == mR && melYref == mC) {
        ctx.fillStyle = "black";
        ctx.fillText("It works!!!!!", 200, 200);
    }

    if (melX < w / 3) { // First Column (Mel)

    ... other conditions
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top