您的位置:首页 > Web前端 > JavaScript

JS开发HTML5游戏《神奇的六边形》(一)

2015-11-12 00:00 971 查看
摘要: 本文主要介绍如何使用青瓷引擎(www.zuoyouxi.com)开发一款魔性消除类HTML5游戏《神奇的六边形》近期出现一款魔性的消除类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();}}});
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。修改Tetris.js文件,增加棋盘的配置信息:
window.Tetris = qc.Tetris = {// 棋盘的大小(半径)SIZE: 4,// 棋盘中,每个格子的宽度和高度BLOCK_W: 61,BLOCK_H: 67,// 所有的操作指令集合operation: {}};
棋盘格子的大小 = 格子图片的大小,后续导入资源后可以看到其大小为61*67。在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*/&nb7fe8sp;   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);};
修改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*580Shape: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.pngdarkblue.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,高度>=9602. 创建棋盘。棋盘大部分情况下是“静态”的,只是在有新的形状放入时才会变化。如果棋盘的每个格子作为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:[b]下一篇:JS开发HTML5游戏《神奇的六边形》(二)[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息