Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

JavaScipt not tracking mouse

Hey guys!

I'm working on a school Javascript project.. Everything is working ok, except that it won't track mouse movements.

Here's the code:

$(document).ready(function(){
    console.log("Document Ready!");

    var canvas = $("#gameCanvas");
    var context = canvas.get(0).getContext("2d");

    var canvasWidth = canvas.width();
    var canvasHeight = canvas.height(); 

    var playGame;

    var ui = $("#gameUI");
    var uiIntro = $("#gameIntro");
    var uiStats = $("#gameStats");
    var uiComplete = $("#gameComplete");
    var uiPlay = $("#gamePlay");
    var uiReset = $(".gameReset");
    var uiRemaining = $("#gameRemaining");
    var uiScore = $(".gameScore");

    var platformX;
    var platformY;
    var platformOuterRadius;
    var platformInnerRadius;
    var asteroids;
    var player;
    var playerOriginalX;
    var playerOriginalY;
    var playerSelected;
    var playerMaxAbsVelocity;
    var playerVelocityDampener;
    var powerX;
    var powerY;
    var score;


    function init() {
        uiStats.hide();
        uiComplete.hide();

        uiPlay.click(function(e){
            e.preventDefault();
            uiIntro.hide();
            startGame();
        });

        uiReset.click(function(e) {
            e.preventDefault();
            uiComplete.hide();
            startGame();
        });
    };

    var Asteroid = function(x, y, radius, mass, friction) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.mass = mass;
        this.friction = friction;
        this.vX = 0;
        this.vY = 0;
        this.player = false;
    };

    function resetPlayer() {
        player.x = playerOriginalX;
        player.y = playerOriginalY;
        player.vX = 0;
        player.vY = 0;
    };

    function startGame(){

        playGame = false;
        platformX = canvasWidth  /2;
        platformY = 150;
        platformOuterRadius = 100;
        platformInnerRadius = 75;

        asteroids = new Array();

        playerSelected = false;
        playerMaxVelocity = 30;
        playerVelocityDampner = 0.3;
        powerX = -1;
        powerY = -1;
        score = 0;

        var pRadius = 15;
        var pMass = 10;
        var pFriction = 0.97;
        playerOriginalX = canvasWidth/2;
        playerOriginalY = canvasHeight - 150;
        player = new Asteroid(playerOriginalX, playerOriginalY, pRadius, pMass, pFriction);
        player.player = true;

        asteroids.push(player);

        var outerRing = 8;
        var ringCount = 3;
        var ringSpacing = (platformInnerRadius/(ringCount - 1));

        for(var r = 0; r < ringCount; r++) {
            var currentRing = 0;
            var angle = 0;
            var ringRadius = 0;

            if(r == ringCount -1) {
                currentRing = 1;
            } else {
                currentRing = outerRing - (r*3)
                angle = 360/currentRing;
                ringRadius = platformInnerRadius - (ringSpacing * r);
            };

            for (var a = 0; a < currentRing; a++) {
                var x = 0;
                var y = 0;

                if(r == ringCount-1) {
                    x = platformX;
                    y = platformY;

                } else {
                    x = platformX + (ringRadius * Math.cos((angle * a) * (Math.PI/180)));
                    y = platformY + (ringRadius * Math.sin((angle * a) * (Math.PI/180)));
                }

                var radius = 10;
                var mass = 5;
                var friction = 0.95;

                asteroids.push(new Asteroid(x, y, radius, mass, friction));
            };
        };

        uiRemaining.html(asteroids.Length - 1);
        uiScore.html("0");
        uiStats.show();

        $(window).mousedown(function(e){
            if (!playerSelected && player.x == playerOriginalX && player.y == playerOriginalY){
                var canvasOffset = canvas.offset();
                var canvasX = Math.floor(e.pageX - canvasOffset.left);
                var canvasY = Math.floor(e.PageY - canvasOffset.top);

                if(!playGame) {
                    playGame = true;
                    animate();
                };

                var dX = player.x - canvasX;
                var dY = player.y - canvasY;
                var distance = Math.sqrt((dX * dX) + (dY * dY));
                var padding = 5;

                if(distance < player.radius + padding) {
                    powerX = player.x;
                    powerY = player.y;
                    playerSelected = true;
                };
            };
        });

        $(window).mousemove(function(e){
            if(playerSelected){
                var canvasOffset = canvas.offset()
                var canvasX = Math.floor(e.pageX - canvasOffset.left);
                var canvasY = Math.floor(e.pageY - canvasOffset.top);

                var dX = player.x - canvasX;
                var dY = player.y - canvasY;  
                var distance = Math.sqrt((dX * dX) + (dY * dY));

                if (distance*playerVelocityDampner < playerMaxVelocity) {
                    powerX = canvasX;
                    powerY = canvasY;
                } else {
                    var ratio = playerMaxAbsVelocity/(distance*playerVelocityDampner);
                    powerX = player.x + (dX * ratio);
                    powerY = player.y + (dY * ratio);
                };
            };
        });


        $(window).mouseup(function(e) {
            if (playerSelected){
                var dX = powerX - player.x;
                var dY = powerY - player.y;

                player.vX = -(dX * playerVelocityDampner);
                player.vY = -(dY * playerVelocityDampner);
                uiScore.html(++score);
            };

            playerSelected = false;
            powerX = -1;
            powerY = -1;

        });

        animate();

    };




    function animate() {
        context.clearRect(0, 0, canvasWidth, canvasHeight);


        context.fillStyle = "rgb(100, 100, 100)";
        context.beginPath();
        context.arc(platformX, platformY, platformOuterRadius, 0, Math.PI * 2, true);
        context.closePath();
        context.fill();

        if(playerSelected) {
            context.strokesStyle = "rgb(255, 255, 255)";
            context.lineWidth = 3;
            context.beginPath();
            context.moveTo(player.x, player.y);
            context.lineTo(powerX, powerY);
            context.closePath();
            context.closePath();
            context.stroke();
        };

        context.fillStyle = "rgb(255, 255, 255)";
        var deadAsteroids = new Array();
        var asteroidsLength = asteroids.length;

        for(var i = 0; i < asteroidsLength; i++) {
            var tmpAsteroid = asteroids[i];

            for(var j = i + 1; j < asteroidsLength; j++) {
                var tmpAsteroidB = asteroids[j];
                var dX = tmpAsteroidB.x - tmpAsteroid.x;
                var dY = tmpAsteroidB.y - tmpAsteroid.y;
                var distance = Math.sqrt((dX * dX) + (dY * dY));

                if(distance < tmpAsteroid.radius + tmpAsteroidB.radius) {
                    var angle = Math.atan2(dY, dX);
                    var sine = Math.sin(angle);
                    var cosine = Math.cos(angle);

                    var x = 0;
                    var y = 0;
                    var xB = dX * cosine + dY * sine;
                    var yB = dY * cosine - dX * sine;

                    var vX = tmpAsteroid.vX * cosine + tmpAsteroid.vY * sine;
                    var vY = tmpAsteroid.vY * cosine - tmpAsteroid.vX * sine;
                    var vXb = tmpAsteroidB.vX * cosine + tmpAsteroid.vY * sine;
                    var vYb = tmpAsteroid.vY * cosine - tmpAsteroid.vX * sine;

                    var vTotal = vX - vXb;
                    vX = ((tmpAsteroid.mass - tmpAsteroidB.mass) * vX + 2 * tmpAsteroidB.mass * vXb) / (tmpAsteroid.mass + tmpAsteroidB.mass);
                    vXb = vTotal + vX;

                    xB = x + (tmpAsteroid.radius + tmpAsteroidB.radius);

                    tmpAsteroid.x = tmpAsteroid.x + (x * cosine - y * sine);
                    tmpAsteroid.y = tmpAsteroid.y + (x * cosine + x * sine);
                    tmpAsteroid.x = tmpAsteroid.x + (xB * cosine - yB * sine);
                    tmpAsteroid.y = tmpAsteroid.y + (yB * cosine + xB * sine);

                    tmpAsteroid.vX = vX * cosine - vY * sine;
                    tmpAsteroid.vY = vY * cosine + vX * sine;
                    tmpAsteroid.vX = vXb * cosine - vYb * sine;
                    tmpAsteroid.vY = vYb * cosine + vXb * sine;
                };
            };

            tmpAsteroid.x += tmpAsteroid.vX;
            tmpAsteroid.y += tmpAsteroid.vY;

            if(Math.abs(tmpAsteroid.vX) > 0.1) {
                tmpAsteroid.vX *= tmpAsteroid.friction;
            } else {
                tmpAsteroid.vX = 0;
            };

            if(Math.abs(tmpAsteroid.vY) > 0.1) {
                tmpAsteroid.vY *= tmpAsteroid.friction;
            } else {
                tmpAsteroid.vY = 0;
            };

            if (player.x != playerOriginalX && player.y != playerOriginalY) {
                if (player.vX == 0 && player.vY == 0) {
                    resetPlayer();
                } else if (player.x + player.radius < 0) {

                } else if (player.x - player.radius > canvasWidth) {
                    resetPlayer();
                } else if (player.y + player.radius < 0) {
                    resetPlayer();
                } else if (player.y - player.radius > canvasHeight) {
                    resetPlayer();
                };
            };
            context.beginPath();
            context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI * 2, true)
            context.closePath();
            context.fill();
        };

            if (!tmpAsteroid.player) {
                var dXp = tmpAsteroid.x - platformX;
                var dYp = tmpAsteroid.y - platformY;
                var distanceP = Math.sqrt((dXp * dXp) + (dYp * dYp));
                if (distanceP > platformOuterRadius) {
                if (tmpAsteroid.radius > 0) {
                    tmpAsteroid.radius -= 2;
                } else {
                    deadAsteroids.push(tmpAsteroid);
                    };
                };
            };

            var deadAsteroidsLength = deadAsteroids.length;
            if (deadAsteroidsLength > 0) {
                for (var di = 0; di < deadAsteroidsLength; di++) {
                    var tmpDeadAsteroid = deadAsteroids[di];
                    asteroids.splice(asteroids.indexOf(tmpDeadAsteroid), 1);
                };
            };

            var remaining = asteroids.length - 1;
            uiRemaining.html(remaining);

            if (remaining == 0) {
                playGame = false;
                uiStats.hide();
                uiComplete.show();

                $(window).unbind("mousedown");
                $(window).unbind("mouseup");
                $(window).unbind("mousemove");
            };
    };

        if(playGame) {
            setTimeout(animate, 33);
        };

    init();
});
Steven Parker
Steven Parker
243,318 Points

Is there some HTML and/or CSS that goes with this? it doesn't do anything by itself.

1 Answer

Steven Parker
Steven Parker
243,318 Points

Are the handlers attached to the wrong element?

Without being able to try it, but just looking over the code one question occurred to me:

Should those mouse event handlers be attached to canvas instead of $(window) ?

Yes, there is a CSS and HTML part of it. Would you like to see it?

Steven Parker
Steven Parker
243,318 Points

Having all the code parts would make it possible to see the problem in action and perhaps find a solution.