代码改变世界

javascript异步编程系列【二】----自由落体

2011-08-19 07:49  【当耐特】  阅读(6431)  评论(21编辑  收藏  举报

重力场:地球重力作用的空间。在该空间中,每一点都有惟一的一个重力矢量与之相对应。
各种网络游戏,不管是3D的还是第一视角的,或者横版游戏(如冒险岛),模拟一个重力场是必须的。
先回顾一下谷歌在牛顿诞辰,logo换成了自由落体的苹果。

<html>
<script language="javascript">
    
var h = 0, v = 1;
    window.setTimeout(aa, 
2000);
    
function aa() {
        
var i = self.setInterval("bb()"25);
    }
    
function bb() {
        
var f = document.getElementById('fall');
        
var r = parseInt(f.style.right) + h;
        
var b = parseInt(f.style.bottom) - v;
        f.style.right 
= r + 'px';
        f.style.bottom 
= b + 'px';
        
if (b > -210) {
            v 
+= 2;
        } 
else {
            h 
= (v > 9? v * 0.1 : 0;
            v 
*= (v > 9? -0.3 : 0;
        }
    }
</script>
<body>
    
<div id="fall" style="position: relative; right: -300px; bottom: -46px">
       apple
    
</div>
</body>
</html>

可以看到setTimeout和setInterval!不去仔细琢磨逻辑,光从代码语意上,是非常令人费解的。

在没有口语编程之前,我非常想把代码写成这样:

<html>
<script language="javascript">
        
function drop() {
             
//自由落体
             code  here
             
//撞击地面之后
             code  here
             
//苹果摔烂
             code  here
        }
        
</script>
<body>
    
<div id="fall" style="position: relative; right: -300px; bottom: -46px">
       apple
    
</div>
<script language="javascript">
drop();
</script>
</body>
</html>

 也只有这样的代码才能调用以后的口语编程接口!那么怎么才能写出这样漂亮的代码?

这个时候【jxcex】 闪亮登场!

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    
<title>Jscex Animation</title>
    
<script language="javascript" type="text/javascript" src="lib/uglifyjs-parser.js"></script>
    
<script language="javascript" type="text/javascript" src="src/jscex.js"></script>
    
<script language="javascript" type="text/javascript" src="src/jscex.builderBase.js"></script>
    
<script language="javascript" type="text/javascript" src="src/jscex.async.js"></script>
    
<!--[if IE]>
    <script language="javascript" type="text/javascript" src="http://www.cnblogs.com/lib/json2.js"></script>
    <script language="javascript">
        Jscex.config.codeGenerator = function (code) { return "false || " + code; }
    </script>
    <![endif]
-->
    
<script type="text/javascript">
        
var dropAsync = eval(Jscex.compile("async"function (e, startPos, speedY, duration) {
            $await(Jscex.Async.sleep(
2000));
            
//e.style.left = startPos.x;
            //重力加速度
            var g = 50;
            
var time = 0;
            
var tag = 0;
            
while (time < duration) {
                $await(Jscex.Async.sleep(
25));
                
if (time < 800) {
                    
//自由落体
                    time = time + 50;
                    speedY 
= speedY + g;
                    startPos.y 
+= speedY * 0.05;
                    e.style.top 
= startPos.y;
                }
                
else {
                    
//撞击地面                 
                    if (speedY > 0 && tag == 0) {
                        tag 
= 1;
                        speedY 
= -speedY;
                        speedY 
= speedY / 3;
                    }
                    time 
= time + 50;
                    speedY 
= speedY + g;
                    startPos.y 
+= speedY * 0.05;
                    e.style.top 
= startPos.y;
                }
            }
        }));
        
var changeImageAsync = eval(Jscex.compile("async"function () {
            document.getElementById(
"heart").src = "grieve.gif";
        }));
        
var executeAsync = eval(Jscex.compile("async"function () {
            
//自由落体并撞击地面
            $await(dropAsync(document.getElementById("dropBox"), { x: 0, y: 20 }, 01350));
            
//❤碎
            $await(changeImageAsync());
        }));
      
    
</script>
</head>
<body>
    
<div id="dropBox" style="position: absolute; top: 20;">
        
<img id="heart" src="heart.gif" alt="" />
    
</div>
    
<script type="text/javascript">
        executeAsync().start();
    
</script>
</body>
</html>

Jquery的animate可以用来制作一些动画效果,但仅限于匀速的直线运动,或者匀速的渐变,当然你可以用下面这种费解的方式去实现变速运动,而且要通过大量的计算才能减少与真实运动的差别。

 var i =0 ;
        
var time = 0;
        
var z = 100;
        
function drop() {
            
if (time <7000) {
                i 
+= 5;
                z 
-=1;
                $(
".block").animate({ top: i }, z);
                time 
+= 50;
                drop();
            }
        }

如果是抛物线呢?对于这种变速运动Jquery的animate真是力不从心啊!

如果不用【jxcex】 ,你会陷入一大堆回调循环当中,痛不欲生!当然如果你觉得很爽,你能想明白,又不想让别人看明白,那又是另外一回事了。

不过话说----代码是写给别人看的。

 

【代码示例下载】:

最新的【jxcex】 库,请上https://github.com/JeffreyZhao/jscex或者http://www.sndacode.com/projects/jscex/wiki下载吧····