Javascript 小游戏,“是男人坚持 100 次”

作者:grace 来源:grace 时间:2009-01-22 14:25:00 

佛爷去了公司的年夜饭,我有点无聊就在公司 Coding 点东西玩玩,于是就有了这玩意。请允许我很猥·琐得将这个游戏称之为“是男人坚持 100 次”(坦白讲,我是死活玩不到这个级别了)。

原定两个小时搞定的脚本,结果花了我将近三个小时的时间。完事后我在 Twitter 上记录下心得结果被群殴(看来 Twitter 不能当作笔记本),还是记录到 Blog 里比较靠谱

  1. 设计模式和算法很重要,在前期打“腹稿”的时候就应该搞定那玩意。

  2. 按需加载,特别是在大量的 DOM 操作时,这时候就要体现算法的力量了。

  3. 命名很重要,能避免很多问题。比如遇到了不大不小的 Bug,原因是我作孽得将某个变量命名为 “class” 了。

  4. 效率优先是没有错,可怜我一开始就考虑这些而忽略了其他更重要的事情,绕了很多的弯路。

  5. 结构尽量精炼,能用 CSS 实现的效果尽量用 CSS 实现。

  6. 将“杂碎”的处理拉出来或者再细分整理下,不要写“一坨”很长的 function,自己看着都累。

对技术实现有兴趣的朋友可以看下核心的 Javascript 代码,欢迎提任何建议。PS,在内测的时,虽然这小游戏是我写的,但发现谁都比我玩得好,真是没有脸活了。

  1 /**
  2  * 考验眼力和反应能力的小游戏
  3  *
  4  * @author i.feelinglucky@gmail.com
  5  * @date   2009-01-21
  6  * @link   http://www.gracecode.com/
  7  *
  8  * @change  2009-01-22
  9  *      增加 3 次出错机会,增加 this.score 属性
 10  * @change  2009-01-21
 11  *      完成基本逻辑 @TODO 代码需要优化
 12  */
 13 (function(_scope) {
 14     var defConfig = {group: 10, step: 1.25, life: 3};
 15     var arrow = ['up', 'down', 'left', 'right'];
 16     var keyCode = {'38': 'up', '40':'down', '37': 'left', '39': 'right'};
 17
 18     _scope.Dazing = function(container, config) {
 19         this.container = container;
 20         this.config = config || defConfig;
 21         this.container.style.overflow = 'hidden';
 22         this.container.style.paddingLeft = this.container.clientWidth + 'px';
 23         this.init();
 24     };
 25
 26     var proto = _scope.Dazing.prototype;
 27
 28     proto.init = function() {
 29         this.container.innerHTML = '';
 30         this.score = this.current = this.life = 0;
 31         this.step = this.config.step || 1.25;
 32         this.container.scrollLeft = 0;
 33         var _self = this;
 34         document.onkeydown = function(e) {
 35             e = e || window.event;
 36             var className = keyCode[e.keyCode];
 37             if (className) { _self.judge(className); }
 38         };
 39     };
 40
 41     proto.build = function() {
 42         for (var i = 0; i < this.config.group*2; i++) {
 43             var node = document.createElement('li');
 44             node.className = arrow[Math.round((Math.random()*100))%4];
 45             node.innerHTML = '<span>' + node.className.toUpperCase() + '</span>';
 46             this.container.appendChild(node);
 47         };
 48     };
 49
 50     proto.judge = function(className) {
 51         var node = this.container.childNodes[this.current], answerName = node.className;
 52         if (answerName == className) {
 53             node.className += ' done';
 54         } else {
 55             if (this.life < this.config.life) {
 56                 node.style.visibility = 'hidden';
 57                 this.life++;
 58             } else {
 59                 this.stop();
 60                 if ('function' == typeof this.config.onFinished) {
 61                     this.config.onFinished.call(this);
 62                 }
 63                 return;
 64             }
 65         }
 66         this.current++;
 67     };
 68    
 69     proto.scrolling = function() {
 70         var _self = this, f = arguments.callee;
 71         this.container.scrollLeft += (this.level + 1) * this.step;
 72
 73         var node = this.container.childNodes[this.current];
 74         if (node && (this.container.scrollLeft > node.offsetLeft)) {
 75             this.stop();
 76             if ('function' == typeof this.config.onFinished) {
 77                 this.config.onFinished.call(this);
 78             }
 79             return;
 80         } else {
 81             this.level = Math.floor((this.current) / this.config.group);
 82             var needNodes = (this.level + 2) * this.config.group;
 83             if (needNodes >= this.container.childNodes.length) {
 84                 this.build();
 85             };
 86             this.timer = setTimeout(function() {f.call(_self);}, 20);
 87         }
 88         this.score = this.current - this.life;
 89
 90         if ('function' == typeof this.config.onScrolling) {
 91             this.config.onScrolling.call(this);
 92         }
 93     };
 94
 95     proto.stop = function() {
 96         clearTimeout(this.timer); document.onkeydown = null;
 97     };
 98
 99     proto.start = function() {
100         this.scrolling();
101     };
102 })(window);
103 // vim: set et sw=4 ts=4 sts=4 fdm=marker ff=unix fenc=utf8

顺便八卦:Javascript 做游戏并不是不可能。从目前的情况以及效果和成本看,还是使用 Flash 比较得当。到 HTML5 以及 Canvas 普及以后,这情况可能会有所改变,不过在这之前谁又能等的了呢。

最后,游戏地址:

http://www.gracecode.com/demo/dazing/

您坚持了多少次?亮出来看看?

标签:小游戏,游戏,JavaScript,代码
0
投稿

猜你喜欢

  • asp使用模板生成静态页面方法详解

    2007-09-24 12:29:00
  • HTML编写小经验

    2011-06-14 09:43:14
  • 如何更改mysql命令下提示信息

    2010-10-25 19:48:00
  • asp防范SQL注入攻击的函数

    2008-03-11 12:23:00
  • 解决Dreamweaver不支持中文文件名方法

    2008-01-09 12:52:00
  • 怎样处理 MySQL中与文件许可有关的问题

    2008-11-27 16:12:00
  • asp中用insert into语句向数据库插入记录(添加信息)的方法

    2011-02-05 10:46:00
  • 如何在Access 2007数据库中添加附件

    2008-11-21 12:32:00
  • MySQL存储过程中的sql_mode问题

    2011-01-04 19:50:00
  • css学习笔记:表格隔行点击变色

    2009-04-30 13:15:00
  • 如何将数据库里的记录生成一个Excel文件?

    2009-12-03 20:09:00
  • 5 个简单实用的 CSS 属性

    2010-03-10 11:00:00
  • Css 清除浮动

    2008-09-15 18:47:00
  • MySql 随机取N条数据

    2009-03-17 12:46:00
  • [JS效果]动画效果打开/关闭/移动层

    2008-04-10 11:42:00
  • 给JavaScript自定义一个Trim函数

    2008-04-20 16:30:00
  • 鼠年发几张可爱老鼠的表情gif

    2008-01-29 12:50:00
  • SQL Server 2005 SSIS技巧:动态目的文件名

    2008-12-05 15:47:00
  • 使用MHTML 解决 data URI scheme 的浏览器兼容问题

    2009-05-11 12:30:00
  • SQL Server中如何优化磁带备份设备性能

    2009-01-07 14:23:00
  • asp之家 网络编程 m.aspxhome.com