2011-10-06 43 views
1

我不知道为什么这段代码没有循环,因为它应该。我的头脑被吹了,希望有人能帮我一把。这是我第一次尝试HTML5和JavaScript世界以及我的第一个StackOverflow帖子。我的背景是用java编写的,所以应该解释我的代码中的怪癖。顺便说一句,如果你运行代码,画布和球会显示出来,只是不动。不循环? HTML5和JavaScript

首先,这里是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 = 'ABCDEF'.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); 
    } 
+0

您是否已经检查过您是否收到任何可能阻止JavaScript继续运行的运行时错误? – Jacob

+2

你有2个身体标签。 – hvgotcodes

+0

不确定它是相关的,但是您应该使用HTML5文档类型'<!DOCTYPE HTML>'来表示HTML5文档。 –

回答

0

我想感谢那些对我的问题作出贡献的人,这对解决问题很有帮助,我选择的答案是某种方式的最新答案,但它以不同的原因解决了问题。

错误:

把引号包围 'moveBalls(球,盒子)' 动画的东西。

实际上修复问题的方法是从调用moveball函数中删除参数和括号。当我按照海报的建议重写我的代码的其他部分时,我发现了这一点。

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

+0

你问过如何让功能工作 - 你明白了。如果你想要一个代码审查,有很大的改进空间。 :-) – RobG

0

我第一次试图运行它,我得到了在Firebug控制台执行以下操作:

无用setInterval调用(在参数周围缺少引号?) [Break On This Error] setInterval(moveBall(balls,b ox),100);

围绕“moveBalls(球,框)”放置引号来激发事物。

顺便说一句,你可以使用原型inhertiance使你的函数更有效一些,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中,函数的关键字由呼叫建立,它不是由你怎样声明函数(虽然设置你可以使用ES5 绑定,但那还没有得到广泛支持)。

其他一些提示:

在盒构造你正在局部变量,但你真的想将它们分配到新的Box实例,所以使用如此代替VAR

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

clearBox函数中,您使用的是这个,当它没有在通话中设置时,所以它引用窗口。刚刚摆脱它,你通过的功能,因此直接引用:

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

同样适用于moveBallmoveAndCheck功能,只是摆脱(我想你应该做一些研究如何这个在JavaScript中处理,有很多文章,它与Java非常不同)。 现在球会在盒子内很好地反弹。

+2

'setInterval(function(){moveBalls(balls,box)},100)'比传入字符串更高效,更快速。 – slebetman

+0

这只是将全局函数调用包装在调用它的另一个函数中。如果你看代码,OP可以从* moveBalls *中删除形式参数,并执行'setInterval(moveBalls,100)',因为* balls *和* box *是全局变量。 OP有很多东西要学习如何使这种功能与其他代码高效并且很好地协作,一个解决这个问题的答案会非常非常长。 – RobG

+0

这不是一个'只是包装'的东西。传递函数允许函数在编译时编译一次,而不是在运行时循环的每次迭代。速度的差异可能非常显着。我曾亲自看过应用程序,在没有将字符串传递给'setInterval'时,帧速率翻倍或翻倍。仅供参考,'setInterval(function(){moveballs()},x)'与'setInterval(moveballs,x)'更密切相关 - 这两个函数都是重要部分。 – slebetman