近期出现一款魔性的消除类HTML5游戏《神奇的六边形》,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏。
(点击图片可进入游戏体验)
因内容太多,为方便大家阅读,所以分成四部分来讲解。
本文为第一部分,主要包括:
1. 功能分析
2. 创建工程与场景
3. 玩家分数管理
4. 棋盘设计与实现
5. 屏幕布局
若要一次性查看所有文档,也可点击这里。
一. 功能分析
首先分析游戏的功能点、算法和数据,然后依此制订代码组织结构。如下图:
主要功能点
- 棋盘的数据结构与绘制
- 3个形状的生成
- 形状拖拽填入棋盘
- 行消除判定与死亡判定
- 各种表现,例如消除动画、加分动画等
代码结构
将游戏逻辑(例如棋盘数据结构、死亡判定等)和界面逻辑分开,分别置于logic和ui界面。所有的UI界面交给UIManager脚本统一维护管理。
二. 创建工程与场景
创建工程Tetris和空的主场景Main,设置如下:
本工程中,画布背景(background)设置为透明
游戏入口与游戏初始化
在Scripts目录下创建文件:Tetris.js。代码如下:
/** * 游戏入口 */ window.Tetris = qc.Tetris = { // 所有的操作指令集合 operation: {} }; // 游戏逻辑初始化 qc.initGame = function(game) { // 将游戏实例记录下来,便于访问 Tetris.game = game; // 帧率显示为60帧(满帧) game.time.frameRate = 60; };
设置此脚本为入口脚本:
此脚本首先定义了名字空间,将全局的数据都记录在qc.Tetris。
游戏入口中,记录了game的实例并将帧率限定为60帧(默认在手机下为30帧)
三. 玩家分数管理
1. 创建脚本:Scripts/logic/Score.js
/** * 维护分数信息 */ var Score = qc.Tetris.Score = function() { var self = this; self._current = 0; self._best = 0; // 将本地数据读取出来 var game = qc.Tetris.game; var current = game.storage.get('current'), best = game.storage.get('best'); if (current) self._current = current; if (best) self._best = best; }; Score.prototype = {}; Score.prototype.constructor = Score; Object.defineProperties(Score.prototype, { current: { get: function() { return this._current; }, set: function(v) { this._current = v; if (this.best < v) this.best = v; } }, best: { get: function() { return this._best; }, set: function(v) { this._best = v; var storage = qc.Tetris.game.storage; storage.set('best', v); storage.save(); } } });
Score类维护了两个数据:current(当前玩家的分数)、best(玩家的历史最高分)
2. 实例化Score类
打开Tetris.js脚本,在initGame方法中,加入代码:
qc.initGame = function(game) { // 将游戏实例记录下来,便于访问 Tetris.game = game; // 帧率显示为60帧(满帧) game.time.frameRate = 60; // 初始化分数信息 Tetris.score = new qc.Tetris.Score(); };
四. 棋盘设计与实现
棋盘为一边长为5的正六变形,为了方便计算,我们如下设定棋盘的坐标系(下文称为:格子逻辑坐标):
原点在六边形中心点,半径为4。
1. 修改Tetris.js文件,增加棋盘的配置信息:
window.Tetris = qc.Tetris = { // 棋盘的大小(半径) SIZE: 4, // 棋盘中,每个格子的宽度和高度 BLOCK_W: 61, BLOCK_H: 67, // 所有的操作指令集合 operation: {} };
棋盘格子的大小 = 格子图片的大小,后续导入资源后可以看到其大小为61*67。
2. 在Scripts/logic下创建文件Board.js,维护棋盘的数据,代码如下:
var Board = qc.Tetris.Board = function() { var self = this, size = qc.Tetris.SIZE, len = qc.Tetris.BLOCK_H; // 构建用来转换格子坐标的矩阵 var m = self.m = new qc.Matrix(); m.a = len; m.c = len / 2; m.d = len * (Math.sqrt(3) / 2); // 初始化棋盘数据 self.data = {}; for (var i = -size; i <= size; i++) { for (var j = -size; j <= size; j++) { // 这些格子落在六边形外,忽略掉 if (i * j > 0 && Math.abs(i + j) > size) continue; if (i * j < 0 && (Math.abs(i) > size || Math.abs(j) > size)) continue; // 计算格子的坐标和对应屏幕上的偏移 var pos = Tetris.makePos(i, j); var pt = self.toWorld(new qc.Point(i, j)); self.data[pos] = { value: 0, x: pt.x, y: pt.y }; } } }; Board.prototype = {}; Board.prototype.constructor = Board; Object.defineProperties(Board.prototype, { /** * @property {boolean} die - 当前是否已经死亡了 * @readonly */ die: { get: function() { // TODO: 等待实现 } } }); /** * 清空棋盘 */ Board.prototype.clear = function() { for (var pos in this.data) { this.data[pos].value = 0; } }; /** * 重新开始游戏 */ Board.prototype.restart = function() { this.clear(); }; // 判定形状可以放进来不 // pos: 目标逻辑坐标 // list: 形状的信息 Board.prototype.checkPutIn = function(pos, list) { // TODO: 等待实现 }; // 把某个形状放进来 Board.prototype.putIn = function(pos, list, value) { // TODO: 等待实现 }; // 根据格子的逻辑坐标,算出所在的屏幕坐标 // distance: 两个格子中心点之间的距离 Board.prototype.toWorld = function(p, distance) { if (!distance) return this.m.apply(p); var m = new qc.Matrix(); m.a = distance; m.c = distance * 0.5; m.d = distance * (Math.sqrt(3) * 0.5); return m.apply(p); }; // 根据格子的屏幕坐标,反算格子的逻辑坐标 Board.prototype.toLocal = function(p) { return this.m.applyInverse(p); };
3. 修改Tetris.js,在qc.initGame方法中,实例化本对象:
qc.initGame = function(game) { // 将游戏实例记录下来,便于访问 Tetris.game = game; // 帧率显示为60帧(满帧) game.time.frameRate = 60; // 初始化分数信息 Tetris.score = new qc.Tetris.Score(); // 构建棋盘对象 Tetris.board = new qc.Tetris.Board(); };
同时,在本文件中实现两个函数:makePos和readPos:
// 构建坐标 window.Tetris.makePos = function(x, y) { return x + '_' + y; }; // 获取坐标 window.Tetris.readPos = function(pos) { var arr = pos.split('_'); return new qc.Point(arr[0]*1, arr[1]*1); };
五. 屏幕布局
在美术设计时,以640*960分辨率(iPhone4)进行设计,其他分辨率的屏幕需要自适应。如下图:
- 整个界面分为标题栏(Top)、棋盘(Board)、3个形状(Shape)
- Top:高度在iPhone4上为130。这里有两个信息:当前分数与历史最高分数
- Board:棋盘,其大小为600*580
- Shape:3个形状,大小为600*230,距离底部20
- 自适应方案:
- 以 640*960为基准,等比缩放,确保所有内容都能全部显示
- 当分辨率比较瘦长时(即Height/Width > 960/640)时,Board和Shape保持和底部位置不变(方便单手操作)。Top高度自动增加
- 当分辨率比较宽时(即Height/Width < 960/640)时,Board和Shape保持居中,两边留白
导入资源
-
新建文件夹:Assets/atlas/ui@atlas,将以下文件拖入并打包图集(图片请在示例工程中查看)
blue.png、cyan.png、gray.png、green.png、lightyellow.png、red.png、shadow.png、white.png、yellow.png
darkblue.png、darkcyan.png、darkgreen.png、darklightyellow.png、darkred.png、darkyellow.png等,具体请参考示例工程
格子在没有数据时,显示gray.png。其他形状的格子颜色,有6种(blue、cyan、green、lightyellow、yellow、red) -
将以下文件拖入文件夹Assets/raw(raw目录下的资源都不会被打包,例如图片直接原样保留,适用于css样式表指定资源)
blue.png、cyan.png、gray.png、green.png、lightyellow.png、red.png、yellow.png等,具体请参考示例工程,各图片的用途在后续中会说明。
界面布局
1. 创建UIRoot,并设置Reference Resolution(参考分辨率)为 640*960,Manual Type为Expand
简单的理解:设置了以后,就可以认为屏幕的宽度>=640,高度>=960
2. 创建棋盘。棋盘大部分情况下是“静态”的,只是在有新的形状放入时才会变化。如果棋盘的每个格子作为UIImage进行贴图,则每帧都需要重绘几十个格子图片,对渲染效率会有所影响。这里我们适用DOM方案,里面每个格子使用div进行绘制。因此创建一个DOM节点,设置其大小为:600*580,同时由于棋盘距离底部的位置固定,因此在布局上:水平居中、垂直距离底部250,自身中心点在底部中心位置。如下图:
3. 添加一个Node节点,挂载3个形状。Node大小为 600*230,距离底部20。如下图:
4. 创建DOM节点显示历史最高分(不常变化,因此不用UIText,使用Dom更高效)。本节点大小为200*60,距离屏幕右边20,顶部20:
5. 创建DOM节点显示当前分(不常变化,因此不用UIText,使用Dom更高效)。本节点大小为200*80,水平居中,顶部顶部29:
TO BE CONTINUED...
相关文章:
开源免费的HTML5游戏引擎——青瓷引擎(QICI Engine) 1.0正式版发布了!
相关推荐
青瓷引擎是一套开源免费的JavaScript游戏引擎类库,其基于开源免费的Phaser游戏引擎,并提供了一套完全基于浏览器的跨平台集成式HTML5游戏编辑器。 采用青瓷引擎,开发HTML5游戏和传统Web网页开发一样,使用任何...
在传媒行业周报中,我们关注了两大焦点事件,一个是曾经大受欢迎的儿童网络游戏——摩尔庄园在排行榜上的排名下滑,另一个是青瓷游戏计划在香港上市。这两件事不仅显示出游戏行业竞争的激烈性,也体现了资本市场的新...
《祖传青瓷碗》这篇小说以一个看似简单却内含深意的物件——青瓷碗,为载体,细腻地勾勒出两代人对于时代变迁的不同态度和反应。小说的字里行间透露出作者对于文化传承与时代进步的思考,引人深思。 小说伊始,作者...
【PHPWind 青瓷模板】是针对PHPWind论坛系统设计的一款主题模板,它以其独特的青瓷风格,为用户提供了优雅、简洁且富有东方韵味的界面体验。PHPWind是一款广泛应用于社区网站搭建的开源软件,它以其高效、稳定、易用...
青瓷游戏 上市招股说明书
1. 游戏行业动态:虚幻引擎技术开放日的举办,说明了游戏开发领域对于先进技术的不断追求。虚幻引擎作为一款主流的游戏开发引擎,提供了杰出的3D图形渲染能力。其在2020年的显著增长,包括产业应用、游戏客户、手游...
尤其以浙江省西南部的龙泉市烧制的青瓷——龙泉水青最为著名。龙泉水青的烧制技艺源远流长,自古以来就深受人们的喜爱与推崇,它不仅是中国传统陶瓷艺术的瑰宝,也是世界陶瓷文化中的一颗璀璨明珠。 【历史渊源】 ...
青瓷游戏上市招股说明书 港股.pdf
首先,青瓷游戏的港股上市计划是一个值得关注的焦点。青瓷游戏作为国内知名的游戏开发商,以其独特的游戏设计和良好的市场表现赢得了用户的喜爱。此次拟港股上市,预示着公司可能寻求更大的资金支持以推动业务扩张、...
报告概述了2022年中国游戏行业的新变化,特别是聚焦于港股游戏新势力——青瓷游戏的发展情况。报告指出,2021年游戏行业在政策监管日益严格的情况下,面临挑战,但也孕育着新的机遇。短期内,严格的版号审批可能导致...
本周的影视传媒行业发生了两件备受瞩目的大事:一是中国电影股份有限公司(简称“中国电影”)宣布收购CINITY,二是青瓷游戏正式递交了IPO申请。这两项事件对于整个行业的发展具有深远的影响,让我们逐一剖析。 ...
在移动互联网时代,游戏已经成为重要的娱乐形式之一,而国内游戏开发商在产品创新、IP打造和全球化战略上展现出强大的竞争力,不断推动着整个行业向前发展。 总结来看,传媒行业的这三个热点事件展示了短视频、游戏...
传媒行业在近段时间备受关注,根据最新发布的传媒周报,传媒行业有两大重要事件:一是青瓷游戏发布了招股书,计划在港股上市;二是芒果超媒的定增计划获批。青瓷游戏的上市招股说明书揭示了该公司过去几年的经营状况...
《提高区域性农产品包装形象设计的研究——以浙江中部为例》 在当今社会,农产品包装形象设计不仅关乎产品的销售,更在很大程度上影响了消费者对产品乃至整个地区的认知。浙江中部,以其丰富的农业资源和深厚的文化...
同时,“青瓷游戏港股交表”表明青瓷游戏公司正在寻求在资本市场上的进一步发展,具体操作为向香港联合交易所提交了首次公开募股(IPO)的申请,这对于了解游戏公司在资本市场的发展动态具有重要意义。“《梦幻新诛仙...
1. 传媒行业数据分析:该周报提供了2021年第26周传媒行业的数据,详细分析了行业的投资机会和趋势。报告指出,投资机会主要来自三个方面:产业大演进周期、新渠道崛起、商业模式升级和品类矩阵扩充。 2. 产业大演进...
### 馆藏高丽青瓷的时间及相关知识点 #### 一、高丽青瓷概述 高丽青瓷作为韩国古代陶瓷艺术的杰出代表之一,以其独特的制作工艺、精美的装饰艺术以及深厚的历史文化内涵闻名于世。根据提供的文档资料,我们可以...
影视传媒行业周报:中国电影收购CINITY,青瓷游戏递交IPO申请.pdf
传媒行业周报:摩尔庄园排名下滑,青瓷游戏拟赴港IPO.pdf