下面来看一看draw函数。
- /**
- 渲染循环
- */
- this.draw = function ()
- {
- // 计算从上一帧到现在的时间
- var thisFrame = new Date().getTime();
- var dt = (thisFrame - this.lastFrame)/1000;
- this.lastFrame = thisFrame;
- // 清理绘制上下文
- this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);
- this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);
- // 首先更新所有游戏对象
- for (x in this.gameObjects)
- {
- if (this.gameObjects[x].update)
- {
- this.gameObjects[x].update(dt, this.backBufferContext2D, this.xScroll, this.yScroll);
- }
- }
- // 然后绘制所有游戏对象
- for (x in this.gameObjects)
- {
- if (this.gameObjects[x].draw)
- {
- this.gameObjects[x].draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll);
- }
- }
- // 将后台缓冲复制到当前显示的画布
- this.context2D.drawImage(this.backBuffer, 0, 0);
- };
这个draw函数就是所有渲染循环的核心。在前面的例子中,渲染循环的函数会直接修改要绘制到屏幕上的对象(笑脸)。如果只需绘制一个对象,这样做没有问题。但是,一个游戏要由几十个单独的对象组成,所以这个draw函数并没有直接在渲染循环中直接处理要绘制的对象,而是维护了一个保存着这些对象的数组,让这些对象自己来更新和绘制自己。
首先,计算自上一帧渲染所经过的时间。即便我们在代码里写了每秒钟调用30次draw函数,但谁也无法保证事实如此。通过计算自上一帧渲染所经过的时间,可以做到尽可能让游戏的执行与帧速率无关。
- // 计算从上一帧到现在的时间
- var thisFrame = new Date().getTime();
- var dt = (thisFrame - this.lastFrame)/1000;
- this.lastFrame = thisFrame;
接着清理绘制上下文。
广州网站建设,网站建设,广州网页设计,广州网站设计
- // 清理绘制上下文
- this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);
- this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);
然后,就是调用游戏对象(这些对象是由GameObject类定义的,下一篇文章将介绍该类)自己的更新(update)和绘制(draw)方法。注意,这两个方法是可选的(这也是我们在调用它们之前先检查它们是否存在的原因),但差不多每一个对象都需要更新和绘制自已。
- // 首先更新所有游戏对象
- for (x in this.gameObjects)
- {
- if (this.gameObjects[x].update)
- {
- this.gameObjects[x].update(dt, this.backBufferContext2D, this.xScroll, this.yScroll);
- }
- }
- // 然后绘制所有游戏对象
- for (x in this.gameObjects)
- {
- if (this.gameObjects[x].draw)
- {
- this.gameObjects[x].draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll);
- }
- }
最后,把后台缓冲复制到前台缓冲,最终用户就可以看到下一帧了。
- // 将后台缓冲复制到当前显示的画布
- this.context2D.drawImage(this.backBuffer, 0, 0);
理解了draw函数,下面再分别讲一讲addGameObject和removeGameObject函数。
广州网站建设,网站建设,广州网页设计,广州网站设计
- /**
- 向gameObjects集合中添加一个GameObject
- @param gameObject The object to add
- */
- this.addGameObject = function(gameObject)
- {
- this.gameObjects.push(gameObject);
- this.gameObjects.sort(function(a,b){return a.zOrder - b.zOrder;})
- };
- /**
- 从gameObjects集合中删除一个GameObject
- @param gameObject The object to remove
- */
- this.removeGameObject = function(gameObject)
- {
- this.gameObjects.removeObject(gameObject);
- }
利用addGameObject和removeGameObject(在Utils.js文件里通过扩展Array.prototype添加)函数,可以在GameObjectManager所维护的GameObject集合(即gameObjects变量)中添加和删除游戏对象。
GameObjectManager类是我们这个游戏框架中最复杂的一个类。在下一篇文章中,我们会讲解游戏框架的另外几个类:GameObject、VisualGameObject、Bounce和ApplicationManager。
好了,现在放松一下,看一看Demo吧。
原文:http://www.brighthub.com/content/matthewcaspersonshubfoliohasmoved.aspx