• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Maze Game
 

Maze Game

on

  • 5,382 views

develop maze game by using javaScript

develop maze game by using javaScript

Statistics

Views

Total Views
5,382
Views on SlideShare
1,351
Embed Views
4,031

Actions

Likes
4
Downloads
41
Comments
0

18 Embeds 4,031

http://www.planabc.net 3416
http://feed.planabc.net 489
http://xianguo.com 27
http://www.zhuaxia.com 24
http://km.oa.com 24
http://reader.youdao.com 10
http://static.slidesharecdn.com 10
http://www.zuixiami.com 7
http://zhuaxia.com 6
http://www.xfruits.com 5
http://www.newsblur.com 4
http://www.itfeed.cn 3
http://webcache.googleusercontent.com 1
http://cache.baiducontent.com 1
http://old.xianguo.com 1
http://mailreader.163.com 1
http://www.slideshare.net 1
http://bbs.9tech.cn 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Maze Game Maze Game Presentation Transcript

    • 怿飞 / 圆心
    • 怿飞 / 圆心 in Taobao UED • Technology Evangelist • Front-End Engineer blankzheng@gmail.com http://www.planabc.net
    • 
    • 迷宫第一定律 只要在出发点单手摸住一面墙出发,手始 终丌离开墙面,总可以找到迷宫的出口。 只要走遍迷宫所有路径必然可以找到迷宫终点
    • 迷宫第二定律 存在未走过的路径时先走未走过的,丌存 在时只走走过一次的路径。
    • 《荒岛历险之山洞里的战斗》 —— 李毓佩
    • 第一条,进入迷宫后,可以任选一条道路往前走;第二条,如果遇到走丌通的死胡同,就马上返回,并在该路口做个记号;
    • 第三条,如果遇到了叉路口,观察一下是否还有没有走过的通道。有,就任选一条通道往前走;没有,就顺着原路返回原来的叉路口,并做个记号。
    • 第四条,重复第二条和第三条所说的走法,直到找到出口为止。第五条,如果要把迷宫所有地方都搜查到,即凡是没有做记号的通道都要走一遍。
    • 设计地图 0 1 2 … x-1 x x+1 x+2 … 2x-1 2x 2x+1 2x+2 … 3x-1 … … … … … (y-1)x (y-1)x+1 (y-1)x+2 … yx-1
    • var grids = [];grids.length = x*y;
    • 设计地图第一条,进入迷宫后,可以任选一条道路 往前走。
    • var anyGrid = Math.floor(Math.random() * grids.length);walk(anyGrid);function walk(grid) { stepByStep(grid); // bala bala}function stepByStep(grid) { // bala bala}
    • 设计地图第二条,如果遇到走丌通的死胡同,就马 上返回,并在该路口做个记号。第三条,如果遇到了叉路口,观察一下是 否还有没有走过的通道。没有,就顺着原 路返回原来的叉路口,并做个记号。
    • var walkHistory = [];function stepByStep(grid) { if (hasNextGrid(grid)) { // bala bala } else { if(walkHistory.length > 0) { var preGrid = walkHistory.pop(); return stepByStep(preGrid); } }}
    • grid-xgrid-1 grid grid+1 grid+x
    • function getGridContext(grid) { var p = 0, c, gc = []; // 判断上方格子是否可通过 p = grid - x; c = p > 0 && !grids[p]; c ? gc.push(p) : gc.push(-1); // 判断右方格子是否可通过 p = grid + 1; c = p % x != 0 && !grids[p]; c ? gc.push(p) : gc.push(-1);
    • // 判断下方格子是否可通过 p = grid + x; c = p < grids.length && !grids[p]; c ? gc.push(p) : gc.push(-1); // 判断左方格子是否可通过 p = grid - 1; c = grid % x != 0 && !grids[p]; c ? gc.push(p) : gc.push(-1); return gc;}
    • function hasNextGrid(grid) { var gc = getGridContext(grid); if(gc.join(‘,’) !== ‘-1,-1,-1,-1’){ return true; } return false;}
    • 设计地图第三条,如果遇到了叉路口,观察一下是 否还有没有走过的通道。有,就任选一条 通道往前走。
    • // In stepByStep(): hasNextGrid() === truevar gc = getGridContext(grid), nextGrid, ngc = [], r;for(var i = 0; i < 4; i++) { if(gc[i] !== -1) { ngc.push(i); }}r = Math.floor(Math.random() * ngc.length);nextGrid = gc[ngc[r]];… // TODO: Mark FunctionwalkHistory.push(grid);return nextGrid;
    • (0001=1) (t,r,b,l) t/r/b/l:0 or 1 1111=8|4|2|1=15(1000=8) 0011=2|1=3 (0010=2) … (0100=4)
    • 0 1 2 3 4 45 6 7 8 910 11 12 13 14 315 16 17 18 1920 21 22 23 24 8 grids[4] = 8 stepByStep(4) [-1,-1,9,3] grids[3] = 2 grids[3] = 2|4= 6 stepByStep(3) [-1,-1,8,2] grids[8] = 1
    • switch (ngc[r]) { case 0: grids[grid] |= 1; grids[nextGrid] |= 4; break; case 1: grids[grid] |= 2; grids[nextGrid] |= 8; break; case 2: grids[grid] |= 4; grids[nextGrid] |= 1; break; case 3: grids[grid] |= 8; grids[nextGrid] |= 2; break;}
    • 设计地图第四条,重复第二条和第三条所说的走法, 直到找到出口为止。第五条,如果要把迷宫所有地方都搜查到, 即凡是没有做记号的通道都要走一遍。
    • function walk(grid) { while (getNextGrid() != -1) { grid = stepByStep(grid); if(grid === undefined) { break; } }}
    • function getNextGrid() { for (var i = 0, l = grids.length; i < l; i ++) { if (!grids[i]) { return i; } return -1; }}
    • ctx.fillStyle = ‘rgb(65, 60, 50)’;ctx.fillRect(50, 50, 35, 20);ctx.strokeStyle = ‘rgb(65, 60, 50)’;ctx.strokeRect(100, 100, 30, 30); 50 100 ctx.fillRect(x,y,w,h) 50 100
    • function drawMap(parentNode) { var canvas = document.createElement("canvas"), w, h, cxt, v, l, t; w = gridWidth * x; h = gridHeight * y; canvas.setAttribute("width", w); canvas.setAttribute("height", h); parentNode.appendChild(canvas); ctx = canvas.getContext("2d"); ctx.fillStyle = "#f5f5f5"; ctx.fillRect(0, 0, w, h);
    • ctx.strokeStyle = "#aaa"; ctx.strokeRect(0, 0, w, h); for(var i = 0, len = grids.length; i < len; i++) { v = grids[i]; l = gridWidth * (i%x); t = gridHeight * Math.floor(i/x); // TODO: Draw grid border function drawBorder(ctx, l, t , v); }}
    • ctx.strokeStyle = ‘rgb(65, 60, 50)’;ctx.beginPath();ctx.moveTo(50, 50);ctx.lineTo(100, 100);ctx.stroke(); 50 100 50 100
    • 0000 0001 0010 0011 0 1 2 30100 0101 0110 0111 4 5 6 7
    • 1000 1001 1010 1011 8 9 10 111100 1101 1110 111112 13 14 15
    • function drawBorder(ctx, l, t, v) { var x1 = l, y1 = t, x2 = x1 + gridWidth, y2 = y1 + gridHeight; ctx.strokeStyle = "#aaa"; var doDraw = function (x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); ctx.closePath(); }
    • // 格子上方丌通过,画出上边 if (!(v & 1)) { doDraw(x1, y1, x2, y1); } // 格子右方丌通过,画出右边 if (!(v & 2)) { doDraw(x2, y1, x2, y2); } // 格子下方丌通过,画出下边 if (!(v & 4)) { doDraw(x1, y2, x2, y2); } // 格子左方丌通过,画出左边 if (!(v & 8)) { doDraw(x1, y1, x1, y2); }}
    • Draw a line from (1, 0) to (1, 3)
    • /** * if you try to draw a line from (1, 0) to (1, 3), * the browser will draw a line covering 0.5 screen pixels * on either side of x=1. * The screen can’t display half a pixel, * so it expands the line to cover a total of two pixels. * * Ref: http://diveintohtml5.org/canvas.html */
    • Draw a line from (1.5, 0) to (1.5, 3)
    • var doDraw = function (x1, y1, x2, y2) { x1 = x1 + 0.5; y1 = y1 + 0.5; x2 = x2 + 0.5; y2 = y2 + 0.5; r = Math.floor(Math.random() * ngc.length); ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); ctx.closePath();}
    • 分解交互 Event: up/left/down/right Behavior: stepBystep Fun: setMood
    • 分解交互: 兼容性的 addEvent / stopEvent 注册事件 / 事件函数的处理
    • function addEvent(obj, type, fn) { if (obj.attachEvent) { obj[e+type+fn] = fn; obj[type+fn] = function(){ obj[e+type+fn](window.event); } obj.attachEvent(on+type, obj[type+fn]); } else { obj.addEventListener(type, fn, false); }}
    • function stopEvent(event){ if (event.cancelBubble) { event.cancelBubble = true; event.returnValue = false; } else { event.preventDefault(); event.stopPropagation(); } return false;}
    • 分解交互: 兼容性的 addEvent / stopEvent 注册事件 / 事件函数的处理
    • keydown keypress keyup
    • var handler = function(event) { var code = event.which || event.keyCode; // {37:left, 38:up, 39:right,40:down‘} switch(code) { // TODO: _stepByStep function case 38: stepByStep(0); break; case 39: stepByStep(1); break; case 40: stepByStep(2); break; case 37: stepByStep(3); break; } stopEvent(event);};addEvent(document, keydown, handler);
    • 分解交互: 类似亍 Map 的 StepByStep
    • var grid = 0, isfinished = false;function stepByStep(d){ var v = maze.grids[grid], gridWidth = maze.width, gridHeight = maze.height, x = maze.x; if(isfinished) return; // TODO: Judgment …}
    • (0001=1) (t,r,b,l) t/r/b/l:0 or 1 1111=8|4|2|1=15(1000=8) 0011=2|1=3 (0010=2) … (0100=4)
    • grid-xgrid-1 grid grid+1 grid+x
    • if (v & Math.pow(2, d)) { // check grid switch (d) { case 0: grid = grid - x; moveTo(grid); break; case 1: grid = grid + 1; moveTo(grid); break; case 2: grid = grid + x; moveTo(grid); break; case 3: grid = grid - 1; moveTo(grid); break; }}
    • function moveTo(grid) { var l = gridWidth * (grid % x), t = gridHeight * Math.floor(grid / x); // set oLostor’s position oLostor.style.left = l + px; oLostor.style.top = t + px; // gird value is change v = grids[grid];
    • if (i === grids.length - 1) { //end isfinished = true; //bala bala } else if(i != 0 && [1,2,4,8].indexOf(v)>-1){ // impasse //bala bala } else if (i === 0) { //start //bala bala } else { //bala bala }};
    • 分解交互: 提示信息:setMoodAnd so on …
    • var _moods = { default: ‚./joyful.gif‚, depressed: ‚./depressed.gif‚, lucky: ‚./lucky.gif‚, surprise: ‚./surprise.gif"}
    • var _setMood = function (mood) { if (_moods[0] === mood) return; if (_moods[mood]) { _moods[0] = mood; oImg.src = _moods[mood]; }}var oImg = doc.createElement("img"),oImg.src = _moods.default;_moods[0] = ‚default‛;oLostor.appendChild(oImg);
    • //In _moveTo Functionif (i === grids.length - 1) { //end isfinished = true; _setMood("lucky");} else if (i != 0&&[1,2,4,8].indexOf(v)>-1){ // impasse _setMood("depressed");} else if (i === 0) { //start _setMood("surprise");} else { _setMood(‚default");}
    • 分解交互: 信息提示:setMood And so on …
    • 分解交互: 动画 标记已走路径 最短路径 Niubility 排行榜
    • http://oldj.net/article/javascript-maze/http://oldj.net/article/javascript-maze-2/http://diveintohtml5.org/canvas.htmlhttp://ejohn.org/projects/flexible- javascript-events/