近期出现一款魔性的消除类HTML5游戏《神奇的六边形》,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏。

(点击图片可进入游戏体验)

因内容太多,为方便大家阅读,所以分成四部分来讲解。

本文为第四部分,主要包括:

16.分数往上飘动画

17.形状飞入动画

18.其他动画表现添加

19.游戏结束界面

20. 添加LOGO

21. 渲染优化

若要一次性查看所有文档,也可点击这里。

十六. 分数往上飘的动画

在表现加分时,分数会有个缩放的效果,然后往上移动并淡出。这些效果可以通过Tween Group来组合实现。

1. 在board节点下,创建UIText节点,取名为score,属性设置如下:

  • 文本居中显示
  • 文本颜色为白色,大小40,外加6像素描边

2. 为score节点,添加TweenScale组件,控制缩放动画,属性设置如下图(注意设置Tween Group=1):

3. 为score节点,添加TweenPosition组件,控制节点向上移动,属性设置如下图(注意设置Tween Group=1):

4. 为score节点,添加TweenAlpha组件,控制节点淡出,属性设置如下图(注意设置Tween Group=1):

5. 将score节点拖拽到Assets/prefab目录,创建预制。然后从场景中删除。

6. 在Scripts/ui下新建脚本:FlyScore.js

/*** 分数飘出来的特效*/var FlyScore = qc.defineBehaviour('qc.tetris.FlyScore', qc.Behaviour, function() {var self = this;}, {scorePrefab: qc.Serializer.PREFAB});/*** 开始播放冒分数动画*/FlyScore.prototype.play = function(pos, score) {var self = this;var scoreOb = self.game.add.clone(self.scorePrefab, self.gameObject);scoreOb.text = '' + score;var tp = scoreOb.getScript('qc.TweenPosition');scoreOb.anchoredX = qc.Tetris.board.data[pos].x;scoreOb.anchoredY = qc.Tetris.board.data[pos].y;tp.from = new qc.Point(scoreOb.x, scoreOb.y);tp.to = new qc.Point(tp.from.x, tp.from.y - 80);tp.resetGroupToBeginning();tp.playGroupForward();self.game.timer.add(600, function() {scoreOb.destroy();});};

7. 将FlyScore脚本挂载到board节点,设置scorePrefab属性为Assets/prefab/score.bin。保存场景。

十七. 形状飞入动画

1. 双击Assets/prefab/Blocks.bin,编辑预制

2. 选中Blocks节点,添加TweenPosition组件,属性设置如下:

3. 保存预置

4. 打开Scripts/ui/Pool.js,添加flyIn接口,处理飞入动画的播放

/*** 播放飞入的动画*/Pool.prototype.flyIn = function(index) {var self = this, o = self.gameObject, children = o.children;var offset = o.width * (0.5 - 0.165);// 先确保位置都正确self.resize();if (index === 0) {var o = children[0], c = o.getScript('qc.tetris.BlocksUI');c.flyIn(offset);}if (index === 0 || index === 1) {var o = children[1], c = o.getScript('qc.tetris.BlocksUI');c.flyIn(offset);}var o = children[2], c = o.getScript('qc.tetris.BlocksUI');c.flyIn(offset);};

5. 打开Scripts/ui/BlocksUI.js,添加flyIn接口,处理单个形状飞入动画

/*** 飞入动画*/BlocksUI.prototype.flyIn = function(offset) {var self = this,tp = self.getScript('qc.TweenPosition');tp.delay = 0.5;tp.to = new qc.Point(self.gameObject.x, self.gameObject.y);tp.from = new qc.Point(tp.to.x + offset, tp.to.y);tp.resetToBeginning();tp.playForward();};

6. 运行游戏,查看下效果:已经可以正常游戏了不是?

十八. 其他动画表现添加

目前还缺少两个表现:加分动画(数字跳动)、形状回弹效果。其方法和之前讲述的大致一样,这里简略做个说明。

加分动画

1. 修改CurrentScore.js代码,添加动画播放代码:

var CurrentScore = qc.defineBehaviour('qc.tetris.CurrentScore', qc.Behaviour, function() {var self = this;self.runInEditor = true;}, {});/*** 初始化处理*/CurrentScore.prototype.awake = function() {var self = this, div = self.gameObject.div;div.className = 'score_current';self.setScore(qc.Tetris.score.current);};/*** 更新最新的高分*/CurrentScore.prototype.setScore = function(best) {best = best || qc.Tetris.score.current;// 做动画表现,从old -> bestvar old = this.gameObject.div.innerHTML * 1;this.delta = best - old;if (this.delta <= 0)this.gameObject.div.innerHTML = '' + best;// 0.2s内需要播放完毕,计算每秒增加的数量this.step = this.delta / 0.2;// 播放缩放动画var ts = this.getScript('qc.TweenScale');ts.resetToBeginning();ts.playForward();};/*** 动画表现*/CurrentScore.prototype.update = function() {if (this.delta <= 0) {// 动画表现完毕了return;}var step = Math.round(this.step * this.game.time.deltaTime / 1000);this.delta -= step;var old = this.gameObject.div.innerHTML * 1 + step;if (old > qc.Tetris.score.current) {old = qc.Tetris.score.current;this.delta = 0;}this.gameObject.div.innerHTML = '' + old;};

2. 为场景节点UIRoot/score添加TweenScale组件,属性设置如下:

形状回弹效果

修改BlocksUI.js代码,添加backAni方法:

/*** 退回到原来位置的动画表现*/BlocksUI.prototype.backAni = function(x, y) {var self = this, o = self.gameObject,tp = self.getScript('qc.TweenPosition');if (tp.enable) return;tp.delay = 0;tp.from = new qc.Point(x, y);tp.to = new qc.Point(self.gameObject.x, self.gameObject.y);tp.stop();tp.resetToBeginning();self.gameObject.interactive = false;tp.onFinished.addOnce(function() {self.gameObject.interactive = true;o.parent.getScript('qc.tetris.Pool').resize();});tp.playForward();};

在onDragEnd方法中,当无法放入棋盘的分支中,加入backAni的调用:

 BlocksUI.prototype.onDragEnd = function(e) {var self = this,o = self.gameObject;self.drag = false;if (self.flagBlocks.visible && self.lastPos) {// 放到这个位置中去self.drop = true;qc.Tetris.operation.putIn(self.index, self.lastPos, self.data);}else {// !!!!!!// 在这个分支中修改为如下代码var x = o.x, y = o.y;self.reset();o.parent.getScript('qc.tetris.Pool').resize();self.backAni(x, y);}// 显示标记可以干掉了self.flagBlocks.destroy();delete self.flagBlocks;};

十九. 游戏结束界面

游戏界面包含2个页面:

 

这两个页面使用html+css元素快速搭建(DOM节点)。步骤如下:

1. 在UIRoot下创建Dom节点,取名GameOver

  • 居中显示,大小为340*441
  • 缩放1.5倍
  • 设置节点可以交互(碰撞范围非常大,这样底部游戏所有的元素都无法接收事件了)
  • 设置className=gameover

2. 在Scripts/ui下新建脚本:GameOverUI.js

/*** 游戏结束界面*/var GameOverUI = qc.defineBehaviour('qc.tetris.GameOverUI', qc.Behaviour, function() {var self = this;qc.Tetris.gameOver = self;self.runInEditor = true;}, {shareClue: qc.Serializer.PREFAB});GameOverUI.prototype.awake = function() {var div = this.gameObject.div;var score = qc.Tetris.score.current;var percent = 40;this.rawHtml ='<div class="gameover_title">Game Over</div>' +'<div class="gameover_score">__SCORE__</div>' +'<div class="gameover_pos">你击败了全球__PERCENT__%的玩家</div>' +'<div class="gameover_desc">让朋友们来膜拜大神吧!</div>' +'<div class="gameover_share" οnclick="qc.Tetris.gameOver.share()" ontouchstart="qc.Tetris.gameOver.share()">马上告诉他们</div>' +'<div class="gameover_restart" οnclick="qc.Tetris.gameOver.restart()" ontouchstart="qc.Tetris.gameOver.restart()">再玩一次</div>' +'<div class="gameover_act">' +'    <div class="gameover_logo"></div><div class="gameover_act_desc">点击关注送好礼</div> ' +'</div>' +'<div class="clear"></div>';this.rawHtml = this.rawHtml.replace('__SCORE__', '' + score);this.rawHtml = this.rawHtml.replace('__PERCENT__', '' + percent);div.innerHTML = this.rawHtml;};GameOverUI.prototype.onDestroy = function() {delete qc.Tetris.gameOver;};GameOverUI.prototype.share = function() {// 打开share界面this.game.add.clone(this.shareClue, this.gameObject.parent);};GameOverUI.prototype.restart = function() {this.gameObject.destroy();qc.Tetris.operation.restart();};

本界面主要通过内置的DOM来进行处理,具体不多作解释(您需要有一定的web前端开发基础)

1. 打开Assets/css/style.css,添加如下样式表:

/* Game Over */.gameover {text-align: center;width: 100%;font-family: arial, sans serif;background: url("../raw/bg.png") no-repeat;color: #000000;}.gameover_title {font-size: 40px;margin-top: 10px;height: 50px;text-align: center;}.gameover_score {font-size: 90px;margin-top: -15px;height: 98px;text-align: center;}.gameover_pos {text-align: center; font-size: 28px;height: 40px;}.gameover_desc {text-align: center; color: #ffffff;height: 30px; font-size: 20px; line-height: 100%;}.gameover_share {background: url("../raw/btn_blue.png") center no-repeat;height: 76px;line-height: 76px;font-size: 30px;color: #ffffff;text-align: center;}.gameover_restart {background: url("../raw/btn_yellow.png") center no-repeat;text-align: center; color: #ffffff;height: 76px;line-height: 76px;font-size: 30px;margin-top: 10px;}.gameover_logo {float: left;background: url("../raw/logo.png") no-repeat;width: 64px;height: 62px;margin: 8px 0px 0px 2px;}.gameover_act_desc {color: #ffffff;float: right;width: 250px;text-align: left;height: 62px;line-height: 62px;margin-top: 8px;font-size: 28px;}.clear { clear: both; }

2. GameOverUI.js脚本挂载到GameOver对象,刷新查看下效果。

3. 将GameOver节点拖拽到Assets/prefab下,创建预制。然后从场景中删除。游戏结束界面就完成了。下面构建分享页面

4. 在UIRoot下新建Dom节点:shareClue,参数设置如下:

大小设置为铺满整个屏幕,className=share

5.在shareClue新建Dom节点:arraw,用来显示箭头,定位为右上角,参数设置如下:

6. 在shareClue新建Dom节点:desc,用来显示提示语内容。参数设置如下:

7. 在Scripts/ui新建文件ShareClue.js

/*** 分享提示页面*/var ShareClue = qc.defineBehaviour('qc.tetris.ShareClue', qc.Behaviour, function() {var self = this;self.runInEditor = true;}, {descNode: qc.Serializer.NODE});/*** 初始化*/ShareClue.prototype.awake = function() {this.descNode.div.innerHTML = '请点击右上角<br/>分享给您的好友吧<br/>看下他们能取得多少分';};/*** 点击时干掉本页面*/ShareClue.prototype.onClick = function() {this.gameObject.destroy();};

8. 将ShareClue脚本挂载到shareClue节点上,设置Desc Node为下面的desc节点

9. 编辑Assets/css/style.css,添加样式表:

/* 分享提示 */
.share {background-color: #000000;opacity:0.5;filter:alpha(opacity=50);text-align: center; color: #ffffff;
}
.share_clue {background-image: url("../raw/arrows.png");
}
.share_desc {color: #ffffff; font-size: 60px; text-align: center;line-height: 70px;
}

10. 保存场景并刷新之,查看效果。

11. 将shareClue拖拽到Assets/prefab,创建预置,然后从场景中删除。

12. 选中UIRoot节点,设置UIManager组件的gameOverPrefab=Assets/prefab/GameOver.bin

13. 双击Assets/prefab/GameOver.bin编辑预置,设置shareClue = Assets/prefab/shareClue.bin

14. 打开Scripts/logic/Board.js,补齐死亡逻辑:

Object.defineProperties(Board.prototype, {/*** @property {boolean} die - 当前是否已经死亡了* @readonly*/ die: {get: function() {// 如果有单个点形状的,一定死不了var pool = qc.Tetris.Shapes.pool;for (var i = 0; i < pool.length; i++) {if (pool[i].list.length === 1) return false;}// 逐一检查,各形状能否扔来进来for (var pos in this.data) {for (var i = 0; i < pool.length; i++) {if (this.checkPutIn(pos, pool[i].list)) return false;}}return true;}}
});

15. 在Scripts/operation创建脚本Restart.js,处理重新开始游戏的逻辑:

/*** 请求重新开始游戏*/
qc.Tetris.operation.restart = function() {var game = qc.Tetris.game,ui = game.ui;// 清空棋盘信息qc.Tetris.board.restart();// 当前分数清0qc.Tetris.score.current = 0;// 3个形状重新替换掉qc.Tetris.Shapes.restart();// 界面初始化ui.restart();
};

16. 游戏的整体逻辑已经完成,测试看看

二十. 添加Logo

具体请自行参考工程理解,涉及的场景节点有:UIRoot/logo和UIRoot/company
涉及的脚本有:Scripts/ui/Company.js
涉及的样式表:

 /* logo */.logo {background-image: url("../raw/qici.png");}.company {color:#ffffff;font-size: 24px;}

二十一. 渲染优化

本游戏,使用图片比较少,并且大部分都采用DOM的方式渲染,非常高效。
唯一可以做优化的是3个形状:每个形状下面挂载了多个格子节点,并且大部分时间是保持不变的,因此可以将这些格子节点缓存到canvas以提升渲染效率(多耗了点内存)。步骤如下:

1. 双击Assets/Prefab/Blocks.bin编辑预置,在预置根节点添加内置组件:CacheAsBitmap,设置属性如下图:

这个组件的用途是将节点渲染到独立的canvas上并缓存起来。

2. 保存预制。当内部的格子发生变化时,需要“设脏”(确保缓存能被刷新)。打开BlocksUI.js,在reset方法最后面加入:

self.getScript('qc.CacheAsBitmap').dirty = true;

添加帧率查看

在UIRoot挂载Dom节点:debug,属性设置如下:

2. 编辑style.css,添加样式表:

.debug { color:green; font-size:18px; }

3. 为debug挂载内置脚本:DebugViewer,刷新下页面,就可以查看帧率情况了:

其中,FPS为游戏实际运行帧率;Total为游戏一次主循环所使用的时间;Logic为游戏逻辑损耗的时间(即Preupdate、Update等),Render为渲染时间。

4. 在最终发布时,需要将debug隐藏掉

    《神奇的六边形》 到此就分享完毕了,感谢各位的耐心阅读,若发现问题,还请大家及时指出,帮助我们不断完善。以后还将陆续分享其他好游戏的开发经验,望大家继续关注,谢谢!

相关文章:

青瓷引擎打造HTML5游戏第一弹——《神奇的六边形》Part 1

开源免费的HTML5游戏引擎——青瓷引擎(QICI Engine) 1.0正式版发布了

青瓷引擎打造HTML5游戏第一弹——《神奇的六边形》Part 4相关推荐

  1. 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 3

    继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...

  2. 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 7(服务器连接数据处理)...

    继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...

  3. 关于『HTML5』第一弹

    关于『HTML5』:第一弹 建议缩放90%食用 祝各位国庆节快乐!!1

  4. html 游戏引擎 白鹭,HTML5游戏性能大幅提升 白鹭Egret Engine 1.5震撼发布

    近日,白鹭时代发布了***一代的Egret Engine 1.5移动游戏引擎,其中备受行业关注的全新物理系统与WebSocket,随着新版引擎的发布与开发者见面.全新的Egret Engine 1.5 ...

  5. Phaser开源2d引擎 javascript/html5游戏框架

    功能特点(Features) 易维护代码(Easy Asset Loading) Phaser可以加载图片,音频文件,数据文件,文本文件和自动解析精灵图和纹理地图集数据(出口纹理封隔器或Flash C ...

  6. 基于引擎开发HTML5游戏实战(一)---游戏引擎

    最近从一个技术沙龙活动中了解到一个游戏引擎(construct2), 这款引擎彻底地改变了游戏开发在我心目中的印象.以前看过一些游戏开发的书籍,基本上都是从canvas,从坐标系讲起,再加上复杂地绘图 ...

  7. LUAT游戏第一弹---贪吃蛇

    文章目录 前言 准备工作 硬件准备 软件准备 开始制作 游戏制作 前言 开个新系列,基于LUAT制作小游戏 准备工作 硬件准备 1,准备724,724等能运行luat的开发版 2,矩阵键盘 软件准备 ...

  8. 基于引擎开发HTML5游戏实战(二)---游戏剧本

    STEP2 设计游戏情节 体验基于引擎开发游戏之后,让我深切感受到,游戏=情节+美工+引擎,编程技术在里面不是决定性因素.一个游戏成功与否很关键的一点是导演和编剧,这和电影电视很类似.当然,两个小时之 ...

  9. PYTHON小游戏(第一弹)————神秘单词

    系列文章目录 壹.输入输出实现猜词游戏 目录 系列文章目录 前言 一.实现思路 二.源码分享 1.英文单词 2.汉字成语 三.试玩截图 前言 根据提示猜词能够锻炼自己的语言能力,今天我们就仿照网上的猜 ...

最新文章

  1. RNN,LSTM,GRU简单图解:
  2. 超详细中文预训练模型ERNIE使用指南
  3. C++ 虚函数个人理解
  4. 数据库优化之统计分析实战篇
  5. 项目进度管理:排列活动顺序
  6. 前端学习(2907):Vite的特点
  7. cudaMemset的调用方式
  8. Kubernetes 搭建 ES 集群(存储使用 local pv)
  9. Android Framework 全面分析 SystemServer
  10. eclipse中安装Tomcat
  11. 快慢指针在数组中的应用
  12. jsp:setProperty getProperty标签的使用
  13. 推荐几个很好的资源下载网站
  14. RTP协议全解析(H264码流和PS流)
  15. Windows10远程登陆Ubuntu桌面
  16. 戴尔游匣7559-拆机磁盘换固态详解
  17. Google(谷歌)正在构造可怕的帝国
  18. spark-面试题(含答案)
  19. 二进制bit0是什么意思_阜平吧在讨论5G的问题,感觉挺有意思,科普下……
  20. 2020年汽车驾驶员(中级)模拟考试题及汽车驾驶员(中级)考试软件

热门文章

  1. 游戏编程之常用设计模式
  2. 【2022版】 Java基础面试题整理(含答案解析)
  3. Linux虐我千百遍,我待linux如初恋
  4. 微信扫描二维码安卓弹出默认浏览器(苹果打开App Store)打开下载链接
  5. 开源系统搭建私有云盘,育网校园云盘系统
  6. 2019牛客暑期多校训练营(第一场)B Integration 裂项相消 + 积分
  7. android 测试机 怎么root,Android 应用安全 - 检测设备是否Root
  8. 让你熟悉 from gne import GeneralNewsExtractor是怎么样的
  9. 动态域名搭建exchang邮箱服务器
  10. TIOBE 2012年9月编程语言排行榜:C语言老当益壮