【★】Web精彩实战之
JS精彩实战之<智能迷宫>
1.能够更改所有元素的颜色。
2.能够变换任意形状的尺寸。
3.能够自由调整地图的大小。
4.能够随机生成迷宫的地图。
5.能够自由绘制路线的位置。
6.能够从起点或者从终点走。
7.能够沿途记录走过的路径。
8.能够瞬间移动到之前的点。
9.能够有多种难度迷宫算法。
10.能够自定义背景音乐图片。
11.能够支持计时和分数系统。
12.能够拥有快速冲刺的技能。
13.能够提供完善的帮助提示。
很好,先贴出成品H5文件,网盘地址为:
https://pan.baidu.com/s/1hrAVM3U
同学们先下载这个安全文件,用自家的浏览器打开,但因为本人只Safari和Firefox上测试过,并不能保证所有浏览器兼容,所以建议你们使用Firefox、Chrome、Safari、Opera之一的浏览器打开,最好不要IE。。下面进入游戏的全流程讲解。
第一步:确定底层原理
1)画布canvas
2)绝对定位
3)浮动元素
第二步:选择合适的框架
1)内核很重要
2)分层分类
站在最高层,总共4个H5元素,分别是canvas,div控制台(float:right),起点和终点div(position:absolute)。canvas的最底层是背景色,上层由方块square和墙wall组成:
起点div的z_index大于终点div的z-index以便到达终点时可以覆盖,但他们都是直接覆盖在canvas之上的。
控制台div很灵活,因为是浮动定位,可以随浏览器窗口随意漂浮。控制台主要由一些表单元素和说明文字组成:
如右上边所示-->-->-->
第三步:建立虚拟媒介
1)虚拟坐标
为什么呢?画布的原始坐标是以像素为单位,但是为了满足需求,可以自由变换尺寸和大小,需要一个内外模式之间的中介,那就是虚拟坐标。因为语言上说明有点难度,所以直接上图:
第四步:定义一些关键的变量
1)数值字段
var wall_size=3;//墙的宽度
var square_size=12;//方块的边长
var amount_y=50;//y的最大坐标
2)存储型变量
用来存放大量数据,比较考验数据结构的理论。
var wall=new Array();//用来存放所有的墙
var shortest_path=new Array();//用来存放随机路径
var direction=new Array();//用来存放可走的方向
var already_path=new Array();//用来存放沿途走过的路径
3)状态变量
该字段也很重要,总共设置了两个:一个state变量用来显示此时迷宫是在play状态还是draw状态;还有一个get变量,后面会介绍用途。
4)标签对象
Very Important!索性把所有标签元素全给document.getElementByIdx_x_x了,不然后面引用的时候累死宝宝。虽然我并没有全设:
var wall_color=document.getElementByIdx_x_x("wall_color");
var path_color=document.getElementByIdx_x_x("path_color");
var destination=document.getElementByIdx_x_x("destination");
var pen_x=document.getElementByIdx_x_x("pen_x");
var pen_y=document.getElementByIdx_x_x("pen_y");
var ori_x=document.getElementByIdx_x_x("ori_x");
var ori_y=document.getElementByIdx_x_x("ori_y");
var des_x=document.getElementByIdx_x_x("des_x");
var des_y=document.getElementByIdx_x_x("des_y");
5)参数变量
这个指的是那些辅助变量,比如用于循环语句的i和j,以及用于JS方法的形式参数event和key等等。
第五步:初始化
1)独立区域
这里强烈建议window.onload中分配一块区域专门用来做初始化,而不要像核显一样集成在Html中,相信我,这样会便于后期管理!!这里我主要初始化的内容有:数值字段的缺省值、存储变量的内存空间、所有标签元素相关的属性。因本游戏不是大型软件,在独立区域只安排了部分初始化,其余都直接在html元素属性中完成:
for(var i=0;i<=100;i++){
wall[i]=new Array();
for(var j=0;j<=100;j++)
wall[i][j]=new Object();
}
for(var i=1;i<=100;i++){
already_path[i]=new Array();
}
clear_already();
draw_border_wall();
origin.style.top=canvas.offsetTop-(-wall_size)+"px";
origin.style.left=canvas.offsetLeft-(-wall_size)+"px";
第六步:思考数据结构
1)矩阵
这一步耗费了我好多精力,我们的矩阵框架想要合理的存储还不是那么容易。思来想去,最终决定用二维数组来存放,因为虚拟坐标的帮助,“方块”的坐标直接写成数组的下标,数组元素值暂定,比如可以0无1有。
2)2.5维数组
这个是用来存放墙的。因为墙的特殊性:横纵坐标中有且只有一个小数。如果将坐标值乘以2存入二维数组中会浪费内存空间,如果只在x方向上乘以2又难以管理整个数组。所以应该采用2.5维数组,这是我起的名字,其实就是个二维数组,只不过每个元素都有子对象,形成了“第三维”,但这“第三维”只有2层,遂我美其名曰“2.5维”。具体实现方式就是:存放坐标为方块,子对象是right和down,值是0或1 ,如图所示:
3)顺序表
之所以没有采用树形存储结构的原因是——忘了怎么定义树。。不过没关系,顺序表同样能满足需求:核心算法中将讲到他。顺序表是一个一维数组,最可贵的是他提供pop()和push()函数,这样就可以把它当做一个堆栈来使用。
第七步:编写常用的函数
1)优选API
浏览器提供的系统函数非常有用,现成的拿来直接用。比如Math对象的库函数、Array对象的库函数等等。这里就不列举了。
2)输入输出型
输入输出型函数就是一个数学函数,在SmartMaze中是一些辅助道具。这里面的direction数组用来存放制图时哪些方向可走,但我找了半天却没找到删除数组制定元素值的函数,无奈之下只能自定义:function del_array(array,data){}也许不久的将来,或许是你读到这篇文章的时候,JS已经支持这些新方法了,期待吧!
3)无参函数
行为函数(没有参数的函数)才是我们用到的主流函数,它的任务就是完成一系列动作,对系统做出一些改变。定义这种函数需要注意,一定要考虑周全,比如状态变量、存储表是否需要做出相应的更改。这里定义了好多好多:
function set_destination_position();//重置终点位置
function clear_already();//清空already_path数组
function look_around();//环顾可走的方向
function random_draw_wall();//随机画墙
function forbid_wall();//设置不可随机画的墙
function run();//“弱智图”算法
function advanced_run();//“专业图”算法
4)事件监听
事件触发函数是自动执行的函数,系统会一直监听环境,当触发条件被打破,函数立即被执行。本游戏的三种事件:
document.getElementByIdx_x_x(“destination_color”).onchange=function();
document.getElementByIdx_x_x(“wall_size").onchange=function();
document.getElementByIdx_x_x(“square_size").onchange=function();
document.getElementByIdx_x_x("amount_x").onchange=function amo_x_cha(){
document.getElementByIdx_x_x("amount_y").onchange=function amo_y_cha(){
wall_color.onchange=function(){
path_color.onchange=function(){
canvas.onclick=function(event){}
document.body.onkeydown=function(key){}
第八步:确定核心算法
1)强大的递归
这里要击破三个困难点:第一个是墙壁碰撞检测;第二个则是与“已走路”之间的碰撞检测。第三个困难点是:检测到碰撞后该朝哪走?要知道,碰撞拐弯之后很可能走入一个死胡同,这该怎么办,现在核心问题就是:如何判断环路?哈哈,方法就多了,但是我选择的办法是:不判断!我们用递归!发句感慨,递归真是算法中最宝贵的财富:当你想不出算法的时候就想它吧:)具体实现看下一段。但是记住,递归函数利于人类思考,代价是大量的机器计算。
2)随机之美
fucntion 算法(){
}
3)神奇的树
fucntion 算法(){
}
第九步:反向考虑兼容性问题
1)Get新技能!
2)分数系统
3)跨平台
第十步:优化
1)拒绝臃肿
2)一起来化妆
3)更多的帮助
最后一步:展望
1)与服务器的交互
毕竟这是个Web应用,来电服务器相应和用户的回馈会大大增强游戏的可玩性,想象就刺激:多人竞赛,即时挑战,自制地图分享,限时追逐赛……
2)转型成3D画面
用JavaScript做3d并不难,好吧我不该发表评论的因为自己目前还不会做。不过SmartMaze3D版本迟早会出现,也许是12.0也许是20.0,或许你读到这段文字的时候我的智能3d版迷宫已经面世了:)
3)曲线迷宫
相比3d迷宫,个人认为这个最有挑战度,因为3d迷宫也可以做成90°,但这个曲线迷宫图还需要新的算法,至少目前没有头绪。Who Care?目前的作品已经够我装一阵子逼了。
OK,所有内容到此结束,如有疑问请留言新浪微博@IT让生活更美好
2017.3.25 19:09