I'm trying to figure out why my Google Chrome console is giving me the error "undefined is not a function." I have a hunch, but maybe I'm on the wrong track. My function boxCollision(...) is defined at the bottom of my class. Nearer to the top I have a statement
    if (this.boxCollision(this.food.getBBox(), this.body[0].getBBox()))
            this.food.translate(this.linkSize, 0);
the first line of which is causing the error I mentioned. I think that's maybe because I haven't yet defined boxCollision, so it's essentially nonexistent. Is that right? The getBBox() functions are recognized because they're from an external JavaScript file.
    function snakegame(C, C_w, C_h, spd)
    {
            /* NOTE TO SELF: C is a Raphel object. Can't find a method to return the height
               and width of a Raphael object in the documentation: 
               http://raphaeljs.com/reference.html#Raphael.
               Using C_h and C_w for now, but should probably change it later.
            */
            this.linkSize = 50; /* size of a snake unit, in pixels; must divide C_h and C_w */
            this.link = C.rect(C_h/2, C_w/2, this.linkSize, this.linkSize);
            this.link.attr("fill", "#E9E581");
            this.body = [this.link];
            this.food = C.rect(randInt(0,C_w/this.linkSize-1) * this.linkSize, randInt(0,C_h/this.linkSize-1) * this.linkSize, this.linkSize, this.linkSize);
            if (this.boxCollision(this.food.getBBox(), this.body[0].getBBox()))
                this.food.translate(this.linkSize, 0);
            this.food.attr("fill","#B43535");
            this.maxSnakeSize = C_h * C_w / (this.linkSize * this.linkSize);
            /* On instantiation, the snake direction is down and has 1 link */
            this.dy = 0;
            this.dx = 0;
            this.score = 0;
            /* Event listener for changing the direction of the
               snake with arroy keys on the keyboard
            */
            this.redirect = function(dirnum)
            {
                switch (dirnum)
                {
                    /*
                        dirnum corresponds to
                        1 ---> right
                        2 ---> down
                        3 ---> left
                        4 ---> up
                    */
                    case 1: 
                        this.dx = this.linkSize;
                        this.dy = 0;
                        break;
                    case 2:
                        this.dx = 0;
                        this.dy = this.linkSize;
                        break;
                    case 3:
                        this.dx = -this.linkSize;
                        this.dy = 0;
                        break;
                    case 4:
                        this.dx = 0;
                        this.dy = -this.linkSize;
                        break;
                    default: /* never happens */
                        break;
                }
            }
            this.move = function()
            {
                if (this.body.length == this.maxSnakeSize)
                {
                    this.destruct();
                    return;
                }
                var addLink = false;
                var BBhead = this.body[0].getBBox();
                if (this.hitWall(BBhead) || this.hitSnake(BBhead))
                {
                    document.getElementById("snakescorediv").innerHTML = "<p>GAME OVER!</p><p>Score: "+ this.score +"</p>";
                    this.destruct();
                    return;
                }
                var BBfood = this.food.getBBox();
                if (this.boxCollision(BBhead, BBfood))
                {
                    this.moveFood();
                    this.score += 10;
                    document.getElementById("snakescorediv").innerHTML = this.score.toString();
                    addLink = true;
                }
                if (addLink)
                    this.body.push(this.body[this.body.length - 1].clone());
                for (var i = this.body.length - 1; i > 0; --i)
                {
                    var prevBB = this.body[i-1].getBBox();
                    var thisBB = this.body[i].getBBox();
                    this.body[i].translate(prevBB.x-thisBB.x, prevBB.y-thisBB.y)
                }
                this.body[0].translate(this.dx, this.dy);
            }
            this.mover = setInterval(this.move.bind(this), spd);   
            this.hitWall = function(bb)
            {
                return bb.x < 0 || bb.x2 > C_w || bb.y < 0 || bb.y2 > C_h;
            }
            this.hitSnake = function(bb)
            {
                var retval = false;
                for (var i = 1, j = this.body.length; i < j; ++i)
                {
                    var thisbb = this.body[i].getBBox();
                    if (this.boxCollision(bb, thisbb))
                    {
                        retval = true;
                        break;
                    }
                }
                return retval;
            }
            this.moveFood = function()
            {   
                var bbf = this.food.getBBox(); // bounding box for food
                do {
                /* tx, ty: random translation units */
                tx = randInt(0, C_w / this.linkSize - 1) * this.linkSize - bbf.x;
                ty = randInt(0, C_h / this.linkSize - 1) * this.linkSize - bbf.y;
                 // translate copy of food
                this.food.translate(tx, ty);
                bbf = this.food.getBBox(); // update bbf
                } while (this.hitSnake(bbf));
            }
            this.boxCollision = function(A, B)
            {
                return A.x == B.x && A.y == B.y;
            }
            this.destruct = function()
            {
                clearInterval(this.mover); 
                for (var i = 0, j = this.body.length; i < j; ++i)
                {
                    this.body[i].removeData();
                    this.body[i].remove();
                }
                this.food.removeData();
                this.food.remove();
                this.score = 0;
            }
    }
 
     
     
    