不循环?HTML5和JavaScript

Not Looping? HTML5 and JavaScript

本文关键字:JavaScript HTML5 循环      更新时间:2023-09-26

我不知道为什么这段代码不循环,因为它应该。我很震惊,希望有人能帮我一把。这是我第一次尝试进入HTML5和JavaScript的世界,也是我的第一个StackOverflow帖子。我的背景是java,所以这应该可以解释我代码中的怪癖。顺便说一下,如果你运行代码,画布和球将显示,只是不移动。

首先,这是HTML5
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ChainReaction5</title>
    <script type="text/javascript" src="chain_reaction.js"></script>
    </head>
    <body>
    <body onLoad="init();">
    <canvas id="myCanvas" width="500" height="400">
    Your browser dosen't support the HTML5 canvas.</canvas><br />
    </body>
    </html>

其次是js

    //gobal vars
    var context;
    var box;
    var balls;
    var defaultBallX=240;
    var defaultBallY=190;
    var defaultBallRad=6;
    var defaultBallV=5;
    var defaultNumBalls=10;
    //box class
    function Box() {
        var boxx=20;
        var boxy=20;
        var boxWidth=460;
        var boxHeight=360;
        this.getX = function() {return boxx;}
        this.getY = function() {return boxy;}
        this.getWidth = function() {return boxWidth;}
        this.getHeight = function() {return boxHeight;}
        this.getBalls = function() {return ball;}
        this.paintMe = function() {
            context.fillStyle = "black";
            context.strokeRect(boxx, boxy, boxWidth, boxHeight);
        }
    }
    /*  Box Class
     *  this class is sloppy but more memory efficent
     */
    function Ball(x, y, radius, vx, vy, color) {
        this.x=x;
        this.y=y;
        this.radius=radius;
        this.vx=vx;
        this.vy=vy;
        this.color=color;   
        this.paintMe = function() {
            context.beginPath();
            context.arc(this.x, this.y, radius, 0, 2*Math.PI, true);
            context.fillStyle = this.color; 
            context.fill();
        }
    }
    Array.prototype.appendBalls = new function(array) {}
    Array.prototype.clearBalls = new function() {}
    Array.prototype.appendBalls = function(array) {
            for (var i = 0; i < array.length; i++) {
                balls.push(array[i]);
            }
        }
    Array.prototype.clearBalls = function() {
            balls = new Array();
        }
    // begin program
    function init() {
        context = document.getElementById("myCanvas").getContext("2d"); 
        box = new Box();
        balls = new Array();
        balls.appendBalls(createBalls(box, defaultNumBalls));
        setInterval(moveBall(balls, box), 100);
    }
    function createBalls(box, numBalls) {
        var locBalls = new Array(numBalls);
        for (var i = 0; i < numBalls; i++) {
            var randx = randp(50, 400)
            var randy = randp(50, 300);
            var randr = Math.random()*defaultBallRad+1;
            var randvx = randv();
            var randvy = randv();
            var randc = randColor();
            locBalls[i] = new Ball(randx, randy, randr, randvx, randvy, randc);
        }
        return locBalls;    
        function randv() {
            var neg = 1;
            if (Math.random()>.5) neg = -neg;
            return Math.random()*defaultBallV*neg;  
        }
        function randp(low, hight) {
            if (low < 0) low = 0;
            var p = -1;
            while (p > hight || p < low) {
                p = Math.random()*hight;
            }
            return p;
        }
        function randColor() {
            var letters = '0123456789ABCDEF'.split('');
            var color = '#';
            for (var i = 0; i < 6; i++ ) {
                color += letters[Math.round(Math.random() * 15)];
            }
            return color;
        }
    }
    function moveBall(balls, box) {
        clear(this.box);
        this.box.paintMe();
        for (var i = 0; i < this.balls.length; i++) {
                moveAndCheck(this.balls[i], this.box);
            }
    }
    function moveAndCheck(b, box) {
        if ((b.x+b.vx+b.radius-1)>(this.box.boxWidth+this.box.boxx) || b.x+b.vx-b.radius<this.box.boxx+1) {
            b.vx = -b.vx;
        }
        if ((b.y+b.vy+b.radius-1)>(this.box.boxHeight+this.box.boxy) || b.y+b.vy-b.radius<this.box.boxy+1) {
            b.vy = -b.vy;
        }
        b.x += b.vx;
        b.y += b.vy;
        b.paintMe();
    }
    function clear(box) {
        context.clearRect(this.box.boxx, this.box.boxy, 
        this.box.boxWidth, this.box.boxHeight);
    }

我第一次尝试运行它时,在Firebug控制台中看到了以下内容:

无用的setInterval调用(缺少引号围绕参数?)setInterval(moveBall(balls, box), 100);

在'moveBalls(balls, box)'周围加引号可以使物体动起来。

顺便说一下,你可以使用原型继承来让你的函数更有效率一点,Box中的方法是给每个实例的。要让它们继承方法,把它们放在构造函数的原型上:
Box.prototype = {
    getX: function() {return this.boxx;},
    getY: function() {return this.boxy;},
    getWidth: function() {return this.boxWidth;},
    getHeight: function() {return this.boxHeight;},
    getBalls: function() {return this.ball;},
    paintMe: function() {
        context.fillStyle = "black";
        context.strokeRect(this.boxx, this.boxy, this.boxWidth, this.boxHeight);
    }
};
请注意,在javascript中,函数的this关键字是由调用设置的,而不是由你如何声明函数设置的(尽管你可以使用ES5 bind,但这还没有得到广泛支持)。

其他提示:

在Box构造函数中,您创建了局部变量,但您确实想将它们分配给新的Box实例,因此使用this而不是var:

function Box() {
    this.boxx=20;
    this.boxy=20;
    this.boxWidth=460;
    this.boxHeight=360;
}

clearBox函数中,当调用中没有设置时,您使用this,因此它引用window。把它去掉,你把box传递给函数所以直接引用它:

function clear(box) {
    context.clearRect(box.boxx, box.boxy, 
    box.boxWidth, box.boxHeight);
}

同样适用于moveBallmoveAndCheck函数,只是摆脱这个(我认为你应该做一些研究如何这个在javascript中处理,有很多文章关于它,它是完全不同于Java)。现在,这些球将在盒子里漂亮地弹来弹去。

我要感谢那些对我的问题做出贡献的人,他们对解决问题很有帮助,我选择的答案在某种程度上是当前的,但它解决了问题的另一个原因。

不正确:

在'moveBalls(balls, box)'周围加引号可以使物体动起来。

真正解决这个问题的是从moveball函数调用中删除参数和圆括号。当我按照海报上的建议重写代码的其他部分时,我发现了这一点。

因此,如果您需要删除参数并使用包装器函数或全局变量,则为将来有类似问题的其他人提供通知。

相关文章: