近期出现一款魔性的消除类HTML5游戏《神奇的六边形》,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏。
(点击这里可进入游戏体验)
因内容太多,为方便大家阅读,所以分成八部分来讲解。
本文为第三部分,主要包括:
10. 形状预制的实现
11.显示出3个形状
若要一次性查看所有文档,也可点击这里。
十. 形状预制的实现
本章节我们进行形状的绘制实现,如下图:
1. 在UIRoot/pool节点下,创建一空的Node节点,设置如下图
定位在父亲的中心点
大小为200*100
pivot设置为:(0.5, 0.5)
本对象需要可以交互(需要被拖放),勾选Interactive。并设置碰撞盒类型为Rectangle(正方形),按图示设置大小(碰撞盒大小会比节点实际大小更大)
2.在Scripts/ui创建文件BlocksUI.js
/** * 绘制一个形状 */ var BlocksUI = qc.defineBehaviour('qc.tetris.BlocksUI', qc.Behaviour, function() { var self = this; // 格子的预置,一个形状下有多个格子 self.blockPrefab = null; // 下属所有的格子 self._blocks = {}; }, { blockPrefab: qc.Serializer.PREFAB }); Object.defineProperties(BlocksUI.prototype, { /** * 关联的数据 */ data: { get: function() { return this._data; }, set: function(v) { this._data = v; this.redraw(); } }, /** * 第几个? */ index: { get: function() { return this.gameObject.parent.getChildIndex(this.gameObject); } } }); /** * 初始化 */ BlocksUI.prototype.awake = function() { // 点击时的偏移量 var self = this; self.offsetY = self.game.device.desktop ? 0 : 50; }; /** * 重新绘制区块 */ BlocksUI.prototype.redraw = function() { var self = this; var frame = qc.Tetris.IMAGES[self.data.value]; self.data.list.forEach(function(pos) { var x = pos[0], y = pos[1]; var block = self.game.add.clone(self.blockPrefab, self.gameObject); block.find('block').frame = frame + '.png'; block.name = x + '_' + y; self._blocks[qc.Tetris.makePos(x, y)] = block; }); self.reset(); }; /** * 重设区块大小和排列下属格子的位置 */ BlocksUI.prototype.reset = function() { var self = this, o = self.gameObject; for (var pos in self._blocks) { var p = qc.Tetris.readPos(pos); var pt = qc.Tetris.board.toWorld(p, qc.Tetris.POOL_DISTANCE_NORMAL); var block = self._blocks[pos]; block.anchoredX = pt.x; block.anchoredY = pt.y; } };
本脚本根据形状的数据,动态创建出格子并显示出来
blockPrefab为格子的预置,后续步骤创建
形状的大小会比棋盘中显示小,因此计算格子的屏幕坐标时,指明了常量:qc.Tetris.POOL_DISTANCE_NORMAL
在初始化时,设置了非PC模式下需要做偏移为50。(在手机上拖拽时方式被手指完全挡住,从而看不清形状)
3. 修改Tetris.js,加入POOL_DISTANCE_NORMAL配置:
window.Tetris = qc.Tetris = { // 棋盘的大小(半径) SIZE: 4, // 棋盘中,每个格子的宽度和高度 BLOCK_W: 61, BLOCK_H: 67, // 没有点击时,格子之间的距离 POOL_DISTANCE_NORMAL: 45, ...
4.在上述Blocks节点下,创建空的节点Node,名字修改为block2,属性为:
· 相对于父亲居中显示
· pivot=(0.5, 0.5)
5. 在block2节点下,创建Image节点,名字修改为shadow,属性设置如下:
相对于父亲居中显示
pivot=(0.5, 0.5)
大小为60*65
使用ui图集
6. 在block2节点下,创建Image节点,名字修改为block,属性设置如下:
相对于父亲居中显示
pivot=(0.5, 0.5)
大小为40*45
使用ui图集
至此,你的场景应该是:
7. 将block2节点拖入到目录Assets/prefab,创建预置。然后将节点从场景中删除。
8. 将BlocksUI.js挂载到Blocks节点,并设置blockPrefab的值为上步骤创建的预制。设置完成后,将此节点拖入Assets/prefab目录,创建预置。
9. 至此,形状的预置创建完毕了
1. 在Scripts/ui创建文件:Pool.js,绘制3个形状。
var s = qc.Serializer; /** * 3个形状的绘制 */ var Pool = qc.defineBehaviour('qc.tetris.Pool', qc.Behaviour, function() { var self = this; /** * 形状的预置 */ self.blocksPrefab = null; /** * 记录下面3个形状的实例 */ self.shapes = []; }, { blocksPrefab: s.PREFAB }); /** * 初始化处理 */ Pool.prototype.awake = function() { var self = this; self.redraw(); }; /** * 绘制3个形状 */ Pool.prototype.redraw = function() { var self = this; // 先干掉旧的形状数据 for (var i = 0; i < self.shapes.length; i++) { self.shapes[i].destroy(); } self.shapes = []; // 创建3个新的形状 for (i = 0; i < 3; i++) { self.add(i); } self.resize(); }; /** * 调整位置 */ Pool.prototype.resize = function() { var self = this, o = self.gameObject; // 计算X方向的偏移 var offset = o.width * (0.5 - 0.165); for (var i = 0; i < 3; i++) { var child = self.shapes[i]; if (!child) return; child.anchoredX = offset * (i - 1); child.anchoredY = 0; } }; /** * 添加一个形状 */ Pool.prototype.add = function(index) { var self = this; var o = self.game.add.clone(self.blocksPrefab, self.gameObject); var c = o.getScript('qc.tetris.BlocksUI'); c.data = qc.Tetris.Shapes.pool[index]; self.shapes[index] = o; }; /** * 删除一个形状 */ Pool.prototype.remove = function(index) { var o = this.shapes[index]; o.destroyImmediately(); this.shapes.splice(index, 1); };
整个代码逻辑比较简单,根据3个形状的数据进行绘制。请参考注释进行理解。
2. 将此脚本挂载到UIRoot/pool节点,关联blocksPrefab属性:
3. 运行测试下效果,3个形状正确显示了:
上一篇:JS开发HTML5游戏《神奇的六边形》(二)
下一篇:JS开发HTML5游戏《神奇的六边形》(四)