0 Comments

使用JavaScript和Canvas写一个游戏框架(1)

发布于:2013-09-12  |   作者:广州网站建设  |   已聚集:人围观

4、写一个游戏框架(一)

http://www.brighthub.com/internet/web-development/articles/40512.aspx

在知道了如何使用画布元素之后,接下来我教大家写一个框架,有了这个框架,我们就可以把它作为基础来创建游戏。在这第一部分,我们会介绍前两个文件/类。

编写代码之前,我们先来看一看随后几篇文章将致力于创建的示例Demo。表面上看起来,这个Demo跟第二篇文章里的那个没啥区别,但如果你看看后台(查看网页源代码)就会发现,为了更方便地创建这个最终效果,一个凝聚不少心血的基础框架已经写好了。

广州网站建设,网站建设,广州网页设计,广州网站设计

 

下面我们要介绍的JavaScript代码使用面向对象的方式来编写。对于没有编写过多少JavaScript代码的人来说,恐怕第一眼看到它们会觉得有点奇怪。如果你真的不太熟悉JavaScript的面向对象编程,建议通过Mozilla Developer Network的这个教程https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript来补补课。这篇教程里解释了我们稍后会用到的一些编程技术。

从设计思想上来看,这个框架可以分成两部分:与底层的2D引擎交互的类(用于操作画布、控制渲染循环、处理输入等的代码)和用来创建对象以便构成游戏的类。前者可以归为引擎类,后者可以归为应用类。由于应用类要构建于引擎类之上,所以我们需要先来创建引擎类。

Main.js

如果你研究了前面例子中的代码,就会发现Main.js文件中包含了不少代码。


  1.  
  2. /** 每秒多少帧  
  3.     @type Number  
  4. */  
  5. var FPS = 30;  
  6. /** 两帧间间隔的秒数  
  7.     @type Number  
  8. */  
  9. var SECONDS_BETWEEN_FRAMES = 1 / FPS;  
  10. /** GameObjectManager 实例的全局引用  
  11.     @type GameObjectManager  
  12. */  
  13. var g_GameObjectManager = null;  
  14. /** 应用中用到的图像  
  15.     @type Image  
  16. */  
  17. var g_image = new Image();  
  18. g_image.src = "jsplatformer3-smiley.jpg";  
  19.  
  20. // 将应用的入口设置为init函数  
  21. window.onload = init;  
  22.  
  23. /**  
  24.     应用的入口  
  25. */  
  26. function init()  
  27. {  
  28.     new GameObjectManager().startupGameObjectManager();  
  29. }  

首先是定义全局变量的代码。然后,跟以前一样,当页面加载完毕后立即运行init函数。在init函数里,创建GameObjectManager类的实例。

这里在GameObjectManager类的实例上调用了startupGameObjectManager函数。这篇文章以及后面的几篇文章还将多次提到几个命名上具有startupClassName形式的函数。这些函数实际上充当了各自类的构造函数,这样做有两个原因。

首先,JavaScript不支持函数重载(至少不容易实现)。如果你想让一个类有多个构造函数,那么这就成了问题。而通过把构造工作分配给另一组函数(如startupClassName1、startupClassName2),就可以比较容易地定义构造类的不同方式了。
广州网站建设,网站建设,广州网页设计,广州网站设计

第二个原因(很大程度上也是个人的问题)是我经常会在构造函数中引用尚未定义的变量。这可能是我使用C++、Java和C#这些语言落下的毛病,在这些语言里,类变量在源代码中的位置对其在构造函数中的可见性没有影响。拿下面这个C#类为例:


  1. class Test  
  2. {  
  3.     public void Test() {this.a = 5;}  
  4.     public int a;  
  5. }  

这些代码是合乎语法的,可以正常工作。下面再看看JavaScript中一个相同的例子:


  1. function Test()  
  2. {  
  3.     this.a = 5;  
  4.     var a;  
  5. }  

这段代码的问题在于,局部变量a在我们把数值5赋给它的时候还不存在。只有运行到var a;这一行,变量a才存在。尽管这个例子有点故意编排的意味,但的确能够说明我所遇到的问题。通过把类的创建放到一个类似startupClassName这样的函数中完成,并且在构造函数中定义(但不初始化)局部变量,然后当我在这些构建函数中引用相应的局部变量时,就能够确保它们一定是存在的。

标签:
飞机