开发记录

前言

之前跟着慕课网学习开发H5小游戏开心鱼,勾起我的兴趣。

在写代码的过程中,不怎么会遇到问题。虽然代码是亲手敲出来的,但是由于并没有对游戏的整体思路,所以并不知道开发与优化的过程。

为了巩固知识,和了解优化的过程。我用了半天时间写出《看你有多色》游戏,(在网上找了一张游戏截图,之后自己写)

由于是第一次自己构思、自己动手的游戏,所以还有很多地方有待完善。

基本界面的实现的过程

就像切图一样,在我找到截图的时候,先利用HTML搭出框架,再用CSS填充样式。

随后是加入JS去实现不同的逻辑与活动。

HTML

我把控制输出信息(得分、倒计时、按钮)与画板(Canvas)分开,这样方便用JS控制。

  1. <div class="message">
  2. <div class="score" id="score">
  3. Score:0
  4. </div>
  5. <div class="timer">
  6. <strong id="timer">
  7. &nbsp;60&nbsp;
  8. </strong>
  9. </div>
  10. <div class="stop">
  11. <button>暂停</button>
  12. </div>
  13. </div>
  14. <div class="colorGame">
  15. <canvas id="canvas" width="500" height="500"></canvas>
  16. </div>

CSS

CSS的实现没什么难度,只是在写的时候发现一个问题:

如果我想把倒计时写成div,并且用display:inline-block;控制其显示为有长宽的矩形时,文字好像脱离了div。原因暂时还没想到,目前的解决方式是改变显示方式。

  1. *{padding: 0;margin: 0;}
  2. .gameView{margin: 0 auto;width: 500px;height: 100px;position: relative;}
  3. .message{margin: 0 auto;width: 500px;height: 100px;background: #D1FFA2;
  4. margin-top: 20px;}
  5. .score,.timer,.stop{width: 160px;height: 100px;display: inline-block;
  6. text-align: center;font: 32px/100px "Tahoma";margin-right: -8px;}
  7. .score{background: #00CF95;}
  8. .timer{width: 180px;background: #0098EF;}
  9. .timer strong{color: #fff;margin: 0px auto;background: red;border-radius: 10px;
  10. font-weight: normal;}
  11. .stop{background: #6D0AD3;}
  12. .stop button{display: inline-block;height: 50px;width: 70px;border: none;
  13. border-radius: 10px;background: red;color: #fff;
  14. font: 24px/50px "微软雅黑";box-shadow: 5px 3px #ccc;}
  15. .colorGame{margin: 0 auto;width: 500px;height: 500px;background: #D1FFA2;}

JS

JS的实现比较复杂,我的思路是先通过Canvas画出游戏刚开始的界面。

这里用到了Canvas绘图的函数。我封装了一个绘制圆角矩形的函数,drawRoundRect(),参数依次是绘图环境名称、圆角矩形的X\Y坐标、圆角矩形的半径、填充色。

  1. function drawRoundRect(cxt,x,y,r,radius,fillColor){
  2. cxt.save();
  3. cxt.translate(x,y);
  4. cxt.beginPath();
  5. cxt.arc(r-radius,r-radius,radius,0,Math.PI/2);
  6. cxt.lineTo(radius,r);
  7. cxt.arc(radius,r-radius,radius,Math.PI/2,Math.PI);
  8. cxt.lineTo(0,radius);
  9. cxt.arc(radius,radius,radius,Math.PI,Math.PI*3/2);
  10. cxt.lineTo(r-radius,0);
  11. cxt.arc(r-radius,radius,radius,Math.PI*3/2,Math.PI*2);
  12. cxt.lineTo(r,r-radius);
  13. cxt.closePath();
  14. cxt.fillStyle = fillColor?fillColor:"black";
  15. cxt.fill();
  16. cxt.restore();
  17. }

然后绘制游戏界面,drawGame()。

由于不同等级下的界面并不相同,所以我需要提前设置变量:level[ ](游戏等级分布)、

spacing[ ](不同等级下的方块间距)、squareW[ ](不同等级下的方块边长)。

又因为绘制时需要的参数是X\Y轴坐标,因为可以通过这三个变量算出来,所以我又封装了一个函数rectXY(),传入的参数是方块的位置值。

  1. function rectXY(a){
  2. return (a+1)*spacing[levelNum]+a*squareW[levelNum];
  3. }
  4. function init(){
  5. /*MaxLevel : 136*/
  6. level = [
  7. 2,2,
  8. 3,3,3,
  9. 4,4,4,4,
  10. 5,5,5,5,5,5,5,5,5,5,
  11. 6,6,6,6,6,6,6,6,6,6,6,6,
  12. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  13. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  14. 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  15. 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  16. 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10];
  17. for (var i = 0; i < level.length; i++) {
  18. spacing[i] = level[i]*(-2)+24;
  19. }
  20. for (var i = 0; i < level.length; i++) {
  21. squareW[i] = Math.floor((w-(level[i]+1)*(level[i]*(-2)+24))/level[i]);
  22. }
  23. }
  24. function drawGame(levelNum){
  25. //画背景
  26. drawRoundRect(context,0,0,500,8,"#D1FFA2");
  27. //画方块
  28. for (var i = 0; i < level[levelNum]; i++){
  29. for (var j = 0; j < level[levelNum]; j++){
  30. drawRoundRect(context,rectXY(i),rectXY(j),squareW[levelNum],6,formerColor);
  31. }
  32. }
  33. drawRoundRect(context,rectXY(differentX),rectXY(differentY),squareW[levelNum],6,differentColor);
  34. canvas.addEventListener('click',detect);
  35. }

这样基本的界面就已经画好了。

交互逻辑的实现

这个游戏的交互活动很简单,仅仅是需要添加点击的监听事件。

难点在于,Canvas是DOM对象,监听时获取到的结果是对整个Canvas的点击效果(Canvas内部的图样是没有办法独立的被监听)。

解决的逻辑是:先获取鼠标的坐标值,然后用isPointInPath()判断当前坐标是否在当前绘制路径内部。

  • canvas对象有一个方法getBoundClientRect(),返回的是canvas元素的边界框对象, 此对象的left与top属性即为canvas左上角点相对窗口的坐标,将事件坐标与canvas坐标相减,得到相对于canvas的坐标。

  1. var x = event.clientX - canvas.getBoundingClientRect().left;
  2. var y = event.clientY - canvas.getBoundingClientRect().top;
  • 获取后再进行判断是否在图形内。

  1. if(context.isPointInPath(x,y)){}
  • 由于绘制差异方块时还需要注意颜色相近,所以我设置了一个数组,用于计算RGB模式下的颜色差值,差值越来越小是因为关卡难度上升导致颜色更加相近。

  1. badNum = [38,28,18,12,10,8,6,4,3,2];

具体的实现方法,包含之前的监听与判断,还有随机色与之相近色的获取和统计分数并更新。

  1. function scoreNum(){
  2. var scoreObj = document.getElementById("score");
  3. score++;
  4. scoreObj.innerHTML = "Score:"+score;
  5. }
  6. function detect(event){
  7. var x = event.clientX - canvas.getBoundingClientRect().left;
  8. var y = event.clientY - canvas.getBoundingClientRect().top;
  9. drawRoundRect(context,rectXY(differentX),rectXY(differentY),squareW[levelNum],6,differentColor);
  10. if(context.isPointInPath(x,y)){
  11. levelNum++;
  12. differentX = Math.floor(Math.random()*level[levelNum]);
  13. differentY = Math.floor(Math.random()*level[levelNum]);
  14. R = Math.floor(Math.random()*255);
  15. G = Math.floor(Math.random()*255);
  16. B = Math.floor(Math.random()*255);
  17. formerColor = "rgb("+R+","+G+","+B+")";
  18. nR = R+badNum[0];
  19. nG = G+badNum[0];
  20. nB = B+badNum[0];
  21. differentColor = "rgb("+nR+","+nG+","+nB+")";
  22. context.clearRect(0,0,500,500);
  23. drawGame(levelNum);
  24. scoreNum();
  25. }
  26. }

汇总

  • 总的来说这个游戏并不复杂,稍微有一些不一样的地方就是对Canvas添加监听事件时,与对DOM添加事件相比更麻烦一点。

  • 暂时来说没有卡住的地方,但是存在一个很大的问题:这个程序并没有体现面向对象的思想,二次浏览的时候会感到逻辑混乱。

  • 还有一些小功能并没有添加进去:

    1.没有暂停功能。

    2.没有GameOver后的提示功能。

模仿开发H5游戏,看你有多色的更多相关文章

  1. 开发H5游戏引擎的选择:Egret或Laya?

    开发H5游戏引擎的选择:Egret或Laya? 一.总结 一句话总结:选laya吧 二.开发H5游戏引擎的选择:Egret或Laya? 一.H5游戏开发的引擎介绍 开发H5游戏的引擎有很多,比如egr ...

  2. HTML5游戏 看你有多“色” 开发

    所有文章搬运自我的个人主页:sheilasun.me 在极客学院看到了这个游戏,在网上找到这个游戏玩了好久真的比较上瘾,于是自己也试着做了一下,可以戳这里试玩→看你有多色 游戏规则: 找出颜色不同的方 ...

  3. 用canvas开发H5游戏小记

    自神经猫风波之后,微信中的各种小游戏如雨后春笋般目不暇接,这种低成本,高效传播的案例很是受开发者青睐.作为一名前端,随手写个这样的小游戏出来应该算是必备技能吧.恰逢中秋节,部门决定上线一个小游戏,在微 ...

  4. H5小游戏——看你有多色

    使用了封装了canvas的create.js库来实现的. 最终效果: 工程: Rect.js /* * 方块类 */ function Rect(n,color,specialColor){ crea ...

  5. 今天我看了一个H5游戏EUI的例子,我都快分不清我到底是在用什么语言编译了代码了,作为刚刚学习H5游戏开发的菜鸟只能默默的收集知识

    今天看了一个EUI的demo,也是接触H5游戏开发的第五天了,我想看看我能不能做点什么出来,哎,自己写果然还是有问题的.在看EUI哪一个demo的时候就遇见了一些摇摆不定的问题,我觉得提出来 1.to ...

  6. 最近这两天看了关于H5游戏开发的一个教程,实践很短暂,看了很多理论的东西,现在呢也只是想回忆回忆关于EUI的部分知识吧

    首先我了解了什么是Egret: Egret中文就是白鹭的意思,Egret是一套H5游戏开发的软件.(纯粹属于个人理解) 其次我对以下几款软件的相关知识做了些了解: Egret Engine(引擎),E ...

  7. H5游戏开发之抓住小恐龙

    第一次写技术性博文,以前都只是写一些生活感想,记录一些生活发生的事情. 博主大三学生一枚,目前学习JS一年多,还处于学习阶段,有什么说的不好的希望大牛指点下,由于第一次写博文,排版什么的有待改进,希望 ...

  8. 使用Phaser开发你的第一个H5游戏(一)

    本文来自网易云社区 作者:王鸽 不知你是否还记得当年风靡一时的2048这个游戏,一个简单而又不简单的游戏,总会让你在空闲时间玩上一会儿. 在这篇文章里,我们将使用开源的H5框架--Phaser来重现这 ...

  9. 开发H5小游戏

    Egret白鹭H5小游戏开发入门(一)   前言: 好久没更新博客了,以前很多都不会,所以常常写博客总结,倒是现在有点点经验了就懒了.在过去的几个月里,在canvas游戏框架方面,撸过了CreateJ ...

随机推荐

  1. 解密FFmpeg播放状态控制内幕

    上一篇文章(http://my.oschina.net/u/2336532/blog/400790)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H264的 ...

  2. jquery实现多行文字图片滚动效果

    今儿分享一个jquery实现多行滚动效果. 我看一些论坛网站上面,公告处用的较多. 代码如下 复制代码 // 多行滚动(function($){$.fn.extend({Scroll:function ...

  3. 在ASP.NET中发送电子邮件的实例教程

    首先.导入命名空间: 代码如下 复制代码 using System.Net.Mail; 定义发送电子邮件的方法[网上很多不同的,可以对比着看一下,WinForm的也适用]: 代码如下 复制代码 /// ...

  4. 桌面虚拟化之部署DDC-5.6

    1. 打开管理软件 2. 选择桌面部署 3. 如果没有数据库则使用默认的 4. 导入许可证文件(当然未申请可试用30天) 5. 主机类型选择无(这里未做服务器虚拟化) 6. 最后完成初步配置 配置计算 ...

  5. UI5_UINavigation传值

    // // AppDelegate.m // UI5_UINavigation传值 // // Created by zhangxueming on 15/7/7. // Copyright (c) ...

  6. JS 提示框 alert()、confirm()、prompt()的三者的区别

    使用消息框 使用警告.提示和确认 可以使用警告.确认和提示消息框来获得用户的输入.这些消息框是 window 对象的接口方法.由于 window 对象位于对象层次的顶层,因此实际应用中不必使用这些消息 ...

  7. hdu 六度分离 floyd

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1869 题意分析:比较简单的最短路算法,最后只需判断最远两点距离是否大于7即可. /*六度分离 Time ...

  8. windows下 berkerly db的安装配置(修正了关键步骤)

    这个是我从别人的博客上找来的,亲测可用,确实解决了我当时遇到的一些问题. 首先,从http://www.oracle.com/technology/global/cn/software/product ...

  9. Linux下编译安装mysql-5.0.45.tar.gz

    安装环境:VMware9(桥接模式) + Linux bogon 2.6.32-642.3.1.el6.x86_64(查看linux版本信息:uname -a) 先给出MySQL For Linux ...

  10. iOS屏幕尺寸和分辨率

    iOS平台家族成员主要包括iPhone.iPod Touch和iPad,但是各类设备的分辨率各不相同,目前存在的尺寸主要有: iOS设备的尺寸多种多样,此外,屏幕的分辨率也有多种,总结如下表所示: 其 ...