共计 1611 个字符,预计需要花费 5 分钟才能阅读完成。
前言
微信小游戏开放了好友关系链,使得小游戏的社交能力得到了加强,有助于增加游戏的活跃度。出于安全限制,只能在开放域使用关系链数据,但是开放域是独立的工程,使得包体变大不小,所以笔者写了一个简单的渲染核心,既保留 API 一致,占用空间也很少。
节点树结构
先模拟一个简单的节点树结构,以便使用父子这样的结构代码,符合一般的引擎风格。
function Node{
this.x = 0
this.y = 0
...
}
通用方法定义:
Node.prototype ={setPosition(x, y) {
this.x = x
this.y = y
this.isDirty = true
},
_updateWorldMatrix(){this.worldMatrix = this.parent ? matMul(this.localMatrix, this.parent.worldMatrix) : this.localMatrix
}
...
}
渲染核心
function render(){
// 重置转换矩阵
context.setTransform(1, 0, 0, 1, 0, 0);
// 清空画布
context.clearRect(0, 0, canvas.width, canvas.height);
var draw = function (node, bUpdate) {
var redraw = node.isDirty || bUpdate
if (redraw) {
// 更新变动部分的矩阵
node._updateWorldMatrix()}
// Y 轴 翻转, 向下平移一个画布高度
context.setTransform(1, 0, 0, -1, 0, canvas.height);
if (node.type) {
var t = node.worldMatrix
context.transform(t[0], t[1], t[3], t[4], t[6], t[7])
context.scale(1, -1);
}
if (node.bClip) {context.save()
// 剪裁
...
}
if (node.type == "sprite") {
// 精灵
...
}
if (node.type == "label") {
// 文字
...
}
node.children.forEach(v => draw(v, redraw))
if (node.bClip) {
// 剪裁区域绘制完,恢复画布
context.restore();}
node.isDirty = false
}
draw(scene)
}
以上是实际绘制的部分,比较多,所以只写了大概的结构,详细的请看源码链接。
引擎 2d 渲染部分原理大概是这样,看明白后,会对游戏引擎的核心部分有更加深入的理解。
触摸事件响应
由于需要制作排行榜,有些需要滚动的,那么要监听并分发触摸事件,以响应用户行为。
先做一个统一的事件分发机制:
function handleEvent(name, event) {var pt = event.changedTouches[0]
scene.forEach(child=>{if (child.getBoundingBox().contains(pt)){if (child.listener[name]) {child.listener[name](pt)
}
}
}
}
监听微信的触摸事件接口:
wx.onTouchStart(e => handleEvent("onTouchBegan", e))
wx.onTouchMove(e => handleEvent("onTouchMove", e))
wx.onTouchEnd(e => handleEvent("onTouchEnded", e))
wx.onTouchCancel(e => handleEvent("onTouchCancel", e))
小结
实际上是写了一个微小的渲染引擎,便于扩展,容易理解学习。篇幅有限,不能展示所有的细节部分,有兴趣的可以查看源码渲染核心 demo。
正文完
发表至: javascript
2019-08-05