【转载】HTML5做一个数独游戏的过程详解

标签: HTML 5技术概览 HTML5 技术博文 HTML5前沿技术 HTML5学习资源 | 发表时间:2012-05-17 00:37 | 作者:HTML5研究小组
出处:http://www.mhtml5.com

数独是很好玩的游戏,之前我用jQuery做了一个数独游戏,因为用javaScript来实现drag和drap非常麻烦,jQuery的UI提供了一套非常不错的drag和drap(以后就简称DnD算了),方便我们开发。现在HTML5支持原生的DnD了,那我们来学习下,并且将原先的数独游戏迁移到HTML5的DnD应用来。

 

先简单的了解下HTML5的DnD事件模型,事件发生在源元素(被拖动的元素)和目标元素(被进入的元素)上,为了简单的描述,我们将源元素称为src,目标元素叫des。

 

drag:src[拖动中] dragstart:src[开始拖动]
dragenter:des[进入目标]
dragover:des[在目标移动]
dragleave:des[离开目标]
drop:des[释放拖动]
dragend:src[拖动完成]

所有的事件我们知道肯定都应该给我们一个event对象,帮助我们获得一些信息或我们来设置一些信息,以上事件都可以得到一个event,如果我们的事件函数是function(e)那

 

e.dataTransfer.effectAllowed,只能在dragstart事件设置,值为以下之一:”none”, “copy”, “copyLink”, “copyMove”, “link”, “linkMove”, “move”, “all”, and “uninitialized”

e.dataTransfer.dropEffect,返回拖来的行为,对应上面的effectAllowed,值是:”none”, “copy”, “link”, and “move”

e.target,可以得到当前事件的dom对象,比如你可以得到e.target.innerHTML,或者设置e.target.classList.add,或者e.target.classList.remove

e.dataTransfer.setData(foramt,value),为拖动赋值,foramt的值是为了描述值的类型,一般有text/plain 和 text/uri-list

e.dataTransfer.getData(foramt),获取被拖来的元素通过setData存储的值

e.stopPropagation,阻止事件冒泡,这样可以防止子元素的拖动处理被带到父元素事件中(触发父元素事件),在IE中可以用e.cancelBubble = true

e.preventDefault,阻止默认事件发生,也可以简单的写return false,在IE中可以用e.returnValue = false

有了上面的基本概念,我们先做一个小小的模型,来测试几个技术要点:监视拖放事件,改变元素在拖放中的样式,传递值和检查值什么的

在body里面,我们声明了10个div元素,并且都标记允许拖放

 

  
  1. <body>
  2.     <div style="width: 50px; height: 50px; background-color: Red;" draggable="true">
  3.         1
  4.     </div>
  5.     <div style="width: 50px; height: 50px; background-color: Yellow;" draggable="true">
  6.         2
  7.     </div>
  8.     <div style="width: 50px; height: 50px; background-color: Blue;" draggable="true">
  9.         3
  10.     </div>
  11.     <div style="width: 50px; height: 50px; background-color: Lime;" draggable="true">
  12.         4
  13.     </div>
  14.     <div style="width: 50px; height: 50px; background-color: Maroon;" draggable="true">
  15.         5
  16.     </div>
  17.     <div style="width: 50px; height: 50px; background-color: Black;" draggable="true">
  18.         6
  19.     </div>
  20.     <div style="width: 50px; height: 50px; background-color: Orange;" draggable="true">
  21.         7
  22.     </div>
  23.     <div style="width: 50px; height: 50px; background-color: Olive;" draggable="true">
  24.         8
  25.     </div>
  26.     <div style="width: 50px; height: 50px; background-color: Teal;" draggable="true">
  27.         9
  28.     </div>
  29.     <div style="width: 50px; height: 50px; background-color: Green;" draggable="true">
  30.         10
  31.     </div>
  32. </body>

现在我们想做一个应用,只有相互有倍数关系的div之间才可用拖放。

 

首选我们做一个用于输出调式的小工具代码

  
  1. $.log = function(msg) {
  2.     console.log(msg);
  3. }

 

这个我们可以方便的$.log()输出,而不要写冗长的console.log了

 

第一步,编写dragStart事件函数

  
  1. function handleDragStart(e) {
  2.     this.style.opacity = "0.5";
  3.     e.dataTransfer.effectAllowed = "move";
  4.     e.dataTransfer.setData("text/plain", this.innerHTML);
  5.     //$.log(this.innerHTML);
  6.     //$.log(e.target.innerHTML);
  7.     //$.log(e.srcElement.innerHTML);
  8.     [ ].forEach.call(document.querySelectorAll("div"),
  9.     function(item) {
  10.         var a = parseInt(e.target.innerHTML);
  11.         var b = parseInt(item.innerHTML);
  12.         if (a % b != 0 && b % a != 0) {
  13.             item.style.opacity = "0.1";
  14.         }
  15.     });
  16. }

 

以上的代码有几个要点

 

1 对事件来讲this、e.target和e.srcElement都是同一对象

2 在forEach中,this是指item,所以forEach中,我们要用e.target来引用

但是一测试我们就发现虽然元素可以拖拉,但并没有事件激活,那是应为我们没有为元素绑定事件,所以现在我们用addEventListener来将元素和事件绑定

  
  1. $(
  2. function() {
  3.     [ ].forEach.call(document.querySelectorAll("div"),
  4. function(item) {
  5.      item.addEventListener("dragstart", handleDragStart, false);
  6. }
  7. );
  8. }
  9. );

 

现在我们可以看到,当任意元素拖动的时候,不和其元素有相互倍数的元素变了很淡了。

 

第二步,当我们拖放完成后,所有div恢复原先颜色,那自然是编写handleDragEnd

  
  1. function handleDragEnd(e) {
  2.     if (e.preventDefault) {
  3.         e.preventDefault(); //不要执行与事件关联的默认动作
  4.     }
  5.     [ ].forEach.call(document.querySelectorAll("div"),
  6.     function(item) {
  7.         item.style.opacity = "1";
  8.     }
  9.     );
  10. }

 

记得将上面的事件做绑定哦,应该类似以下代码

  
  1. $(
  2. function() {
  3.     [ ].forEach.call(document.querySelectorAll("div"),
  4. function(item) {
  5.      item.addEventListener("dragstart", handleDragStart, false);
  6.      item.addEventListener("dragend", handleDragEnd, false);
  7. }
  8. );
  9. }
  10. );

第三步,我们要通知那些互为倍数的元素允许我们做拖入操作

 

我们先需要为目标元素定义些事件函数

  
  1. function handleDragEnter(e) {
  2.     $.log(e);
  3. }
  4. function handleDragOver(e) {
  5.     if (e.preventDefault) {
  6.         e.preventDefault(); //不要执行与事件关联的默认动作
  7.     }
  8.     if (e.stopPropagation) {
  9.         e.stopPropagation(); //停止事件的传播
  10.     }
  11.     $.log(e);
  12.     return false;
  13. }
  14. function handleDragLeave(e) {
  15.     $.log(e);
  16. }
  17. function handleDrop(e) {
  18.     if (e.preventDefault) {
  19.         e.preventDefault(); //不要执行与事件关联的默认动作
  20.     }
  21.     if (e.stopPropagation) {
  22.         e.stopPropagation(); //停止事件的传播
  23.     }
  24.     console.log(e);
  25.     return false;
  26. }

 

 

注意我们使用了preventDefault和stopPropagation消除了浏览器默认的一些动作。

显然这些事件不是所有的元素都有的,只有互为倍数才有,所以我们要去修改handleDragStart函数了

修改后的代码大致如下

  
  1. function handleDragStart(e) {
  2.     this.style.opacity = "0.5";
  3.     e.dataTransfer.effectAllowed = "move";
  4.     e.dataTransfer.setData("text/plain", this.innerHTML);
  5.     //$.log(this.innerHTML);
  6.     //$.log(e.target.innerHTML);
  7.     //$.log(e.srcElement.innerHTML);
  8.     //$.log(this.innerHTML);
  9.     [ ].forEach.call(document.querySelectorAll("div"),
  10.     function(item) {
  11.         var a = parseInt(e.target.innerHTML);
  12.         var b = parseInt(item.innerHTML);
  13.         if (a % b != 0 && b % a != 0) {
  14.             item.style.opacity = "0.1";
  15.         }
  16.         else {
  17.             item.addEventListener("dragover", handleDragOver, false);
  18.             item.addEventListener("dragenter", handleDragEnter, false);
  19.             item.addEventListener("dragleave", handleDragLeave, false);
  20.             item.addEventListener("drop", handleDrop, false);
  21.         }
  22.     });
  23. }

 

现在你可以发现,当我们拖动互为倍数的元素是,视觉效果明显是允许拖入,否则就不允许了。当然记得在handleDragEnd函数中要恢复哦

  
  1. function handleDragEnd(e) {
  2.     if (e.preventDefault) {
  3.         e.preventDefault(); //不要执行与事件关联的默认动作
  4.     }
  5.     [ ].forEach.call(document.querySelectorAll("div"),
  6.     function(item) {
  7.         item.style.opacity = "1";
  8.         item.removeEventListener("dragover", handleDragOver, false);
  9.         item.removeEventListener("dragenter", handleDragEnter, false);
  10.         item.removeEventListener("dragleave", handleDragLeave, false);
  11.         item.removeEventListener("drop", handleDrop, false);
  12.     }
  13.     );
  14. }

第四步,当我们在可以放置的元素上结束拖放后,我们希望两个元素的值累计,并出现在被放置的元素里面,我们需要修改handleDrop函数

  
  1. function handleDrop(e) {
  2.     if (e.preventDefault) {
  3.         e.preventDefault(); //不要执行与事件关联的默认动作
  4.     }
  5.     if (e.stopPropagation) {
  6.         e.stopPropagation(); //停止事件的传播
  7.     }
  8.     this.innerHTML = parseInt(this.innerHTML)+parseInt(e.dataTransfer.getData("text/plain"))
  9.     console.log(e);
  10.     return false;
  11. }

好了,到现在为止,准备知识都差不多了,而且作品我们也可以得意的玩玩,你可以发现div被累计都,再次拖拉的时候,是重新计算相互的倍数的,对不?

 

最后,我感觉黑色的字不好看,我们修改下初始化的函数

  
  1. $(
  2. function() {
  3.     [ ].forEach.call(document.querySelectorAll("div"),
  4. function(item) {
  5.     item.addEventListener("dragstart", handleDragStart, false);
  6.     item.addEventListener("dragend", handleDragEnd, false);
  7.     item.style.color = "White";
  8. }
  9. );
  10. }
  11. );

 

 

好了,现在这个无聊的拖动作品,至少可以打发下你的时间,对不,欣赏下自己的作品吧,接下来,我们开始做正式做数独游戏了。

第一步,我们先生成一个1-9的数字对象矩形,这个矩形可以拖动。

先设计htmltag

  
  1. <ol id="numberBox" style="list-style-type: none; width: 90px; height: 90px;">
  2. </ol>

 

 

然后准备些样式

  
  1. [css] view plaincopy
  2. #numberBox > li
  3. {
  4.     width: 30px;
  5.     height: 25px;
  6.     text-align: center;
  7.     font-size: 20px;
  8.     padding-top: 5px;
  9.     float: left;
  10.     color: White;
  11. }

最后是脚本

  
  1. [javascript] view plaincopy
  2.  $(
  3. function() {
  4.     [{ number: 1, bgcolor: "#C71585" }, { number: 2, bgcolor: "#800080" }, { number: 3, bgcolor: "#B8860B" },
  5.     { number: 4, bgcolor: "rgb(0,0,128)" }, { number: 5, bgcolor: "rgb(30,144,255)" },
  6.     { number: 6, bgcolor: "rgb(255,165,0)" },
  7.      { number: 7, bgcolor: "hsl(0,75%,50%)" }, { number: 8, bgcolor: "hsl(30,50%,50%)" },
  8.      { number: 9, bgcolor: "hsl(120,75%,38%)"}].forEach(
  9.      function(key, index) {
  10.      $.log(key);
  11.          var li = $("<li>").html(key.number).css("backgroundColor", key.bgcolor).attr("draggable","true");
  12.          $.log(li);
  13.          li[0].addEventListener("dragstart", function() {
  14.          }, false);
  15.          $("#numberBox").append(li);
  16.      }
  17.      );
  18. }
  19. );

好,然后你运行下页面,可以看到一个九宫格,并且每一个格子都可以拖动。

第二步,我们要类似的创建我们填数字得的区域了。

首先还是htmlTag

  
  1. [html] view plaincopy
  2. <ol id="player" style="list-style-type: none; width: 450px; height: 450px;">
  3. </ol>

然后是样式设定

  
  1. [css] view plaincopy
  2. #player .default
  3. {
  4.     float: left;
  5.     width: 48px;
  6.     height: 33px;
  7.     border: solid 1px rgb(0,0,0);
  8.     font-size: 20px;
  9.     padding-top: 15px;
  10.     text-align: center;
  11.     background-color: #B8860B;
  12. }
  13. #player .fix
  14. {
  15.     float: left;
  16.     width: 48px;
  17.     height: 33px;
  18.     border: solid 1px rgb(0,0,0);
  19.     font-size: 20px;
  20.     padding-top: 15px;
  21.     text-align: center;
  22.     background-color: #FFFABC;
  23. }
  24. #player .ation
  25. {
  26.     float: left;
  27.     width: 48px;
  28.     height: 33px;
  29.     border: solid 1px rgb(0,0,0);
  30.     font-size: 20px;
  31.     padding-top: 15px;
  32.     text-align: center;
  33.     background-color: #FFA07A;
  34. }

然后初始化这个区域。数独填字区域有的格子有值有的没有值,我用0表示没有值将来你可以填制,非0表示是固定区不可以改

现在你已经可以在页面上看到一个非常威武的“独”字了!

  
  1. [javascript] view plaincopy
  2.  $(
  3. function() {
  4.     "500000300090500400004000700051037289302080604008052137035000900609000823080023006".split("").forEach(
  5.     function(item, index) {
  6.         $.log(item);
  7.         var li = $("<li>")
  8.         if (item != "0") {
  9.             li.addClass("fix");
  10.             li[0].innerHTML = item;
  11.         }
  12.         else {
  13.             li[0].classList.add("default");
  14.             li[0].addEventListener("dragenter",
  15.             function(e) {
  16.                 $.log(e);
  17.             }, false);
  18.             li[0].addEventListener("dragover",
  19.             function(e) {
  20.                 if (e.preventDefault) {
  21.                     e.preventDefault(); //不要执行与事件关联的默认动作
  22.                 }
  23.                 if (e.stopPropagation) {
  24.                     e.stopPropagation(); //停止事件的传播
  25.                 }
  26.                 $.log(e);
  27.                 return false;
  28.             }, false);
  29.             li[0].addEventListener("dragleave",
  30.             function(e) {
  31.             }, false);
  32.             li[0].addEventListener("drop",
  33.             function(e) {
  34.                 if (e.preventDefault) {
  35.                     e.preventDefault(); //不要执行与事件关联的默认动作
  36.                 }
  37.                 if (e.stopPropagation) {
  38.                     e.stopPropagation(); //停止事件的传播
  39.                 }
  40.             }, false);
  41.         }
  42.         $("#player").append(li);
  43.     }
  44.     );
  45. }
  46. );

第三步:我们拖动数字之后,希望可以填数字的区域有明显的颜色变化并给出提示,同时固定区域不可以拖进去,其他区域可以拖进去,并且拖动的时候要send值。

有了前面的知识,我们马上知道去哪里改事件控制了:dragstart事件

  
  1. [javascript] view plaincopy
  2.  $(
  3. function() {
  4.     [{ number: 1, bgcolor: "#C71585" }, { number: 2, bgcolor: "#800080" }, { number: 3, bgcolor: "#B8860B" },
  5.     { number: 4, bgcolor: "rgb(0,0,128)" }, { number: 5, bgcolor: "rgb(30,144,255)" },
  6.     { number: 6, bgcolor: "rgb(255,165,0)" },
  7.      { number: 7, bgcolor: "hsl(0,75%,50%)" }, { number: 8, bgcolor: "hsl(30,50%,50%)" },
  8.      { number: 9, bgcolor: "hsl(120,75%,38%)"}].forEach(
  9.      function(key, index) {
  10.          //$.log(key);
  11.          var li = $("<li>").html(key.number).css("backgroundColor", key.bgcolor).attr("draggable", "true");
  12.          //$.log(li);
  13.          li[0].addEventListener("dragstart", function(e) {
  14.              e.dataTransfer.effectAllowed = "copyMove";
  15.              e.dataTransfer.setData("text/plain", this.innerHTML);
  16.              $.log(this.innerHTML);
  17.              [ ].forEach.call(document.querySelectorAll("#player .default"),
  18.          function(item) {
  19.              //$.log(item);
  20.              item.classList.remove("default");
  21.              item.classList.add("ation");
  22.          });
  23.          }, false);
  24.          li[0].addEventListener("dragend", function() {
  25.              [ ].forEach.call(document.querySelectorAll("#player .ation"),
  26.          function(item) {
  27.              item.classList.remove("ation");
  28.              item.classList.add("default");
  29.          });
  30.          }, false);
  31.          $("#numberBox").append(li);
  32.      }
  33.      );
  34. }
  35. );

 

 

现在你可以测试下了,当你拖动数字的时候,有明显的颜色改变,并且不同的区域你的鼠标样式也不同哦。

第四步,我们接受值,并且判断这个值是否存在行列冲突,如果冲突就提示,否则改写

  
  1. [javascript] view plaincopy
  2.  $(
  3. function() {
  4.     "500000300090500400004000700051037289302080604008052137035000900609000823080023006".split("").forEach(
  5.     function(item, index) {
  6.         $.log(item);
  7.         var li = $("<li>")
  8.         if (item != "0") {
  9.             li.addClass("fix");
  10.             li[0].innerHTML = item;
  11.         }
  12.         else {
  13.             li[0].classList.add("default");
  14.             li[0].addEventListener("dragenter",
  15.             function(e) {
  16.                 $.log(e);
  17.             }, false);
  18.             li[0].addEventListener("dragover",
  19.             function(e) {
  20.                 if (e.preventDefault) {
  21.                     e.preventDefault(); //不要执行与事件关联的默认动作
  22.                 }
  23.                 if (e.stopPropagation) {
  24.                     e.stopPropagation(); //停止事件的传播
  25.                 }
  26.                 $.log(e);
  27.                 return false;
  28.             }, false);
  29.             li[0].addEventListener("dragleave",
  30.             function(e) {
  31.             }, false);
  32.             li[0].addEventListener("drop",
  33.             function(e) {
  34.                 if (e.preventDefault) {
  35.                     e.preventDefault(); //不要执行与事件关联的默认动作
  36.                 }
  37.                 if (e.stopPropagation) {
  38.                     e.stopPropagation(); //停止事件的传播
  39.                 }
  40.                 var sendData = e.dataTransfer.getData("text/plain");
  41.                 //获得#player>li矩阵数组
  42.                 var matrix = Array.prototype.slice.call(document.querySelectorAll("#player>li"));
  43.                 var currIndex = matrix.indexOf(this); //获得当前元素的位置
  44.                 var rowIndex = currIndex - currIndex % 9; //行开始的位置
  45.                 var colIndex = currIndex % 9//列开始的位置
  46.                 for (var i = rowIndex; i < rowIndex + 9; i++) {
  47.                     if (i != currIndex && matrix[i].innerHTML == sendData) {
  48.                         alert("对不起行上有数据重复,请小心哦!亲");
  49.                         return;
  50.                     }
  51.                 }
  52.                 for (var i = colIndex; i < 81; ii = i + 9) {
  53.                     if (i != currIndex && matrix[i].innerHTML == sendData) {
  54.                         alert("对不起列上有数据重复,请小心哦!亲");
  55.                         return;
  56.                     }
  57.                 }
  58.                 this.innerHTML = sendData;
  59.             }, false);
  60.         }
  61.         $("#player").append(li);
  62.     }
  63.     );
  64. }
  65. );

现在你可以开始玩啦,虽然颜色不怎么好看,但至少可以玩,对不,我们第一个html5的实用游戏。我后期的blog打算再做些类似新浪微博的“你画我猜”还有“接龙游戏”。

转自 http://shyleoking.blog.51cto.com/1374881/863969#559183-tsina-1-13805-ed0973a0c870156ed15f06a6573c8bf0

相关 [html5 数独 游戏] 推荐:

【转载】HTML5做一个数独游戏的过程详解

- - HTML5研究小组
数独是很好玩的游戏,之前我用jQuery做了一个数独游戏,因为用javaScript来实现drag和drap非常麻烦,jQuery的UI提供了一套非常不错的drag和drap(以后就简称DnD算了),方便我们开发. 现在HTML5支持原生的DnD了,那我们来学习下,并且将原先的数独游戏迁移到HTML5的DnD应用来.

割绳子游戏HTML5版

- - 我爱互联网
在拉斯维加斯正在举行的CES大会上,微软CEO鲍尔默宣布了基于IE9和 html 5框架的 割绳子游戏,由微软及游戏开发商ZeptoLab共同推出,用于促进IE9的使用及网页的美化,网页版点击这里. 游戏主角就是一个贪吃的小绿怪兽,必须通过割绳子来将糖果送到小怪物嘴里,并搜集星星来增加得分. 到目前为止,下载量已经超过6000万,潜力足以和《愤怒的小鸟》媲美.

游戏开发商开源HTML5游戏

- - Solidot
游戏工作室Wooga开源了其开发的HTML5游戏Pocket Island,源代码托管在GitHub上,该公司在官方博客上介绍了他们的开发经验,认为HTML5游戏有潜力,但尚未做好准备,开源的意图将是让其他人了解他们的工作,学习和改进. Wooga认为,2012年也许不是HTML5的黄金时代,但它的黄金时代即将到来.

HTML5 tower defense – HTML5 塔防游戏 | 小众软件 > 游戏

- Yishen - 小众软件
塔防类游戏还是很受人喜爱的,今天的这个塔防是用 HTML5 写成的,虽然是简单的画面,但是深得塔防精髓. 官方网站 | 来自小众软件. ©2011 root for 小众软件 | 原文链接 | 0 留言 | 加入我们 | 投稿 | 订阅指南. vNES – 经典的在线电视游戏. 玛丽猫 – 经典的变态超级玛丽.

推荐10个HTML5游戏网站

- ZB - cnBeta.COM
原文作者Julio Rivera是一名来自纽约市的创意总监和网页设计师,他是Underworld Magazines的创始人. 到现在为止,我玩了好几年的在线游戏. 我已经看过用Flash和其他软件制作游戏,目前是在用HTML5做游戏,只看到一个完整用CSS3做的游戏.

25 超棒的 HTML5 Canvas 游戏

- 迎客松 - LinuxEden开源社区-Linux伊甸园
Canvas 元素作为HTML5标准的一部分,允许你通过脚本动态渲染点阵图像. 这是为了基于浏览器的矢量图形而设计. HTML Canvas 把一个绘图 API 展现给 JS 客户端,使得脚本能够把想绘制的东西都绘制到一块画布上. 阅读全文 | 邮件推荐 | 评论回复.

推荐10个HTML5游戏网站

- scotty - 博客园新闻频道
  导读:原文作者Julio Rivera是一名来自纽约市的创意总监和网页设计师,他是Underworld Magazines的创始人.   到现在为止,我玩了好几年的在线游戏. 我已经看过用Flash和其他软件制作游戏,目前是在用HTML5做游戏,只看到一个完整用CSS3做的游戏.   HTML5正在慢慢成为新的Flash,以前在Flash上很酷的东东,如拖放和下载条等,现在已可以用HTML5做到了.

HTML5游戏开发工具推荐:IMPACT

- iDesperadO - HTML5研究小组
Impact 是一个 JavaScript 游戏引擎,可以为桌面和手机浏览器开发令人惊叹的 HTML5 游戏. 我已经试过了四个其他 JavaScript 游戏引擎,这是我用过的第一个比较有意义的(……)Impact 是市场上第一个真正专业级的 JavaScript 和 HTML5 游戏引擎. ——《Game Developer Magazine》,2011年5月.

HTML5游戏前端开发秘籍

- - 腾讯ISUX - 社交用户体验设计 - Better Experience Through Design
QQ空间Android版4.2和4.5上线的玩吧游戏“空间疯狂套牛”是一款使用HTML5开发出的手机游戏,虽然还有很多不足,但其中使用的一些技术与技巧还是很有必要为大家分享出来,方便大家用秘籍打通各种关卡创造出更多更好的HTML5游戏. (本秘籍主要讲述使用HTML + CSS技术方面). Android手机的屏幕碎片化非常严重,各种各样的分辨率非常之多,那么如何让游戏可以适配这些机型就显得尤为重要.

基于引擎开发HTML5游戏实战(一)---游戏引擎

- - CSDN博客推荐文章
最近从一个技术沙龙活动中了解到一个游戏引擎( construct2), 这款引擎彻底地改变了游戏开发在我心目中的印象. 以前看过一些游戏开发的书籍,基本上都是从canvas,从坐标系讲起,再加上复杂地绘图编程,使得我不 敢对游戏开发有所奢望,更别提那些大制作. 但基于这款引擎让我在2个小时之内根据官方tutorial就能搞出一个看上去还不错的web游戏,并且不需要 一行代码,有点当年第一次接触ruby on rails时的震撼.