Sunday, 7 April 2019

Spot The Bug: The donkey and its tail

Bugs, beware. Spot The Bug is back!

Here's looking at you!


This is one of those cases where your code is right but the logic is very, very wrong. Fortunately, the bug was visible and didn't take too long. I was making a web-based version of the classic Pin The Tail On The Donkey game...



Here's the code in its entirety, at least right up to the point it started to fail.
<!DOCTYPE html>
<html>
    <head>
        <title>Donkey</title>

        <style>
            body
            {
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #donkey
            {
                width: 500px;
                height: 400px;
                margin: 100px auto 0 auto;
                outline: 1px solid #000000;
                background: url(donkey_body.jpg) left top no-repeat;
            }

            #tail
            {
                width: 150px;
                height: 150px;
                visibility: hidden;
                position: absolute;
                outline: 1px solid #000000;
                background: url(donkey_tail.png) left top no-repeat;
            }
        </style>

        <script>
            function setTail()
            {
                document.getElementById("donkey").onmousemove =
                    function(e)
                    {
                        showTail(e);
                    };

                document.getElementById("donkey").onmouseover =
                    function(e)
                    {
                        showTail(e);
                    };

                document.getElementById("donkey").onmouseout =
                    function(e)
                    {
                        hideTail(e);
                    };  
            }

            function showTail(e)
            {
                if (!e)
                {
                    var e = window.event;
                }

                var x = parseInt(e.screenX);
                var y  =parseInt(e.screenY);

                var tail = document.getElementById("tail");
                tail.style.visibility = "visible";
                tail.style.left = x + "px";
                tail.style.top = y + "px";
            }

            function hideTail(e)
            {
                var tail = document.getElementById("tail");
                tail.style.visibility = "hidden";
            }
        </script>
    </head>

    <body onload = "setTail()">
        <div id="donkey">
          
        </div>

        <div id="tail"></div>
    </body>
</html>


So I had a div (id donkey) which housed an image of a tail-less donkey, and I had another div (id tail) which housed the image of its tail. Now, whenever I move the mouse cursor onto the donkey div, the tail div appears and follows the mouse cursor. So far so good, right?



OK, one of the problems was that when I was about to place the tail on the ass's ass (heh heh), the tail disappeared! This was because I had a mouseover event to make the tail appear and follow the cursor, and I had a mouseout event to make the tail disappear. So we'd only see the tail if the cursor was over the div that the donkey was in. If I moved the mouse cursor so that the tail was right where the donkey butt was, the mouse cursor would end up going outside of the div and the tail would disappear. This was a problem because, hey, what's the point of a game if something goes wrong just as you're about to win?


So what I did was, I not only positioned tail to follow the mouse pointer, I even positioned tail so that the mouse cursor was dead center of it!
                tail.style.left = (x - 75) + "px";
                tail.style.top = (y - 50) + "px";


What went wrong

There, that solved the first problem. However, it gave rise to a new, and trickier problem. tail started to blink whenever I moved the mouse cursor into the donkey div. It would flicker endlessly. And that was annoying as hell.

Why it went wrong

The code was working fine. In fact, it was following my instructions way too faithfully. See, when mousing over donkey, tail appears. And when mousing out of donkey, tail disappears.

And since tail becomes dead center of the mouse pointer whenever it's displayed, this counts as triggering the mouseout event. Because technically, I'm now mousing over tail and not donkey!

So tail would appear, disappear, and appear again, like a politician during and after the elections.

How I fixed it

I basically contented myself with positioning tail to be beneath the cursor but horizontally still in the middle. That way, the user can still move the tail to the rear end of the donkey without the tail disappearing.
                tail.style.left = (x - 75) + "px";
                tail.style.top = y + "px";




Conclusion

Be careful what you want the computer to do. Even when the program screws up, chances are, it's doing exactly what you wanted it to do.

Glad we got to the bottom of this!
T___T

No comments:

Post a Comment