9

I have part of a game where the cursor is supposed to "slow down" when it passes over certain divs. I'm using a function that can detect a collision with the div. This works fine when the cursor meets the first div, but it doesn't work at all on the second div.

Check out this jsFiddle for a better idea of what I'm talking about. Pass the cursor over the first white block (class='thing') on the left and it slows down. Pass the cursor over the other block (also class='thing'), and nothing happens. I need this collision function to work on all divs where class='thing'.

HTML

<div id='cursor'>
            &nbsp;
        </div>
        <div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 350px; right: 800px; z-index: -1;'>
            &nbsp;
        </div>
        <div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 200px; right: 400px; z-index: -1;'>
            &nbsp;
        </div>

JS

(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
    var x1 = $cursor.offset().left;
    var y1 = $cursor.offset().top;
    var h1 = $cursor.outerHeight(true);
    var w1 = $cursor.outerWidth(true);
    var b1 = y1 + h1;
    var r1 = x1 + w1;
    var x2 = $thing.offset().left;
    var y2 = $thing.offset().top;
    var h2 = $thing.outerHeight(true);
    var w2 = $thing.outerWidth(true);
    var b2 = y2 + h2;
    var r2 = x2 + w2;

    // change 12 to alter damping higher is slower
    var varies = 12;    

    if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
    } else {
    varies = 200;
    console.log(varies);
    }
$xp += (($mouseX - $xp)/varies);
    $yp += (($mouseY - $yp)/varies);
    $("#cursor").css({left:$xp +'px', top:$yp +'px'}); 

}

$(collision($('#cursor'), $('.thing')));
//$('.result').text(collision($('#cursor'), $('.thing')));

}, 20);
})();

2 Answers2

12

$thing is a collection of elements, like you want, but the problem here is that you ask specific attributes from $thing like offset().left;, which can not return more than one number, therefor it just takes the first. What you should do instead is use an .each() function to loop over all the elements in $thing.

$thing.each( function( index, element ){
    //your code for each thing here
});
Niki van Stein
  • 10,564
  • 3
  • 29
  • 62
  • Thanks for the help. It sort of works now. I've seem to run into what appears to be a bug. If you take a look at this updated jsfiddle: [link](https://jsfiddle.net/5sy1tg36/8/) You'll see: `if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){ varies = 200; changeMouseSpeed(); } else { varies = 12; changeMouseSpeed(); console.log('hit'); } ` But if I switch around the values in `varies` it won't work at all. – jack_of_all_trades Oct 01 '15 at 19:09
  • Could you make that a separate question? Sounds interesting! – Niki van Stein Oct 01 '15 at 19:12
  • Perhaps you should put `varies` outside the loop. – Niki van Stein Oct 01 '15 at 19:26
  • I've tried that, but it doesn't seem to make a difference. I just made a new question addressing this problem. The new question is here: [link](http://stackoverflow.com/questions/32895727/is-this-a-bug-javascript-conditional) – jack_of_all_trades Oct 01 '15 at 19:53
  • However, your answer does solve the problem I had with looping through the collection, so I'll mark it as the best answer. – jack_of_all_trades Oct 01 '15 at 19:55
8

When you are selecting element by class name(in your case using .thing) in jQuery you will get an array of elements and collision() function will take first element in an array. so to overcome this you need to uniquely select both the elements this can be done using id as a selector,You can change your code like below to work it as expected

<div id='track'>
    <div class = 'container'>
        <div id='cursor' class='cursor'>
            &nbsp;
        </div>
        <div class='thing' id="a1" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 175px; right: 400px; z-index: -1;'>
            &nbsp;
        </div>
        <div class='thing' id="a2"  style='width:70px; height:70px; background: #fff; position: absolute; bottom: 100px; right: 200px; z-index: -1;'>
            &nbsp;
        </div>
    </div>
</div>


(function cursorMapping(){

var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;

$(document).mousemove(function(e){
    $mouseX = e.pageX;
    $mouseY = e.pageY;    
});

function showCoords(event) {
    var x = event.clientX;
    var y = event.clientY;
    var coor = "X: " + x + ", Y: " + y;
}

var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;

var mrefreshinterval = 500; // update display every 500ms
 var lastmousex=-1; 
 var lastmousey=-1;
 var lastmousetime;
 var mousetravel = 0;
 var lastmousetravel = 0;

var speed;
var marker1 = 1;
var marker2 = 1;

var timer = setInterval(function(){
    marker1;
    marker2;
}, 20);

$(function() {

    var $speedometer = $('#speed'),
         _speed = 0; 

    $('#track').cursometer({
        onUpdateSpeed: function thisSpeed(speed) {
            _speed = speed;
            $speedometer.text(Math.ceil(speed * 100)/100);
        },
        updateSpeedRate: 20
    });

});

var thisInterval = setInterval(function FXInterval(){
    speed = $('#speed').text();
        $('#cursor').css({'background-color': '#CE7A7A'});
}, 20);

 $('html').mousemove(function(e) {
     var mousex = e.pageX;
     var mousey = e.pageY;
     if (lastmousex > -1)
         mousetravel += Math.max( Math.abs(mousex-lastmousex), Math.abs(mousey-lastmousey) );
     lastmousex = mousex;
     lastmousey = mousey;
     var speed = lastmousex + lastmousey;

    setTimeout(function(){
        lastmousetravel = mousetravel;
    }, 20);
 });

(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
    var x1 = $cursor.offset().left;
    var y1 = $cursor.offset().top;
    var h1 = $cursor.outerHeight(true);
    var w1 = $cursor.outerWidth(true);
    var b1 = y1 + h1;
    var r1 = x1 + w1;
    var x2 = $thing.offset().left;
    var y2 = $thing.offset().top;
    var h2 = $thing.outerHeight(true);
    var w2 = $thing.outerWidth(true);
    var b2 = y2 + h2;
    var r2 = x2 + w2;

    // change 12 to alter damping higher is slower
    var varies = 12;    

    if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
    } else {
    varies = 200;
    console.log(varies);
    }
$xp += (($mouseX - $xp)/varies);
    $yp += (($mouseY - $yp)/varies);
    $("#cursor").css({left:$xp +'px', top:$yp +'px'}); 
}
$(collision($('#cursor'), $('#a1')));
$(collision($('#cursor'), $('#a2')));

}, 20);
})();

})();
Murli
  • 1,258
  • 9
  • 20
  • Thanks for your help! This is definitely the most direct solution to my problem. However, I'm going to use `.each()` because I'm less familiar with that and it's good for me to try different things. – jack_of_all_trades Oct 01 '15 at 19:16