《TypeScript图形渲染实战:2D架构设计与实现》 —3.2.3 Application类中的更新和重绘
3.2.3 Application类中的更新和重绘
Application中的step成员方法和3.1节中的step函数仅仅有一些小的差别。下面来看一下代码是如何实现的。
// 不停地周而复始运动
protected step ( timeStamp : number ) : void {
// 第一次调用本函数时,设置start和lastTime为timeStamp
if ( this . _startTime === -1 ) this . _startTime = timeStamp ;
if( this . _lastTime === -1 ) this . _lastTime = timeStamp ;
//计算当前时间点与第一次调用step时间点的差,以毫秒为单位
let elapsedMsec : number = timeStamp - this . _startTime ;
//计算当前时间点与上一次调用step时间点的差(可以理解为两帧之间的时间差)
// 注意:intervalSec是以秒为单位,因此要除以1000.0
let intervalSec : number = ( timeStamp - this . _lastTime )/ 1000.0 ;
//记录上一次的时间戳
this . _lastTime = timeStamp ;
console . log (" elapsedTime = " + elapsedMsec + " intervalSec = " +
intervalSec ) ;
// 先更新
this . update ( elapsedMsec , intervalSec ) ;
// 后渲染
this . render ( ) ;
// 递归调用,形成周而复始地循环操作
requestAnimationFrame ( ( elapsedMsec : number ) : void => {
this . step ( elapsedMsec ) ;
} ) ;
}
最后来看一下在Application类中的update和render函数。具体代码如下:
//虚方法,子类能覆写(override)
//注意:intervalSec是以秒为单位的,而elapsedMsec是以毫秒为单位
public update ( elapsedMsec : number , intervalSec : number ) : void { }
//虚方法,子类能覆写(override)
public render ( ) : void { }
会发现,update和render方法都是空实现,需要继承自Application的子类根据实际的需求来覆写(override)这两个方法,这是面向对象三要素的经典体现,如下所述。
* 封装:将不变的部分(更新和渲染的流程)封装起来放在基类中,也就是基类固定了整个行为规范。
* 多态:将可变部分以虚函数的方式公开给具体实现者,基类并不知道每个子类要如何更新,也不知道每个子类如何渲染(例如,Canvas2DApplication子类使用CanvasRenderingContext2D来进行各种二维图形的绘制,而WebGLApplication子类则使用WebGLRenderingContext进行二维或三维图形的绘制),让具体的子类来实现具体的行为,运行时动态绑定到实际调用的类成员方法上。
* 继承:很明显,虚函数多态机制依赖于继承,没有继承就没有多态。
- 点赞
- 收藏
- 关注作者
评论(0)