一张H5游戏页引起的思考
最近开发了一个移动端的端午活动页面,做完后就想写点东西总结一下,感受最深的就是打草稿。
刚开始并没有打草稿,直接开干,越做到后面就越觉得代码很乱很杂,非常不舒服,做到哪个页面写这个页面的CSS,没有大局观。
在完成页面后,就思考了一下,觉得打草稿是个好习惯,磨刀不误砍柴工。
打草稿的步骤如下:
1)margin、padding的大致值记录
2)字体的配色与尺寸
3)图片的切割,哪些比较适合单个的切割,哪些比较适合合成起来
4)通用组件的提取,包括按钮、弹出层、Loading、输入框、以及表格
5)小工具样式的搜集,例如居左居右等
6)CSS3动画实现
7)页面中的难点分析,功能的主次实现排序
一、总览
上图是这个活动的总览。页面其实就五张半,通过这几张图,可以先打打草稿。
1)margin与padding,说的具体点可以是布局的分析,例如上面的“点击继续”、“再玩一次”、“朕知道了”这几个按钮的边距,肯定是左右居中的。
2)大致看了下字体有7种颜色,10种字体大小,如果使用SASS,可以将颜色和字体大小设置为合适的变量,方便引用
3)活动页面最多的就是图片了,像“选择战队”和“成绩排名”的背景图就是同一个,可以复用,四个Logo图标可以组成一张合成图,我比较喜欢将相同功能的图片做成合成图,而不是全部合在一起,不过实际情况实际分析。
4)大概有4种按钮,可以抽象出一个“btn”样式,与不同的按钮组合使用,2种弹出层,Loading、输入框、以及表格都是1种。
5)大概有4种动画,渐显、放大、滑动、上下浮动等。
6)此次活动的难点就是第三屏的游戏实现,有一个倒计时效果,还有飘动的粽子和白云,按下后会自动飘落。将会用CreateJS来实现。
7)开发顺序是先实现页面样式和简单的JS,最后实现游戏效果。
二、图片
1)切图
原先切图就是用PS中的裁剪来做,不过这样切起来不精确,而且也费事,最近同事推荐了一个PS插件“cutterman”,可以方便的切图。
只要选中图层,点一下导出就OK了,还可以将图层分为一个组后,再导出。
导出后就是一张png、jpg或gif的图片了。
2)Sprite图
做Sprite图也能用这个工具,就是将图片放在一个图层或组里,选中生成就行了。
原先在PC端中“background-position”都是用“px”来定位的,但是,现在在移动端由于使用了“flexible.js”插件,就会放大页面,造成用“px”会不准确。
Sprite图是根据“background-position”移动位置来显示背景图的,后面在网上查了一下,查到了一些资料,网上说可以用百分比来计算,只是百分比计算的话,还需要了解一些概念。
属性值为百分比时,将以图片的 中心点 为基准计算其相对位置,而使用px像素值时将以图片的 左上角 为基准。
With a value pair of '50% 75%', the point 50% across and 75% down the image is to be placed at the point 50% across and 75% down the padding area.
就是说如果“background-position”设置“50% 75%”,那么就以Sprite中的小图“50% 75%”作为基准,放到Sprite图的“50% 75%”位置,就是下图所示:
可以得出公式,也就是计算左上角的坐标:
n%*W - n%*w = -x
n%*H - n%*h = -y
以上面的那张Sprite图为例,写成SASS的@minix如下,“$offset_y”是Y轴偏移量,“$height”是小图的高度,“$total_height”是Sprite图的高度。
@mixin spriteY($offset_y, $height, $total_height) {
background-position: 0 $offset_y /($height - $total_height)*100%;
}
注意下背景“background-size”的宽度为“Sprite图宽度”,高度为“auto”。
三、PrimusUI
PrimusUI是前面一段时间整理的一个微型UI库,为了提升开发效率,提取公用模块而制作的。
具体内容可以参考前面一段时间写的一篇介绍文《小身材大用途,用PrimusUI驾驭你的页面》。
本次活动页面主要应用到了normalize(重置)、grid(网格)、rem(rem计算)、typeface(文本)、layout(布局)、loading以及table(表格)。
1)网格
首页的Logo排列就是用了网格中的Flex布局与平均分配。
2)文本
在文本CSS中,设置了h1-h6的字体,这样就可以直接使用标签,而不用p再设置字体。
HTML中的标签元素也能更丰富,例如排名的页面。
3)表格
参与人数的排行是用表格做的,这与平时看到的表格样子略有不同。
考虑到上面一部分与下面一部分都要左右居中对齐,并且居中的中轴也是同一个,上下部分还有一条横线分割,用表格的tr、td就很容易实现。
但如果用其他标签实现,就比较费劲。
四、CSS3特效
1)简单动画
前面一段时间正好写过一些动画特效《用CSS3动画,让页面动起来》,这次再加深一下印象,这次也参考了一下《Animate.css》。
下图是一个龙舟滑动的动画,简单的上下浮动,船桨的摆动,虽然没有惊艳的视觉冲击,不过至少能看出这龙舟动了。
@keyframes boat {
from {
transform: translate3d(0, funcPxToRem(-10px, 75px), 0);
}
to {
transform: translate3d(0, funcPxToRem(10px, 75px), 0);
}
}
@keyframes quant {
from {
transform: rotate(15deg);
}
to {
transform: rotate(0deg);
}
}
2)渐变与阴影
设计稿中经常会有些渐变效果,后面咨询了设计后,要实现渐变,要先吸取上面颜色与下面颜色,再用CSS渐变属性,简单而又粗暴,但很有效。
.btn-begin {
background: linear-gradient(to bottom,#ec3d1d 50%, #a8270f);
box-shadow: 0 8px #761c0b;
}
下图中按钮的下部分是用阴影来实现的,上面的代码中已展示。
写过两篇文章专门讨论了一下这两个属性《CSS3中惊艳的gradient》与《CSS3中border-radius、box-shadow与gradient那点事儿》
3)伪对象::after或::before
伪对象可以帮助你少写两个标签,让HTML代码更清晰。
下图中的选择战队就是一个背景,还有张标题图,相对定位。
当时做的时候就做了两个标签,现在想想完全可以用一个标签搞定。
<div class="corps" id="corps">
<img src="img/blank.gif" data-src="img/corps-select.png" class="corps-title" />
</div>
4)弹出层
当时为了偷懒就在每一屏的页面上面直接写了HTML代码。
其实可以通过JS做个通用的代码块,直接引用即可,不必像我现在这样每个页面都写一遍相关代码。
5)倒计时
倒计时的JS实现起来不难,用setInterval即可,代码也不多。
只是这个样式的实现比较麻烦。
下图中的数字是需要打出来的,但是四个数字的定位是通过position来实现的,手机屏幕不同,就会出现细微的差别。
最终不得已,对于特定的屏幕范围使用了CSS媒体查询。
@media only screen and(max-width: 640px) and (-webkit-min-device-pixel-ratio: 2),
only screen and(max-width: 640px) and (min-device-pixel-ratio: 2){
#third{
.countdown {
span {
&:nth-child(1) {
left: 147px;
}
&:nth-child(2) {
left: 215px;
}
&:nth-child(3) {
right: 211px;
}
&:nth-child(4) {
right: 143px;
}
}
}
}
}
五、CreateJS
CreateJS封装了Canvas,使得你更容易操纵Canvas,包括四个部分EaselJS(画布)、TweenJS(动画)、SoundJS(音频)、PreloadJS(资源加载)。
有一本书专门介绍了一下这个库《HTML5.Games.with.CreateJS》,没有中文版。
前面一段时间曾经做过两篇简单记录《CreateJS基础类(一)》和《CreateJS事件(二)》,但在实际应用中,还是有点够呛。
游戏的操作很简单,就是点击粽子就飘落,飘落到船上就加2分,游戏的内容可以查看下面的GIF图。
流程可以参看下面的流程图:
1)画布的缩小
移动端画布中的元素还是按“px”来的话,在Android端会被放的很大。
粽子变成了巨棕,云也变成了巨云,显然很不符合美感,需要做点调整。Stage对象中有个scaleX和scaleY属性。
stage.scaleX = stage.scaleY = 0.5;
2)加载资源
如果不用 PreloadJS 中的方法加载资源,后面初始化Bitmap,就是获取不到图片尺寸信息。
游戏的主体代码放到了game.js中。
Loading.queue = new createjs.LoadQueue();
Loading.queue.setMaxConnections(20);
res.img && Loading.queue.loadManifest(res.img, !1);
Loading.queue.load();
3)粽子与云朵
每400毫秒出现一只粽子或云朵,通过setInterval实现。
粽子和云朵的直线飘动用TweenJS实现。
createjs.Tween.get(gift).to({
x: -750
}, 5000).call(function() {
gift.parent.removeChild(gift);
});
给粽子绑定“mousedown”事件,如果用“click”,在移动端会出现300ms延迟。
“mousedown”在PC端是鼠标左键点击的意思,在CreateJS中如果设置了“createjs.Touch.enable(stage, true);”,那么“mousedown”就相当于手指的点击了。
gift.addEventListener('mousedown', function() {
});
粽子的飘落也是用TweenJS来实现,里面还有些计算方式,为何如此计算也不是非常清楚,参照一个demo的,囧。
createjs.Tween.get(gift).to({
y: 550 - gift.y
}, 800 * ((550 - gift.y) / 550)).to({
y: 700 - gift.y,
alpha: 0
}, 300).call(function() {
if (gift.x > 15) { }
})
demo源码下载:
https://github.com/pwstrick/dragon
参考资料:
解决 CSS Sprites 使用 rem 单位时在移动端下错位的问题
一张H5游戏页引起的思考的更多相关文章
- 如何选择 H5 游戏引擎
原生手游市场已是红海,腾讯.网易等寡头独霸天下,H5游戏市场或将成为下一个风口.据笔者所知,很多H5游戏开发团队由于选择引擎不慎导致项目甚至团队夭折.如何选择适合团队和项目的引擎,笔者通过学习和项目实 ...
- h5游戏引擎有哪些
h5游戏引擎有哪些 一.总结 一句话总结: Layabox Egret Pixi.js Three.js PlayCanvas Cocos2d-js Hilo 1.H5游戏开发语言? Flash_AS ...
- 用微信小程序做H5游戏尝试
微信小程序发布后,公司虽然没有拿到第一批内测资格,但作为微信亲密合作伙伴,一定要第一时间去尝试啦.现在微信小程序刚发布还在测试阶段,可以说是1.0版本,所以框架和结构内容都还不多,相关的文档跟微信AP ...
- 使用顽灯浏览器执行H5游戏辅助挂机
前一篇<使用Fidder从安卓模拟器获取APP内H5游戏网址>我们获取到了APP内H5游戏的网址,那么接下来我们使用辅助工具做一些日常任务,如:每天晚上20点做副本,定时喊话,自动清理包裹 ...
- 开发H5游戏引擎的选择:Egret或Laya?
开发H5游戏引擎的选择:Egret或Laya? 一.总结 一句话总结:选laya吧 二.开发H5游戏引擎的选择:Egret或Laya? 一.H5游戏开发的引擎介绍 开发H5游戏的引擎有很多,比如egr ...
- 如何部署 H5 游戏到云服务器?
在自学游戏开发的路上,最有成就感的时刻就是将自己的小游戏做出来分享给朋友试玩,原生的游戏开可以打包分享,小游戏上线流程又长,那 H5 小游戏该怎么分享呢?本文就带大家通过 nginx 将构建好的 H5 ...
- 关于h5游戏开发,你想了解的一切都在这儿!
2020年,受疫情影响,线下产业红利褪去,线上迎来的新一轮的高峰.众多商家纷纷抓住了转型时机,开启了流量争夺战.H5游戏定制无疑是今年引流的大热门.如何开发一款有趣.有爆点.用户爱买单的好游戏呢? ...
- 今天我看了一个H5游戏EUI的例子,我都快分不清我到底是在用什么语言编译了代码了,作为刚刚学习H5游戏开发的菜鸟只能默默的收集知识
今天看了一个EUI的demo,也是接触H5游戏开发的第五天了,我想看看我能不能做点什么出来,哎,自己写果然还是有问题的.在看EUI哪一个demo的时候就遇见了一些摇摆不定的问题,我觉得提出来 1.to ...
- 最近这两天看了关于H5游戏开发的一个教程,实践很短暂,看了很多理论的东西,现在呢也只是想回忆回忆关于EUI的部分知识吧
首先我了解了什么是Egret: Egret中文就是白鹭的意思,Egret是一套H5游戏开发的软件.(纯粹属于个人理解) 其次我对以下几款软件的相关知识做了些了解: Egret Engine(引擎),E ...
随机推荐
- angular 中父元素ng-repeat后子元素ng-click失效
在angular中使用ng-repeat后ng-click失效,今天在这个上面踩坑了.特此记录一下. 因为ng-repeat创造了新的SCOPE.如果要使用这个scope的话就必须使用$parent来 ...
- Spark 应用程序调优
对于很多刚接触Spark的人来说,可能主要关心数据处理的逻辑,而对于如何高效运行Spark应用程序了解较少.由于Spark是一种分布式内存计算框架,其性能往往受限于CPU.内存.网络等多方面的因素,对 ...
- SSH整合,必出精品
SSH:顾名思义(spring,struts2,hirbernate) Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts是一个表示层框架,主要作用是界面展示 ...
- Python之路Day15--JavaScript(一)
一.JavaScript简介 JavaScript是世界上最流行的脚本语言,因为你在电脑.手机.平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱动的. ...
- python Django 进阶篇
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- html中的图像动态加载问题
首先要说明下文档加载完成是什么概念 一个页面http请求访问时,浏览器会将它的html文件内容请求到本地解析,从窗口打开时开始解析这个document,页面初始的html结构和里面的文字等内容加载完成 ...
- C#读取Excel设置(亲测可用)
OpenFileDialog openFD = new OpenFileDialog(); openFD.FileName = ""; openFD.Filter = " ...
- bool型变量下标的时候javascript是不能允许的
jother编码是我最开始想写的内容,原因有两点:1.原理比较简单,不需要太多关于算法的知识.2.比较有趣,是在对javascript有了很深的理解之后催生的产物.如果你只需要知道jother编码和解 ...
- IPC操作时IPC_CREAT和IPC_EXCL选项的说明
IPC(包括消息队列,共享内存,信号量)的xxxget()创建操作时,可以指定IPC_CREAT和IPC_EXCL选项.以共享内存为例:当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存, ...
- 使用Guava EventBus构建publish/subscribe系统
Google的Guava类库提供了EventBus,用于提供一套组件内publish/subscribe的解决方案.事件总线EventBus,用于管理事件的注册和分发.在系统中,Subscribers ...