SlideShare a Scribd company logo
1 of 12
StefanJS 简介


目录

什么是 StefanJS ................................................................................................................................ 2

为什么使用 StefanJS ........................................................................................................................ 2

StefanJS 详解 .................................................................................................................................... 4

       实体模型................................................................................................................................... 4

              Element ............................................................................................................................. 4
              Layer .................................................................................................................................. 5
              Rect ................................................................................................................................... 6
              Text .................................................................................................................................... 6

              Circle 和 RoundedRect ...................................................................................................... 6

              XComponent...................................................................................................................... 6

              Fill(color、image)和 Border ........................................................................................ 7

       帧渲染机制............................................................................................................................... 7

              坐标转换........................................................................................................................... 7

              更新机制........................................................................................................................... 8

              时间控制........................................................................................................................... 9

       事件模型................................................................................................................................. 10
辅助功能................................................................................................................................. 11

           Tangram、Closure 和 Box2DJS ....................................................................................... 11

           Python 自动化工具 ........................................................................................................ 11




什么是 StefanJS

    StefanJS 是一款基于 HTML5-CANVAS 的游戏/应用引擎,旨在为想要通过 CANVAS 开发游

戏以及应用的程序员提供便利。

    StefanJS 作为一个游戏引擎,除了核心代码外,囊括了脚本编译、项目模板化自动创建

等功能。它基于丰富的 JS 库, tangram、
                如        closure 和 box2d,可以提供丰富的代码逻辑支持。




为什么使用 StefanJS

    我们先来看看,如果不适用 StefanJS 你会遭遇些什么:



   当你接触 CANVAS 编程的时候,你会头痛这家伙根本就是一堆像素点。你每画出一个圆

    形,你总情不自禁地把它和 DOM 对象联系在一起。但是,CANVAS 不像 SVG,它只是

    一张图,你需要的对象它无法提供给你,所以你只能自己模拟。
   因为 CANVAS 的上述特性,理所当然的,它也没有浏览器提供的 DOM1 或者 DOM2 级

    事件模型的支持。因为你压根找不到一个对象为他绑定事件,注册回调函数更无从说起。

    也许你看了第一条以后,把你每一个绘制的图形和对象联系在一起,你也只是成功了一

    小步。因为你还要面对事件系统这一难题。对,你可以给一个对象注册事件,但是你怎

    么触发?答案只有一个——通过坐标判断。你一定会疯掉,因为面对成千上百的元素,

    你怎么去判断?如果你的对象是树形的,你将面对多少次的坐标转换?再刺痛一下你的

    伤口——你怎么去模拟事件冒泡?怎么提供接口去实现浏览器原生事件的

    preventDefault 和 stopPropagation?所以你只能“痛苦吧!在血和暗的深渊里!”

   作为一个无状态的系统,CANVAS 就像一个失意患者一样,每次的刷新都抹去了从前的

    记忆。所以你需要通过一套有效的帧渲染/更新机制,让你的 CANVAS 重拾记忆。于是

    你夜不能寐、辗转反侧……

   当你开发一个大型的游戏,你把所有的赌注都压到一张 CANVAS 里,你会痛苦么?当然!

    你不痛苦浏览器都替你痛苦。每次帧刷新,都要重绘一堆元素,你的浏览器会挂起,系

    统会缓慢,你的用户会离你而去……



    我已然目不忍视,一个开发者经受如此煎熬,所以必须有一个引擎或者框架来拯救它们,

那就是 StefanJS!

    上述的仅仅是编码中遇到的问题,还不涉及到代码的组织、编译以及项目生成等一系列

问题。如果你不想被这些问题困扰,你需要 StefanJS 的帮助。

    StefanJS 的项目托管地址:

    http://code.google.com/p/stefan-js/
StefanJS 详解

   我们从“实体模型” “帧渲染机制” “事件模型” “辅助功能”四个角度去了解这款游戏应用引
           、       、      ,

擎:




实体模型

   StefanJS 是一个完全面向对象的游戏应用引擎。他提供了一套拥有相互继承关系的实体

来构建界面元素:




Element


   StefanJS 最基础的实体类就是 Element,它是所有界面元素的基础,声明或者实现了一
套基础的实体参数和方法。

   元素的基础属性包括:

       Position:set/get,用于设置/获取元素的位置。注意这个位置是相对于父元素的。

       Anchor:set/get,用于设置/获取元素的锚点,也就是自身坐标系的原点针对于元

        素本身的位置。它是一个数组,例如[0.5,1],则说明元素自身坐标系的原点就是元

        素底部中点。

       Size:set/get,用于设置/获取元素的大小。

       Fill:set/get,用于设置/获取元素的填充方式,包括图片、颜色、边缘等。

       Rotation:set/get,用于设置/获取元素的旋转角度。




Layer


   我们前面曾经说过,在一个 canvas 中绘制多个元素,在渲染的时候,将是一笔很大的

系统开销。因此 Layer 为我们解决了这个问题。

   在实体模型的树形结构里,它是最根部的节点,在这棵树里,所有的事件机制和渲染逻

辑都是从根部发起的。它其实是一个绝对定位的 CANVAS。

   之所以构造 Layer 这一实体,主要因为以下两点:

       它能够将帧渲染和事件逻辑按照 CANVAS 分割成多层。例如当你制作一款塔防游戏,

        你可以将控制面板和主体地图区域分成两个 Layer,这样就可以为树降级,减少树

        的深度!

       CANVAS 之间可以良好的叠加,内中元素的透明度不会受 CANVAS 元素的影响,因

        此你可以在制作游戏或者应用的时候,采用叠加的方式构造多层 Layer,将几乎不

        重绘的部分和经常发生重绘的部分分离。
Rect


   它集成于 Element。从它开始继承出来的元素都拥有了“渲染”功能。它实现了 Element

类的 render 抽象方法。

   Element 的 renderAll 方法,是调配当前节点与子节点之间渲染关系的“适配器” 而 render
                                                ,

方法则是渲染的“执行器” 它把元素和和元素的填充、边框等渲染属性连接在一起。
           。

   Rect 类作为无状态帧渲染的中坚力量,任何需要在界面展现的元素都需要继承自它。




Text


   文字类继承于 Rect。它提供了 CANVAS 上的文字展现,包括行高/padding/换行等。

   用户可以通过输入“n”实现文字自定义换行。也可以什么都不用考虑,StefanJS 会做到

文字的自动换行。




Circle 和 RoundedRect


   圆形、圆角矩形类。当然也包括日后将要开发的多边形类,都是 Rect 的重新实现。




XComponent


   任何一款库都离不开他提供的丰富的界面组件,XComponet 就承担了这个使命。现在已

经实现的 Button 和 toggleButton 就是 XComponent 系列中的一员。作为 StefanJS 的 UI 库的

源泉,是所有希望为 StefanJS 开发界面组件的程序员的立足点。
Fill(color、image)和 Border


   CANVAS 赋予开发者丰富而多样的填充图形的能力。包括颜色、图片和边框等。这三个

类分别实现了这几种填充方式。




帧渲染机制

   从“坐标转换” “更新机制”和“时间控制”三个方面来说明 StefanJS 游戏应用引擎的帧渲染
         、

机制:



坐标转换


   对于树形的实体模型,要做到合理的渲染,必须实现一套稳妥的坐标转换机制。

   元素的父子关系通过 appendChild/removeChild 方法维护,
                                         从根节点开始一层一层递进。

结合 anchor/position/size,实现了一套坐标转换的方法。

   先举个例子,看下实体之间的位置关系,如下图:




黑色边框的为 Layer,从 Layer 开始形成一棵深度为 4 的树,节点依次为:红色圆角矩形、

蓝色矩形、绿色圆形。
啥都不说,直接上代码:




 这只是个深度为 4 的树,而且完全没有分叉。但是,如果深度加深,分叉又很多,计算

相互之间的位置转换将是一件很头痛的事情。

 但是 StefanJS 提供了这样一套坐标转换的方法:

 parentToSelf:父->子的坐标转换。

 selfToParent:子->父的坐标转换。

 screenToSelf:页面->当前节点的坐标转换。

 selfToScreen:当前节点->页面的坐标转换。

 selfToLayer:当前节点->Layer 的坐标转换。



更新机制


 拥有了一套完备的实体模型以及坐标转换的方案,接下来得就是看如何通过它们更新界
面。

   前面说过,Element 类提供 renderAll 方法,而 Rect 和继承自 Rect 的类都要实现自己的

一套 render 方法。

   对于 Fill 和 border 类,一般不执行真正的渲染,只是指定 fillStyle 和 strokeStyle 的方式,

而具体的形状类则需要进行真正的区域渲染。

   利用 CANVAS 的 save 和 restore,可以在渲染同层节点时,记录画布当时的状态。这样

一层一层下去,每对 save 和 restore 就像一个一个函数临时作用域一样,把画布的坐标变化

限制在自己内部。

   现在来说下,整个游戏/应用是如何更新的:

   当改变实体元素的位置、锚点、旋转角度等,都会触发元素的 update 方法,这个方法

会将元素所在的 Layer 注册到 Stefan.UpDater 这个单例中,这样就可以在下一帧重绘这个

Layer。




时间控制


   先进的浏览器,都会提供一套自己的帧渲染时间控制函数或者事件。

   例如 Chrome 的 webkitRequestAnimationFrame,以及 firefox 的 MozBeforePaint 事件。

   我们的帧渲染逻辑处理,就是再这些函数参数或者事件回调中。

   例如,chrome 下:




   Firefox 下:
注意, chrome 里,
      在         webkitRequestAnimationFrame 这个是会返回一个数字,但是 Firefox

不会。并且,两者实现帧渲染步进方法的挂载方式也不一样,一个通过函数传参,一个通过

事件回调。

   对于如何停止帧渲染的进行。

   Webkit 内核提供了 webkitCancelRequestAnimationFrame 方法,传入参数是之前注册时

返回的数字。

   对于 Firefox,需要通过 removeListener 的方式去掉事件的回调函数。



   以上所述的是时间控制的核心代码。StefanJS 提供的 Stefan.Timer 单例就是用来处理时

间的。它提供了注册、停止、启动等时间控制方法。




事件模型

   对于 CANVAS 来讲,模拟事件,只能靠坐标。

   比如点击 CANVAS 上得某一像素点,我们需要依托坐标转换来看这一点是属于哪个元素

的。Element 类中的 eventTest 方法就是判断事件发生位置是否处于该元素内部的。

   为了模拟事件冒泡和事件广播,我们需要拟定一个根节点,它就是 CANVAS。所有的事

件都将冒泡到这里。但是由于内部元素可能互相交叠或者繁复错杂,我们需要像原生事件那

样提供一套对事件的管理方法。最重要的就是 stopPropagation 和 preventDefault。

   此外,StefanJS 还提供了 stopAfter 方法,用来阻止比自己先添加的兄弟节点的同类事件

触发,同时阻止事件冒泡。
注册事件的方法采用 element.on(‘eventType’, function)的方式。function 的回调参数是

event,但不是原生的 event,是由 stefanJS 包装过的 event。如果想获取原生事件,只需通

过 event.nativeEvent 属性获得。




辅助功能

Tangram、Closure 和 Box2DJS


   StefanJS 使用了 tangram 和 closure 库,
                                   并且集成了 http://thinkpixellab.com 改写的 box2d

物理引擎。

   我们都知道,tangram 是一种简单可依赖的 JS 库,它只提供方法,而不修改原生对象。

用起来方便易懂。 closure 的 base.js 提供了一套完整的 JS 命名空间维护机制,
        而                                       可以通过更

新 deps.js 来更新 JS 文件之间的依赖关系。

   对于 box2d 物理引擎,他里面定义的物体则和 StefanJS 中定义的物体完全对应,我们可

以在对游戏和应用的时间控制步进方法中,去更新 box2d 的 world!可以这样说,box2d 胜

任了 StefanJS 的动画效果运行,让牛顿成为游戏和应用的总导演。




Python 自动化工具


   初来乍到,使用伊始,你肯定还不知道建立一个 StefanJS 的游戏或者应用的基本框架是

什么。别担心,StefanJS 为你提供了项目生成工具,提供了如下功能:



项目模板化生成



   CD 到 projects 目录,使用“stefan.py create 项目名称” 就可以在 projects 目录中建立你
                                            ,
自己的项目。HTML 和 JS 的模板就会自动改名符合你项目的名称。



文件依赖关系自动更新



  利用 Closure 提供给我们的 python 脚本,使用“Stefan.py update”便可以对项目中的脚本

依赖关系进行自动更新,维护好 closure 库的 deps.js 文件。



压缩编译 JS 代码



  使用“steanfa.py compile arg1 arg2”就可以自动压缩编译 JS 代码。其中 arg1 是工程所使用

的顶级命名空间,arg2 为输出的压缩 JS 的文件名。




                                                      By 樊中恺

More Related Content

Similar to Stefan js游戏引擎

Cite space中文手册
Cite space中文手册Cite space中文手册
Cite space中文手册cueb
 
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案maclean liu
 
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...sugeladi
 
Dwr中文文档
Dwr中文文档Dwr中文文档
Dwr中文文档yiditushe
 
DELL PowerStore 相關主題中譯本
DELL PowerStore 相關主題中譯本DELL PowerStore 相關主題中譯本
DELL PowerStore 相關主題中譯本裝機安 Angelo
 
Huangjing renren
Huangjing renrenHuangjing renren
Huangjing renrend0nn9n
 
Mongo db &lamp;redis,nosql
Mongo db &lamp;redis,nosqlMongo db &lamp;redis,nosql
Mongo db &lamp;redis,nosqltaocheng1989
 
Java eye新闻月刊 2009年08月 - 总第18期
Java eye新闻月刊   2009年08月 - 总第18期Java eye新闻月刊   2009年08月 - 总第18期
Java eye新闻月刊 2009年08月 - 总第18期lileinba
 
Ubuntu手册(中文版)
Ubuntu手册(中文版)Ubuntu手册(中文版)
Ubuntu手册(中文版)byp2011
 
Java eye新闻月刊 -_2010年01月_-_总第23期
Java eye新闻月刊 -_2010年01月_-_总第23期Java eye新闻月刊 -_2010年01月_-_总第23期
Java eye新闻月刊 -_2010年01月_-_总第23期JianXiong Ma
 
Skan it 6.0 user manual chinese
Skan it 6.0 user manual chineseSkan it 6.0 user manual chinese
Skan it 6.0 user manual chineseLenin TaMe
 
Glibc内存管理ptmalloc源代码分析4
Glibc内存管理ptmalloc源代码分析4Glibc内存管理ptmalloc源代码分析4
Glibc内存管理ptmalloc源代码分析4hans511002
 
Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训flynofry
 
Word Press 主題教學
Word Press 主題教學Word Press 主題教學
Word Press 主題教學pao
 
26421135 Word Press 主題教學
26421135  Word Press 主題教學26421135  Word Press 主題教學
26421135 Word Press 主題教學杜龍 杜
 
Liferay环境搭建
Liferay环境搭建Liferay环境搭建
Liferay环境搭建donotbeevil
 
Python 数据库技术第三讲
Python 数据库技术第三讲Python 数据库技术第三讲
Python 数据库技术第三讲March Liu
 
Dreaming Infrastructure
Dreaming InfrastructureDreaming Infrastructure
Dreaming Infrastructurekyhpudding
 
Parnassus data技术白皮书v0.1
Parnassus data技术白皮书v0.1Parnassus data技术白皮书v0.1
Parnassus data技术白皮书v0.1maclean liu
 

Similar to Stefan js游戏引擎 (20)

Cite space中文手册
Cite space中文手册Cite space中文手册
Cite space中文手册
 
Min book
Min bookMin book
Min book
 
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
 
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...
首先要感謝讀者長久以來的支持與愛護!這一系列書籍仍然採用我一貫的 ...
 
Dwr中文文档
Dwr中文文档Dwr中文文档
Dwr中文文档
 
DELL PowerStore 相關主題中譯本
DELL PowerStore 相關主題中譯本DELL PowerStore 相關主題中譯本
DELL PowerStore 相關主題中譯本
 
Huangjing renren
Huangjing renrenHuangjing renren
Huangjing renren
 
Mongo db &lamp;redis,nosql
Mongo db &lamp;redis,nosqlMongo db &lamp;redis,nosql
Mongo db &lamp;redis,nosql
 
Java eye新闻月刊 2009年08月 - 总第18期
Java eye新闻月刊   2009年08月 - 总第18期Java eye新闻月刊   2009年08月 - 总第18期
Java eye新闻月刊 2009年08月 - 总第18期
 
Ubuntu手册(中文版)
Ubuntu手册(中文版)Ubuntu手册(中文版)
Ubuntu手册(中文版)
 
Java eye新闻月刊 -_2010年01月_-_总第23期
Java eye新闻月刊 -_2010年01月_-_总第23期Java eye新闻月刊 -_2010年01月_-_总第23期
Java eye新闻月刊 -_2010年01月_-_总第23期
 
Skan it 6.0 user manual chinese
Skan it 6.0 user manual chineseSkan it 6.0 user manual chinese
Skan it 6.0 user manual chinese
 
Glibc内存管理ptmalloc源代码分析4
Glibc内存管理ptmalloc源代码分析4Glibc内存管理ptmalloc源代码分析4
Glibc内存管理ptmalloc源代码分析4
 
Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训
 
Word Press 主題教學
Word Press 主題教學Word Press 主題教學
Word Press 主題教學
 
26421135 Word Press 主題教學
26421135  Word Press 主題教學26421135  Word Press 主題教學
26421135 Word Press 主題教學
 
Liferay环境搭建
Liferay环境搭建Liferay环境搭建
Liferay环境搭建
 
Python 数据库技术第三讲
Python 数据库技术第三讲Python 数据库技术第三讲
Python 数据库技术第三讲
 
Dreaming Infrastructure
Dreaming InfrastructureDreaming Infrastructure
Dreaming Infrastructure
 
Parnassus data技术白皮书v0.1
Parnassus data技术白皮书v0.1Parnassus data技术白皮书v0.1
Parnassus data技术白皮书v0.1
 

Stefan js游戏引擎

  • 1. StefanJS 简介 目录 什么是 StefanJS ................................................................................................................................ 2 为什么使用 StefanJS ........................................................................................................................ 2 StefanJS 详解 .................................................................................................................................... 4 实体模型................................................................................................................................... 4 Element ............................................................................................................................. 4 Layer .................................................................................................................................. 5 Rect ................................................................................................................................... 6 Text .................................................................................................................................... 6 Circle 和 RoundedRect ...................................................................................................... 6 XComponent...................................................................................................................... 6 Fill(color、image)和 Border ........................................................................................ 7 帧渲染机制............................................................................................................................... 7 坐标转换........................................................................................................................... 7 更新机制........................................................................................................................... 8 时间控制........................................................................................................................... 9 事件模型................................................................................................................................. 10
  • 2. 辅助功能................................................................................................................................. 11 Tangram、Closure 和 Box2DJS ....................................................................................... 11 Python 自动化工具 ........................................................................................................ 11 什么是 StefanJS StefanJS 是一款基于 HTML5-CANVAS 的游戏/应用引擎,旨在为想要通过 CANVAS 开发游 戏以及应用的程序员提供便利。 StefanJS 作为一个游戏引擎,除了核心代码外,囊括了脚本编译、项目模板化自动创建 等功能。它基于丰富的 JS 库, tangram、 如 closure 和 box2d,可以提供丰富的代码逻辑支持。 为什么使用 StefanJS 我们先来看看,如果不适用 StefanJS 你会遭遇些什么:  当你接触 CANVAS 编程的时候,你会头痛这家伙根本就是一堆像素点。你每画出一个圆 形,你总情不自禁地把它和 DOM 对象联系在一起。但是,CANVAS 不像 SVG,它只是 一张图,你需要的对象它无法提供给你,所以你只能自己模拟。
  • 3. 因为 CANVAS 的上述特性,理所当然的,它也没有浏览器提供的 DOM1 或者 DOM2 级 事件模型的支持。因为你压根找不到一个对象为他绑定事件,注册回调函数更无从说起。 也许你看了第一条以后,把你每一个绘制的图形和对象联系在一起,你也只是成功了一 小步。因为你还要面对事件系统这一难题。对,你可以给一个对象注册事件,但是你怎 么触发?答案只有一个——通过坐标判断。你一定会疯掉,因为面对成千上百的元素, 你怎么去判断?如果你的对象是树形的,你将面对多少次的坐标转换?再刺痛一下你的 伤口——你怎么去模拟事件冒泡?怎么提供接口去实现浏览器原生事件的 preventDefault 和 stopPropagation?所以你只能“痛苦吧!在血和暗的深渊里!”  作为一个无状态的系统,CANVAS 就像一个失意患者一样,每次的刷新都抹去了从前的 记忆。所以你需要通过一套有效的帧渲染/更新机制,让你的 CANVAS 重拾记忆。于是 你夜不能寐、辗转反侧……  当你开发一个大型的游戏,你把所有的赌注都压到一张 CANVAS 里,你会痛苦么?当然! 你不痛苦浏览器都替你痛苦。每次帧刷新,都要重绘一堆元素,你的浏览器会挂起,系 统会缓慢,你的用户会离你而去…… 我已然目不忍视,一个开发者经受如此煎熬,所以必须有一个引擎或者框架来拯救它们, 那就是 StefanJS! 上述的仅仅是编码中遇到的问题,还不涉及到代码的组织、编译以及项目生成等一系列 问题。如果你不想被这些问题困扰,你需要 StefanJS 的帮助。 StefanJS 的项目托管地址: http://code.google.com/p/stefan-js/
  • 4. StefanJS 详解 我们从“实体模型” “帧渲染机制” “事件模型” “辅助功能”四个角度去了解这款游戏应用引 、 、 , 擎: 实体模型 StefanJS 是一个完全面向对象的游戏应用引擎。他提供了一套拥有相互继承关系的实体 来构建界面元素: Element StefanJS 最基础的实体类就是 Element,它是所有界面元素的基础,声明或者实现了一
  • 5. 套基础的实体参数和方法。 元素的基础属性包括:  Position:set/get,用于设置/获取元素的位置。注意这个位置是相对于父元素的。  Anchor:set/get,用于设置/获取元素的锚点,也就是自身坐标系的原点针对于元 素本身的位置。它是一个数组,例如[0.5,1],则说明元素自身坐标系的原点就是元 素底部中点。  Size:set/get,用于设置/获取元素的大小。  Fill:set/get,用于设置/获取元素的填充方式,包括图片、颜色、边缘等。  Rotation:set/get,用于设置/获取元素的旋转角度。 Layer 我们前面曾经说过,在一个 canvas 中绘制多个元素,在渲染的时候,将是一笔很大的 系统开销。因此 Layer 为我们解决了这个问题。 在实体模型的树形结构里,它是最根部的节点,在这棵树里,所有的事件机制和渲染逻 辑都是从根部发起的。它其实是一个绝对定位的 CANVAS。 之所以构造 Layer 这一实体,主要因为以下两点:  它能够将帧渲染和事件逻辑按照 CANVAS 分割成多层。例如当你制作一款塔防游戏, 你可以将控制面板和主体地图区域分成两个 Layer,这样就可以为树降级,减少树 的深度!  CANVAS 之间可以良好的叠加,内中元素的透明度不会受 CANVAS 元素的影响,因 此你可以在制作游戏或者应用的时候,采用叠加的方式构造多层 Layer,将几乎不 重绘的部分和经常发生重绘的部分分离。
  • 6. Rect 它集成于 Element。从它开始继承出来的元素都拥有了“渲染”功能。它实现了 Element 类的 render 抽象方法。 Element 的 renderAll 方法,是调配当前节点与子节点之间渲染关系的“适配器” 而 render , 方法则是渲染的“执行器” 它把元素和和元素的填充、边框等渲染属性连接在一起。 。 Rect 类作为无状态帧渲染的中坚力量,任何需要在界面展现的元素都需要继承自它。 Text 文字类继承于 Rect。它提供了 CANVAS 上的文字展现,包括行高/padding/换行等。 用户可以通过输入“n”实现文字自定义换行。也可以什么都不用考虑,StefanJS 会做到 文字的自动换行。 Circle 和 RoundedRect 圆形、圆角矩形类。当然也包括日后将要开发的多边形类,都是 Rect 的重新实现。 XComponent 任何一款库都离不开他提供的丰富的界面组件,XComponet 就承担了这个使命。现在已 经实现的 Button 和 toggleButton 就是 XComponent 系列中的一员。作为 StefanJS 的 UI 库的 源泉,是所有希望为 StefanJS 开发界面组件的程序员的立足点。
  • 7. Fill(color、image)和 Border CANVAS 赋予开发者丰富而多样的填充图形的能力。包括颜色、图片和边框等。这三个 类分别实现了这几种填充方式。 帧渲染机制 从“坐标转换” “更新机制”和“时间控制”三个方面来说明 StefanJS 游戏应用引擎的帧渲染 、 机制: 坐标转换 对于树形的实体模型,要做到合理的渲染,必须实现一套稳妥的坐标转换机制。 元素的父子关系通过 appendChild/removeChild 方法维护, 从根节点开始一层一层递进。 结合 anchor/position/size,实现了一套坐标转换的方法。 先举个例子,看下实体之间的位置关系,如下图: 黑色边框的为 Layer,从 Layer 开始形成一棵深度为 4 的树,节点依次为:红色圆角矩形、 蓝色矩形、绿色圆形。
  • 8. 啥都不说,直接上代码: 这只是个深度为 4 的树,而且完全没有分叉。但是,如果深度加深,分叉又很多,计算 相互之间的位置转换将是一件很头痛的事情。 但是 StefanJS 提供了这样一套坐标转换的方法: parentToSelf:父->子的坐标转换。 selfToParent:子->父的坐标转换。 screenToSelf:页面->当前节点的坐标转换。 selfToScreen:当前节点->页面的坐标转换。 selfToLayer:当前节点->Layer 的坐标转换。 更新机制 拥有了一套完备的实体模型以及坐标转换的方案,接下来得就是看如何通过它们更新界
  • 9. 面。 前面说过,Element 类提供 renderAll 方法,而 Rect 和继承自 Rect 的类都要实现自己的 一套 render 方法。 对于 Fill 和 border 类,一般不执行真正的渲染,只是指定 fillStyle 和 strokeStyle 的方式, 而具体的形状类则需要进行真正的区域渲染。 利用 CANVAS 的 save 和 restore,可以在渲染同层节点时,记录画布当时的状态。这样 一层一层下去,每对 save 和 restore 就像一个一个函数临时作用域一样,把画布的坐标变化 限制在自己内部。 现在来说下,整个游戏/应用是如何更新的: 当改变实体元素的位置、锚点、旋转角度等,都会触发元素的 update 方法,这个方法 会将元素所在的 Layer 注册到 Stefan.UpDater 这个单例中,这样就可以在下一帧重绘这个 Layer。 时间控制 先进的浏览器,都会提供一套自己的帧渲染时间控制函数或者事件。 例如 Chrome 的 webkitRequestAnimationFrame,以及 firefox 的 MozBeforePaint 事件。 我们的帧渲染逻辑处理,就是再这些函数参数或者事件回调中。 例如,chrome 下: Firefox 下:
  • 10. 注意, chrome 里, 在 webkitRequestAnimationFrame 这个是会返回一个数字,但是 Firefox 不会。并且,两者实现帧渲染步进方法的挂载方式也不一样,一个通过函数传参,一个通过 事件回调。 对于如何停止帧渲染的进行。 Webkit 内核提供了 webkitCancelRequestAnimationFrame 方法,传入参数是之前注册时 返回的数字。 对于 Firefox,需要通过 removeListener 的方式去掉事件的回调函数。 以上所述的是时间控制的核心代码。StefanJS 提供的 Stefan.Timer 单例就是用来处理时 间的。它提供了注册、停止、启动等时间控制方法。 事件模型 对于 CANVAS 来讲,模拟事件,只能靠坐标。 比如点击 CANVAS 上得某一像素点,我们需要依托坐标转换来看这一点是属于哪个元素 的。Element 类中的 eventTest 方法就是判断事件发生位置是否处于该元素内部的。 为了模拟事件冒泡和事件广播,我们需要拟定一个根节点,它就是 CANVAS。所有的事 件都将冒泡到这里。但是由于内部元素可能互相交叠或者繁复错杂,我们需要像原生事件那 样提供一套对事件的管理方法。最重要的就是 stopPropagation 和 preventDefault。 此外,StefanJS 还提供了 stopAfter 方法,用来阻止比自己先添加的兄弟节点的同类事件 触发,同时阻止事件冒泡。
  • 11. 注册事件的方法采用 element.on(‘eventType’, function)的方式。function 的回调参数是 event,但不是原生的 event,是由 stefanJS 包装过的 event。如果想获取原生事件,只需通 过 event.nativeEvent 属性获得。 辅助功能 Tangram、Closure 和 Box2DJS StefanJS 使用了 tangram 和 closure 库, 并且集成了 http://thinkpixellab.com 改写的 box2d 物理引擎。 我们都知道,tangram 是一种简单可依赖的 JS 库,它只提供方法,而不修改原生对象。 用起来方便易懂。 closure 的 base.js 提供了一套完整的 JS 命名空间维护机制, 而 可以通过更 新 deps.js 来更新 JS 文件之间的依赖关系。 对于 box2d 物理引擎,他里面定义的物体则和 StefanJS 中定义的物体完全对应,我们可 以在对游戏和应用的时间控制步进方法中,去更新 box2d 的 world!可以这样说,box2d 胜 任了 StefanJS 的动画效果运行,让牛顿成为游戏和应用的总导演。 Python 自动化工具 初来乍到,使用伊始,你肯定还不知道建立一个 StefanJS 的游戏或者应用的基本框架是 什么。别担心,StefanJS 为你提供了项目生成工具,提供了如下功能: 项目模板化生成 CD 到 projects 目录,使用“stefan.py create 项目名称” 就可以在 projects 目录中建立你 ,
  • 12. 自己的项目。HTML 和 JS 的模板就会自动改名符合你项目的名称。 文件依赖关系自动更新 利用 Closure 提供给我们的 python 脚本,使用“Stefan.py update”便可以对项目中的脚本 依赖关系进行自动更新,维护好 closure 库的 deps.js 文件。 压缩编译 JS 代码 使用“steanfa.py compile arg1 arg2”就可以自动压缩编译 JS 代码。其中 arg1 是工程所使用 的顶级命名空间,arg2 为输出的压缩 JS 的文件名。 By 樊中恺