标签:
这是公司的一个h5游戏项目,找茬的游戏相信大家都玩过不多说了上图。
游戏过程:开始游戏 -> 找茬 -> 游戏结束
具体需求:游戏有5个不同点,需要在30秒内找到,找错3次或时间耗尽则失败。
拿到这个项目后我首先分析,是用canvas游戏引擎做,还是用dom+js+css3来做,毕竟后者开发速度以及游戏大小来说更优。因为操作dom比较少,无非是隐藏显示和简单的动画效果,不会太耗性能,所以我选择了后者。
操作dom肯定要请出jquery这个老将,加上require来做模块化和依赖加载,再写一些css3的动画效果,好了,整个项目的架构有了:
项目名称:quickspot
css文件夹:loading.css进度条动画、main.css样式主文件
data文件夹:gamecfg.json游戏配置、res.json游戏资源
img图片文件夹
js文件夹:ajax.js与后台通信、event.js游戏事件、game.js游戏主文件、res.js游戏预加载
根目录的index.html是游戏入口文件,main.js是依赖加载的主配置文件
本文主要是以架构和面向对象的编程思想来讲解,一些基础的东西跳过,比如css3、require的使用,不会的朋友可以看这方面的教程,接下来我逐步分析每一个文件。
main.js不多说了,就是文件依赖的一些配置操作。懂require的朋友一眼就明白啦。
‘use strict‘; (function (win) { //配置baseUrl var baseUrl = document.getElementById(‘main‘).getAttribute(‘data-baseurl‘); /* * 文件依赖 */ var config = { baseUrl: baseUrl, //依赖相对路径 paths: { //如果某个前缀的依赖不是按照baseUrl拼接这么简单,就需要在这里指出 ‘jquery.mousewheel‘: ‘libs/jquery.mousewheel‘, ‘jquery‘: ‘libs/jquery1.12.0.min‘, ‘esmere‘: ‘libs/esmere‘, ‘game‘: ‘js/game‘, ‘ajax‘: ‘js/ajax‘, ‘event‘: ‘js/event‘, ‘res‘: ‘js/res‘ }, shim: { //引入没有使用requirejs模块写法的类库。 ‘jquery‘: { exports: ‘$‘ }, ‘jquery.mousewheel‘: { deps: [‘jquery‘] }, ‘esmere‘: { deps: [‘jquery‘,‘jquery.mousewheel‘], exports: ‘esmere‘ }, ‘game‘: { deps: [‘esmere‘] }, ‘ajax‘: { deps: [‘esmere‘] }, ‘event‘: { deps: [‘esmere‘,‘game‘,‘ajax‘] }, ‘res‘: { deps: [‘esmere‘,‘game‘,‘event‘] } } }; require.config(config); //esmere会把自己加到全局变量中 require([‘esmere‘,‘res‘], function(esmere,res){ }); })(this);
index.html也没啥好说的,因为不是重点代码有点乱,主要看一下游戏的html结构就行。
<!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="full-screen" content="yes"/> <meta name="screen-orientation" content="portrait"/> <meta name="x5-fullscreen" content="true"/> <meta name="360-fullscreen" content="true"/> <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> <title>大家来找茬</title> <style> body, canvas, div { -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; -khtml-user-select:none; -webkit-tap-highlight-color:rgba(0, 0, 0, 0); } body{margin:0px;padding:0px;} div, p, ul, ol, dl, dt, dd, form{padding:0;margin:0;list-style-type:none;} img{border:0;} </style> <link href="css/loading.css" rel="stylesheet" type="text/css" /> <link href="css/main.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> if(/Android (\d+\.\d+)/.test(navigator.userAgent)){ var version = parseFloat(RegExp.$1); if(version>2.3){ var phoneScale = parseInt(window.screen.width)/640; document.write(‘<meta name="viewport" content="width=640, minimum-scale = ‘+ phoneScale +‘, maximum-scale = ‘+ phoneScale +‘, target-densitydpi=device-dpi,user-scalable=no">‘); }else{ document.write(‘<meta name="viewport" content="width=640, target-densitydpi=device-dpi,user-scalable=no">‘); } }else{ document.write(‘<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">‘); } </script> </head> <body> <div class="main"> <div class="life"></div> <div class="time"> <ul class="s1"></ul> <ul class="s2"></ul> </div> <div class="game"> <ul></ul> </div> <div class="mask"></div> <div class="start"> <ul class="text"></ul> <ul class="btn play"></ul> </div> <div class="over"> <ul class="title"></ul> <ul class="btn replay"></ul> <ul class="btn share"></ul> <ul class="btn go"></ul> </div> </div> <div id="heng" style="z-index:1000;position:absolute;display:none"><img src="img/2.png"></div> </body> <script> //判断手机横竖屏状态 //http://www.w3cways.com/1772.html var getOrient = function(){ if (window.orientation != undefined) { return window.orientation % 180 == 0 ? "portrait": "landscape" } else { return (window.innerWidth > window.innerHeight) ? "landscape": "portrait" } }; var heng = document.getElementById(‘heng‘); if(getOrient() == "portrait"){ //console.log(‘竖屏状态!‘); heng.style.display = ‘block‘; }else{ //console.log(‘横屏状态!‘); } //判断手机横竖屏状态: window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function() { if(getOrient() == "portrait"){ //console.log(‘竖屏状态!‘); }else{ //console.log(‘横屏状态!‘); heng.style.display = ‘none‘; } }, false); </script> <script data-baseurl="./" data-main="main.js" src="libs/require.js" id="main"></script> </html>
data文件夹是存放游戏的配置文件,比如游戏的生命值、时间、子弹数量等属性,以及游戏中所用的图片链接地址。可能有的人会说我直接写在js代码里面也可以啊,这么小的项目有必要搞这么复杂吗,的确这样做也是可以的而且很多人都是这样干的,但是这样做并不规范,游戏开发应尽量避免出现硬编码。如果客户改变需求,我们不需要去js代码中寻找,仅仅在配置文件中修改一个值即可。好了,说了这么多,我们来看下配置文件的内容吧。
res.json有2个属性,分别为image和cfg,image保存了图片名字和图片路径,cfg保存了游戏配置文件的名称和路径
{ "image":[ {"name":"main","src":"img/main.png"}, {"name":"bingo","src":"img/bingo.png"}, {"name":"bingo2","src":"img/bingo2.png"}, {"name":"fail","src":"img/fail.png"}, {"name":"number","src":"img/number.png"}, {"name":"start","src":"img/start.png"}, {"name":"text","src":"img/text.png"}, {"name":"title1","src":"img/title1.png"}, {"name":"title2","src":"img/title2.png"}, {"name":"replay","src":"img/replay.png"}, {"name":"share","src":"img/share.png"}, {"name":"go","src":"img/go.png"}, {"name":"layer","src":"img/layer.png"} ], "cfg":[ {"name":"gf0","src":"data/gamecfg.json"} ] }
gamecfg.json 我分析一下各属性的含义:
time:游戏时间
life:剩余机会
rect:游戏中5个不同点的坐标和宽高以及classname
fail:游戏中找错了会显示一个叉,它也有宽高以及classname
number:数字用于游戏中的时间和剩余机会
link:游戏结束后的跳转链接地址
{ "time":30, "life":3, "rect":[ {"w":68,"h":68,"x":378,"y":124,"name":"bingo"}, {"w":73,"h":73,"x":40,"y":208,"name":"bingo"}, {"w":64,"h":64,"x":40,"y":386,"name":"bingo"}, {"w":58,"h":58,"x":109,"y":439,"name":"bingo"}, {"w":44,"h":280,"x":362 ,"y":400,"name":"bingo2"} ], "fail":{"w":33,"h":33,"name":"fail"}, "number":{"w":29,"h":33}, "link":"http://www.baidu.com" }
dfhdfhdfh
标签:
原文地址:http://www.cnblogs.com/gongshunkai/p/5892107.html