Weitere ähnliche Inhalte Ähnlich wie Maze Game (20) Maze Game2. 怿飞 / 圆心
in Taobao UED
• Technology Evangelist
• Front-End Engineer
blankzheng@gmail.com
http://www.planabc.net
12. 设计地图
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
15. var anyGrid =
Math.floor(Math.random() * grids.length);
walk(anyGrid);
function walk(grid) {
stepByStep(grid);
// bala bala
}
function stepByStep(grid) {
// bala bala
}
17. var walkHistory = [];
function stepByStep(grid) {
if (hasNextGrid(grid)) {
// bala bala
} else {
if(walkHistory.length > 0) {
var preGrid = walkHistory.pop();
return stepByStep(preGrid);
}
}
}
19. 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);
20. // 判断下方格子是否可通过
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;
}
23. // In stepByStep(): hasNextGrid() === true
var 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 Function
walkHistory.push(grid);
return nextGrid;
24. (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)
25. 0 1 2 3 4
4
5 6 7 8 9
10 11 12 13 14 3
15 16 17 18 19
20 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
26. 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;
}
28. function walk(grid) {
while (getNextGrid() != -1) {
grid = stepByStep(grid);
if(grid === undefined) {
break;
}
}
}
29. function getNextGrid() {
for (var i = 0, l = grids.length; i < l;
i ++) {
if (!grids[i]) {
return i;
}
return -1;
}
}
31. 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
32. 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);
33. 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);
}
}
35. 0000 0001 0010 0011
0 1 2 3
0100 0101 0110 0111
4 5 6 7
36. 1000 1001 1010 1011
8 9 10 11
1100 1101 1110 1111
12 13 14 15
37. 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();
}
38. // 格子上方丌通过,画出上边
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); }
}
40. /**
* 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
*/
42. 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();
}
47. 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);
}
}
48. function stopEvent(event){
if (event.cancelBubble) {
event.cancelBubble = true;
event.returnValue = false;
} else {
event.preventDefault();
event.stopPropagation();
}
return false;
}
51. 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);
53. 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
…
}
54. (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)
56. 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;
}
}
57. 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];
58. 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
}
};
60. var _moods = {
default: ‚./joyful.gif‚,
depressed: ‚./depressed.gif‚,
lucky: ‚./lucky.gif‚,
surprise: ‚./surprise.gif"
}
61. 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);
62. //In _moveTo Function
if (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");
}
64. 分解交互:
动画
标记已走路径
最短路径
Niubility 排行榜