TypeScript图形渲染实战(2D架构设计和实现)详介

2019-03-13  本文已影响0人  随风而行之青衫磊落险峰行
一本让你知其然,知其所以然的TypeScript 2D图形架构和常用基础算法书

京东商场网购链接地址,请点这里

一、书写本书的目的

本书的目的是使用微软最新的TypeScript语言,以面向接口及泛型的编程方式,采用HTML5中的Canvas2D绘图API,实现了一个具备最小运行环境(更新、重绘、裁剪以及事件分发和响应)的,支持精确点选(点与点、线段、矩形、圆形、椭圆、三角形以及凸多边形)的,采取享元设计模式的,基于场景图管理的并且兼容非场景图类型的,易于扩展的2D动画精灵系统,并在该精灵系统上演示精心设计的,和图形数学变换相关的Demo。

精灵系统架构图

二、本书有何特色

本书特色
1. 全程使用TypeScript面向接口编程

本书通过TypeScript语言提供的面向接口编程的能力,实现了:

2. 披露Canvas2D底层原理

本书在讲述Canvas2D相关内容的章节中,实现了如下几个重要的例子:

3. 详解图形数学及点与基本几何形体的碰检算法

图形编程的最大拦路虎是涉及图形数学变换内容,本书设计的大部分例子都是以图形数学变换为核心,主要例子如下所示:

4. 提供几何原理图示的生成源码

本书图形数学相关部分的几何原理图都是使用Canvas2D直接绘制出来,并在相关章节后面提供所有这些几何原理图示的绘制源码,包括:

5. 精准的使用设计模式

总结一下本书中主要用到了哪些设计模式,在哪里使用:

6 详尽的描述树数据结构的要点

本书专门提供一章来了解树数据结构,并且详尽的描述了树的各种重要算法:

7. 提供完善的技术支持和售后服务

本书提供了专门的技术支持邮箱:47178234@qq.com。读者在阅读本书过程中有任何疑问都可以通过该邮箱获得帮助。

三、本书内容及知识体系

全书共分10章,下面是各章的内容简要介绍。

第1章 构建TypeScript开发编译和调试环境

在本章中,以循序渐进的方式介绍了TypeScript语言的开发、编译和调试环境的构建过程,最终形成一个支持源码自动编译、模块自动载入、服务器端热部署、具有强大断点调试功能的TypeScript快捷开发环境。

第2章 使用TypeScript实现Doom3词法解析器

在本章中,使用TypeScript语言,以面向接口的方式实现了一个Doom3(原id Software公司毁灭战士3游戏引擎)词法解析器,并且在此基础上实现了工厂模式和迭代器两种设计模式,使其支持接口的生成以及使用迭代方式进行Token解析输出,同时封装了XMLHttpRequest类,用来支持从服务器端下载要解析的文件。本章详细描述TypeScript中后续章节要用到的一些常用语法知识。

第3章 动画与Application类

在本章中,详细的了解了requestAnimationFrame方法与屏幕刷新频率之间的关系,并且在此基础上封装了一个支持基于时间的刷新、重绘、事件的分发和处理的Application类,并且实现了能正确处理CSS盒模型的坐标变换功能,最后添加了支持不同帧率运行的计时器,模拟了setTimeout和setInterval方法的实现。

第4章 使用Canvas2D绘图

在本章中,主要关注Canvas2D中矢量图形、文本、图像以及阴影绘制相关内容,实现了一个本章以及后续章节要使用的、基于Canvas2D的演示和测试环境。可以重点关注一下渲染状态堆栈的实现原理、文本各种对齐方式算法、支持repeat模式的drawImage实现等相关内容。

第5章 Canvas2D坐标系变换

在本章中,通过多个例子来演示Canvas2D中局部坐标系变换相关的知识点,目的是让读者掌握变换顺序的重要性,如何理解变换以及原点变换的几种方式,并且通过一个太阳自转,月亮自公转的例子来了解Canvas2D中矩阵堆栈层次变换用法,最后通过一个坦克跟随鼠标朝向正确的运动Demo来深入理解一些常用的三角函数的应用。本章是本书的精华章节。

第6章 向量数学及基本形体的点选

在本章中,首先讲述了向量的一些基本操作,然后通过向量的加法和缩放操作,替换掉第5章坦克Demo中使用的sin / cos函数。接着为了演示向量这些基本操作,特意实现了点投影到向量的动画效果Demo。接着在下一节中关注点与线段、圆、矩形、椭圆、三角形、凸多边形等基本形体之间的碰撞检测算法。在本章最后一节中,附加了本章所有几何图示的生成源码,目的是让大家更加深入的了解向量各个操作背后的几何含义。

第7章 矩阵数学及贝塞尔曲线

在本章中,首先讲述了矩阵相关的知识,重点推导了旋转矩阵。然后将第5章中的坦克Demo用矩阵方式重写,目的是为了演示如何从两个单位向量构建旋转矩阵从而消除掉atan2函数的使用。接着模拟了Canvas2D中的矩阵堆栈,并且使用自己实现的矩阵堆栈重写坦克Demo的相关操作。最后一节主要关注贝塞尔曲线多项式的推导过程以及实现一个曲线动画Demo。

第8章 精灵系统

在本章中,以面向接口编程方式实现一个具有必要功能的(更新、绘制、鼠标和键盘事件的分发与响应)、使用非场景图类型的、支持精确点选的、基于保留模式的、采取享元设计模式的精灵系统。并在该精灵系统上实现了一个Demo,用来测试精灵系统的点与各个基本形体之间的精确碰撞检测。

第9章 优美典雅的树结构

在本章中,主要讲解了树结构的增删改查,以及各种遍历算法,最后实现树结构的JSON序列化和反序列化算法,本章也是TypeScript泛型编程的灵活应用章节,里面涉及不少泛型编程的细节。

第10章 场景图系统

本章是前面知识的大融合,以面向接口的编程方式实现一个具有必要功能(更新,重绘,裁剪及事件分发和响应)的、使用场景图类型(建立在第9章树结构上)的、支持精确点选的、基于非立即渲染模式(保留模式)的、采取享元设计模式的、兼容运行第8章的非场景图类型的精灵系统。然后通过骨骼层次精灵动画来演示场景图的层次变换功能以及享元模式的优点,最后实现坦克沿着贝塞尔路径朝向正确运行的Demo来演示该精灵系统的综合特点。

由此可见,本书的章节安排按照知识体系结构可以划分为四个篇章。

四、适合阅读本书的读者

五、阅读本书的建议

六、本书目录

第1章 构建TypeScript开发编译和调试环境

1.1 TypeScript简介


1.2 安装TypeScript开发环境
1.2.1 安装NodeJS
1.2.2 安装Visual Studio Code
1.2.3 npm全局安装TypeScript
1.2.4 第一个TypeScript程序


1.3 使用tsc编译(转译)器
1.3.1 生成tsconfig.json文件
1.3.2 解决生成tsconfig.json文件后带来的常见问题
1.3.3 自动编译TypeScript文件


1.4 模块化开发TypeScript
1.4.1 tsconfig.json文件中的target和module命令选项
1.4.2 编写Canvas2D类导出给main.ts调用
1.4.3 使用lite-server搭建本地服务器


1.5 使用SystemJS自动编译加载TypeScript
1.5.1 npm本地安装TypeScript库和SystemJS库
1.5.2 SystemJS直接编译TypeScript源码


1.6 使用VS Code调试TypeScript源码
1.6.1 安装及配置Debugger for Chrome扩展
1.6.2 VS Code中单步调试TypeScript


1.7 本章总结


第2章 使用TypeScript实现Doom3词法解析器

2.1 Token与Tokenizer
2.1.1 Doom3文本文件格式
2.1.2 使用IDoom3Token与IDoom3Tokenizer接口
2.1.3 ES6中的模板字符串
2.1.4 IDoom3Token与IDoom3Tokenizer接口的定义


2.2 IDoom3Token与IDoom3Tokenizer接口的实现
2.2.1 Doom3Token类成员变量的声明
2.2.2 Doom3Token类变量初始化的问题
2.2.3 IDoom3Token接口方法的实现
2.2.4 Doom3Token类的非接口方法实现
2.2.5 Doom3Tokenzier处理数字和空白符
2.2.6 IDoom3Tokenizer接口方法实现
2.2.7 Doom3Tokenizer字符处理私有方法
2.2.8 核心的getNextToken方法
2.2.9 跳过不需处理的空白符和注释
2.2.10 实现_getNumber方法解析数字类型
2.2.11 实现_getSubstring方法解析子字符串
2.2.12 实现_getString方法解析字符串
2.2.13 IDoom3Tokenizer词法解析器状态总结表


2.3 使用工厂模式和迭代器模式
2.3.1 微软COM中创建接口的方式
2.3.2 Doom3Factory工厂类
2.3.3 迭代器模式已经成为语法的一部分
2.3.4 模拟微软.NetFramework中的泛型迭代器
2.3.5 IDoom3Tokenizer扩展 IEnumerator接口
2.3.6 修改Doom3Tokenizer源码
2.3.7 使用VS Code中的重命名重构方法
2.3.8 使用迭代器来解析Token
2.3.9 面向接口面向对象编程的个人感悟


2.4 从服务器获取资源
2.4.1 加载本地HTML资源遇到的问题
2.4.2 从服务器加载资源
2.4.3 使用XHR向服务器请求资源文件
2.4.4 TypeScript中的类型别名
2.4.5 使用doGet请求文本文件并解析
2.4.6 解决仍有空白字符输出问题
2.4.7 实现doGetAsync异步请求方法
2.4.8 声明TypeScript中的回调函数
2.4.9 调用回调函数


2.5 本章总结


第3章 动画与Application类

3.1 requestAnimationFrame方法与动画
3.1.1 HTML中不间断的循环
3.1.2 requestAnimationFrame与监视器刷新频率
3.1.3 基于时间的更新与重绘


3.2 Application类及其子类
3.2.1 Application类体系结构
3.2.2 启动动画循环和停止动画循环
3.2.3 Application类中的更新和重绘
3.2.4 回调函数this指向问题
3.2.5 函数调用时this指向的Demo演示
3.2.6 CanvasInputEvent及其子类
3.2.7 使用getBoundingRect ( )方法变换坐标系
3.2.8 将DOM Event事件转换为CanvasInputEvent事件
3.2.9 EventListenerObject与事件分发
3.2.10 让事件起作用
3.2.11 Canvas2DApplication子类和WebGLApplication子类


3.3 测试及修正Application类
3.3.1 继承并覆写Application基类的虚方法
3.3.2 测试ApplicationTest类
3.3.3 多态(虚函数动态绑定)
3.3.4 鼠标点击事件测试
3.3.5 CSS盒模型对_viewportToCanvasCoordinate的影响
3.3.6 正确的_viewportToCanvasCoordinate方法实现


3.4 为Application类增加计时器功能
3.4.1 Timer类与TimeCallback回调函数
3.4.2 添加和删除Timer(计时器)
3.4.3 触发多个定时任务的操作
3.4.4 测试Timer功能


3.5 本章总结


第4章 使用Canvas2D绘图

4.1 绘制基本几何物体
4.1.1 Canvas2DApplication的绘制流程
4.1.2 绘制矩形Demo
4.1.3 模拟Canvas2D中渲染状态堆栈
4.1.4 线段属性与描边操作(stroke)
4.1.5 虚线绘制(交替绘制线段)
4.1.6 使用颜色描边和填充
4.1.7 使用渐变对象描边和填充
4.1.8 使用图案对象描边和填充
4.1.9 后续要用到的一些常用绘制方法


4.2 绘制文本
4.2.1 封装fillText方法
4.2.2 文本的对齐方式
4.2.3 自行实现文本对齐效果
4.2.4 计算文本高度算法
4.2.5 嵌套矩形定位算法
4.2.6 fillRectWithTitle方法的实现
4.2.7 自行文本对齐实现Demo
4.2.8 font属性
4.2.9 实现makeFontString辅助方法


4.3 绘制图像
4.3.1 drawImage方法
4.3.2 Repeat图像填充模式
4.3.3 加强版的drawImage方法的实现
4.3.4 加强版drawImage方法效果演示
4.3.5 离屏Canvas的使用
4.3.6 操作Canvas中的图像数据


4.4 绘制阴影


4.5 本章总结


第5章 坐标系变换

5.1 局部坐标系变换
5.1.1 准备工作
5.1.2 平移操作演示
5.1.3 平移和旋转组合操作演示
5.1.4 绘制旋转的轨迹
5.1.5 变换局部坐标系的原点
5.1.6 测试fillLocalRectWithTitle方法
5.1.7 彻底掌控局部坐标系变换
5.1.8 通用的原点变换方法
5.1.9 公转(Revolution)与自转(Rotation)
5.1.10 原点变换的另一种方法


5.2 坦克Demo
5.2.1 象限(Quadrant)文字绘制
5.2.2 坦克形体的绘制
5.2.3 坦克以及炮塔的旋转
5.2.4 计算坦克的朝向
5.2.5 坦克朝着目标移动
5.2.6 使用键盘控制炮塔的旋转
5.2.7 初始朝向的重要性
5.2.8 朝向正确的运行
5.2.9 图5.25效果的生成代码


5.3 本章总结


第6章 向量数学及基本形体的点选

6.1 向量数学
6.1.1 向量的概念
6.1.2 向量的大小与方向
6.1.3 向量的加减法及几何含义
6.1.4 负向量及几何含义
6.1.5 向量与标量乘法及几何含义
6.1.6 向量标量相乘取代三角函数sin / cos的应用
6.1.7 向量的点乘及几何含义
6.1.8 向量的夹角以及朝向计算


6.2 向量投影Demo
6.2.1 Demo的需求描述
6.2.2 绘制向量
6.2.3 向量投影算法
6.2.4 投影效果演示代码
6.2.5 向量getAngle和getOrientation方法的区别


6.3 点与基本几何形体碰撞检测算法
6.3.1 点与线段以及圆的碰撞检测算法
6.3.2 点与矩形以及椭圆的碰撞检测算法
6.3.3 点与三角形的碰撞检测算法
6.3.4 点与任意凸多边形的碰撞检测算法


6.4 附录:图示代码
6.4.1 图6.1向量概念图示源码
6.4.2 图6.2 / 图6.3向量加减法图示源码
6.4.3 图6.4负向量图示源码
6.4.4 图6.5向量标量相乘图示源码
6.4.5 图6.6向量点乘图示源码
6.4.6 图6.11点与三角形的关系图示源码
6.4.7 图6.12 / 图6.13 凹凸多边形图示源码


6.5 本章总结


第7章 矩阵数学及贝塞尔曲线

7.1 矩阵数学
7.1.1 矩阵乘法
7.1.2 单位矩阵
7.1.3 矩阵求逆
7.1.4 用矩阵变换向量
7.1.5 平移矩阵及其逆矩阵
7.1.6 缩放矩阵及其逆矩阵
7.1.7 旋转矩阵及其逆矩阵
7.1.8 从两个单位向量构建旋转矩阵
7.1.9 使用makeRotationFromVectors方法取代atan2的应用
7.1.10 仿射变换
7.1.11 模拟Canvas2D中的矩阵堆栈
7.1.12 在坦克Demo中应用矩阵堆栈
7.1.13 图7.1旋转矩阵推导图示源码


7.2 贝塞尔曲线
7.2.1 Demo效果
7.2.2 使用Canvas2D内置曲线绘制方法
7.2.3 伯恩斯坦多项式推导贝塞尔多项式
7.2.4 贝塞尔曲线自绘版
7.2.5 鼠标碰撞检测和交互功能
7.2.6 实现贝塞尔曲线枚举器


7.3 本章总结


第8章 精灵系统

8.1 精灵系统架构与接口
8.1.1 精灵系统概述
8.1.2 应用程序的入口与命令分发
8.1.3 IRenderState、ITransformable以及ISprite接口
8.1.4 IDrawable、IHittable以及IShape接口


8.2 实现非场景图类型精灵系统
8.2.1 Transform2D辅助类
8.2.2 ISprite接口的实现
8.2.3 Sprite2DManager管理类


8.3 IShape形体系统
8.3.1 线段Line类
8.3.2 BaseShape2D抽象基类
8.3.3 Rect类和Grid类
8.3.4 Circle类和Ellipse类
8.3.5 ConvexPolygon类
8.3.6 Scale9Grid类
8.3.7 SpriteFactory生产IShape产品


8.4 精灵系统测试Demo
8.4.1 Demo的运行流程
8.4.2 创建各种IShape对象
8.4.3 创建网格精灵和事件处理函数
8.4.4 非网格精灵的事件处理函数
8.4.5 Demo的入口代码


8.5 本章总结


第9章 优美典雅的树结构

9.1 树数据结构
9.1.1 树结构简介
9.1.2 树节点添加时的要点
9.1.3 树节点isDescendantOf和remove方法的实现
9.1.4 实现添加树节点方法
9.1.5 树结构的层次关系查询操作


9.2 树数据结构的遍历
9.2.1 树结构遍历顺序
9.2.2 树结构线性遍历算法
9.2.3 树结构遍历枚举器
9.2.4 树结构枚举器的实现
9.2.5 测试树结构枚举器
9.2.6 深度优先的递归遍历
9.2.7 使用儿子兄弟方式递归遍历算法
9.2.8 儿子兄弟方式非递归遍历算法


9.3 树数据结构的序列化与反序列化
9.3.1 树节点自引用特性导致序列化错误
9.3.2 树节点的序列化和反序列化操作
9.4 队列与栈的实现


9.5 本章总结


第10章 场景图系统

10.1 实现场景图精灵系统
10.1.1 非场景图精灵系统的不足之处
10.1.2 树结构场景图系统
10.1.3 矩阵堆栈和场景图
10.1.4 实现场景图精灵系统概述
10.1.5 核心的SpriteNode类
10.1.6 实现SpriteNode类的接口方法
10.1.7 SpriteNode类的findSprite方法实现
10.1.8 递归的更新与绘制操作
10.1.9 SpriteNodeManager类
10.1.10 修改Sprite2D类的getWorldMatrix方法
10.1.11 让Sprite2DApplication类支持场景图精灵系统


10.2 骨骼层次精灵Demo
10.2.1 实现骨骼形体
10.2.2 SkeletonPersonTest类
10.2.3 事件处理程序
10.2.4 使用renderEvent事件
10.2.5 总结


10.3 坦克沿贝塞尔路径运动Demo
10.3.1 实现BezierPath形体类
10.3.2 需求描述
10.3.3 Demo的场景图
10.3.4 TankFollowBezierPathDemo类初始化
10.3.5 创建锚点、控制点及连线精灵
10.3.6 创建二次贝塞尔路径及坦克精灵
10.3.7 键盘事件处理方法
10.3.8 鼠标事件处理方法
10.3.9 坦克沿路径运动的核心算法
10.3.10 让坦克动起来


10.4 让精灵系统支持裁剪操作


10.5 本章总结


七、Q&A

Q1:为什么选择TypeScript语言及Canvas2D图形渲染API?

A1:选择TypeScript是因为:强类型有利于团队合作;支持面向对象、面向接口及泛型编程;可以根据预先设定转译输出为JavaScript各个标准(ES3、ES5等)。而选择Canvas2D是因为跨平台,运行方便,使用广泛,简单易学,最关键的是我们使用了TypeScript语言。

Q2:编译和转译的区别是什么?

A2:编译(Compile)通常产生可直接运行的二进制代码(例如C/C++等)或字节码(例如C# 、Java等)。而转译(Transpile)通常将一种源码转换为另外一种源码,产生的源码仍旧需要被编译或解释执行。TypeScript就是转译为JavaScript。

Q3:目前市面上有哪些主流的JavaScript引擎?

A3:JavaScript引擎是一个专门处理JavaScript脚本的解释器。目前有四大主流的、开源跨平台的、基于C++ 实现的JavaScript引擎,既Google的V8、Mozilla的SpideMonkey、WebKit的JavaScriptCore以及微软的ChakraCore引擎。

Q4:目前市面上有哪些主流的图形API?

A4:2D图形常用的API包括:Windows中的GDI/GDI+、Linux中的Cairo/Qt、macOS/iOS中的Quartz 2D、Android中的Skia以及HTML5中的Canvas2D。3D图形常用的API包括:MS DirectX、OpenGL(ES)、WebGL、Vulkan以及macOS/iOS中的Metal。

Q5:图像和图形的区别是什么?

A5:可以将图像(Image)看成一个二维像素(Pixel)数组,而像素是具有位置和色彩值的小方格。图形(Graph)则是由基本图元(Primitive)组成的,图元的全称为图形输出原语(Graphics Output Primitive),是软件包中用来描述各种图形元素(例如点,线,面,曲线,路径等)的函数。

Q6:本书所讲的内容只适合TypeScript及Canvas2D吗?

A6:本书所讲的大部分内容实际是图形相关的背景知识,和编程语言以及图形API无关。你可以很容易的将本书的知识用到其他编程语言或图形API上。编程是思想和背景知识的完美融合,而编程语言和API则是工具。

八、编者简介

九、下一步目标

· gif1.gif
gif2.gif

在TypeScript图形渲染实战(2D架构设计和实现)一书中,实现了IDoom3Tokenizer词法解析器,WebGLApplocation类以及部分的2D骨骼蒙皮动画技术,在接下来的一本书将扩展一下这些技术,来演示3D图形相关的知识。
下本书,将会继续使用安德斯海尔斯伯格的TypeScript语言来演示3D引擎之神约翰卡马克的相关技术。
每日科技英文16: 我的精神导师约翰卡马克
每日科技英文17: 我的偶像安德斯·海尔斯伯格

本书姊妹3D图形篇
上一篇下一篇

猜你喜欢

热点阅读