Javascript 身体动画不是';t平滑

Javascript 身体动画不是';t平滑,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,下面代码中的“宇宙飞船”在按下任何箭头键开始时移动不平稳。它移动一步,冻结一秒钟,然后“平稳”移动。我如何才能让它从一开始就平稳运行,而不是“冻结” 我的代码: <!doctype html> <html> <head> <meta http-content="Content-type" charset="utf-8"> <title>Make body move smoothly</title> &

下面代码中的“宇宙飞船”在按下任何箭头键开始时移动不平稳。它移动一步,冻结一秒钟,然后“平稳”移动。我如何才能让它从一开始就平稳运行,而不是“冻结”

我的代码:

<!doctype html>
<html>
<head>
    <meta http-content="Content-type" charset="utf-8">
    <title>Make body move smoothly</title>
    <style type="text/css">
        body {
        }

        canvas {
            margin: auto;
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            border: 1px solid black;
        }

    </style>
</head>
<body>
<canvas id="canvas" width="400" height="600"></canvas>
<script type="text/javascript">

// Set up requestAnimationFrame and cancelAnimationFrame
(function() {
    var lastTime =0;
    var vendors=['ms', 'moz', 'webkit', 'o'];
    for(var x=0; x<vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame=window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame =
        window[vendors[x]+ 'CancelAnimationFrame'] ||
        window[vendors[x] +'CancelRequestAnimationFrame'];
    }
    if (!window.requestAnimationFrame)
    window.requestAnimationFrame=function(callback, element) {
        var currTime =new Date().getTime();
        var timeToCall =Math.max(0, 16 - (currTime - lastTime));
        var id =window.setTimeout(function() { callback(currTime+timeToCall); },
        timeToCall);
        lastTime =currTime + timeToCall;
        return id;
    };
    if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame=function(id) {
        clearTimeout(id);
    };
}());


    var canvas;
    var ctx;
    // ship data
    var shipPositionX = document.getElementById('canvas').width/2;
    var shipPositionY = document.getElementById('canvas').height - 30;
    var deltaShipPositionX = 10;
    var deltaShipPositionY = 10;

    function init() {
        canvas = document.getElementById('canvas');
        ctx = canvas.getContext('2d');

        draw();
    }

    function draw(){
        clear();
        createRectangleToCoverCanvas();
        createSpaceShip(shipPositionX, shipPositionY, 10);

        requestAnimationFrame(draw);
    }

    function clear(){
        ctx.clearRect(0, 0, document.getElementById('canvas').width, document.getElementById('canvas').height);
    }

    function createRectangleToCoverCanvas(){
        ctx.fillStyle = 'black';
        ctx.strokeStyle = 'black';
        ctx.beginPath();
        ctx.rect(0, 0, canvas.width, canvas.height);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    }

    function createSpaceShip(x, y, radius) {
        ctx.fillStyle = 'white'
        ctx.strokeStyle = 'white'
        ctx.beginPath();
        ctx.rect(x, y, 20, 20);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
    }

    function moveSpaceShip(event){
        switch(event.keyCode){
            // left
            case 37:
                if(shipPositionX - deltaShipPositionX + 15 > 0){
                    shipPositionX -= deltaShipPositionX;
                }
            break;

            // up
            case 38:
                if(shipPositionY - deltaShipPositionY + 15 > 0){
                    shipPositionY -= deltaShipPositionY;
                }
            break;

            // right
            case 39:
                if(shipPositionX + deltaShipPositionX < document.getElementById('canvas').width){
                    shipPositionX += deltaShipPositionX;
                }
            break;

            //down
            case 40:
                if(shipPositionY + deltaShipPositionY < document.getElementById('canvas').height){
                    shipPositionY += deltaShipPositionY;
                }
            break;
        }

    }

    window.addEventListener('load', init);
    window.addEventListener('keydown', moveSpaceShip, true);
</script>
</body>
</html>

使身体平稳地运动
身体{
}
帆布{
保证金:自动;
位置:绝对位置;
左:0;
排名:0;
右:0;
底部:0;
边框:1px纯黑;
}
//设置requestAnimationFrame和cancelAnimationFrame
(功能(){
var lastTime=0;
var供应商=['ms','moz','webkit','o'];
对于(变量x=0;x 0){
shipPositionX-=deltaShipPositionX;
}
打破
//向上
案例38:
如果(船位Y-三角洲船位Y+15>0){
船位Y-=三角洲船位Y;
}
打破
//对
案例39:
if(shipPositionX+deltaShipPositionX
请注意我的代码与此示例之间的差异:

看看这个例子是如何平滑的,但我的“宇宙飞船”不是?
为什么会发生这种情况?我如何修复它?是因为该示例使用了一个精灵(但这似乎没有多大意义)?

问题是,您需要等待每个
按键事件来更新船舶位置。
keydown事件在再次触发之前有一个延迟:开始时经历的延迟和每次重画时面临的跳转

这里的解决方案是在
keydown
上触发移动,然后在
keydup
上释放。这样,只要你按下按钮,你的飞船就会平稳移动

//Im'假设这里的大多数访问者都有最新的浏览器,所以为了便于阅读,我删除了rAF polyfill
//如果在canvas元素deparation之后将其包装,则可以填充此变量,这样可以避免对document.getElementById()进行大量调用
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
//船舶数据
var shipPositionX=canvas.width/2;
//仅针对代码段高度
var-shipPositionY=0;
变量deltaShipPositionX=10;
var deltaShipPositionY=10;
//删除了init()函数,因为我们的元素已加载。
函数绘图(){
清除();
createRectangleToCoverVas();
创建宇宙飞船(shipPositionX,shipPositionY,10);
}
函数clear(){
clearRect(0,0,canvas.width,canvas.height);
}
函数createRectangleToCoverVas(){
ctx.fillStyle='黑色';
ctx.strokeStyle=‘黑色’;
ctx.beginPath();
ctx.rect(0,0,canvas.width,canvas.height);
ctx.fill();
ctx.stroke();
}
函数createSpaceShip(x,y,radius){
ctx.fillStyle='white'
ctx.strokeStyle='白色'
ctx.beginPath();
ctx.rect(x,y,20,20);
ctx.fill();
ctx.stroke();
}
//实例化一个将存储animationFrame id的变量,以便进一步取消它
var raf,
//方向对象,具有x和y值
方向={
x:0,,
y:0
};
//我们可以设置一个速度变量
无功转速=2.5;
功能触发宇宙飞船(事件){
开关(event.keyCode){
//左
案例37:
//更新方向对象
方向x=速度;
//避免在代码段中滚动
event.preventDefault();
打破
//向上
案例38:
方向y=速度;
event.preventDefault();
打破
//对
案例39:
方向x=速度;
event.preventDefault();
打破
//向下
案例40:
方向y=速度;
event.preventDefault();
打破
}
//如果我们还没有启动动画,并且我们的方向不是0,那么现在就开始
如果(!raf&&(direction.x | | direction.y))移动宇宙飞船();
}
功能释放移动宇宙飞船(事件){;
开关(event.keyCode){
//左
案例37:
//重置此方向
方向x=0;
打破
//向上
案例38:
方向y=0;
打破
//对
案例39:
方向x=0;
打破
//向下
案例40:
方向y=0;
打破
}
如果(!direction.x&&!direction.y){
//如果未设置任何方向,请停止动画
取消动画帧(raf);
raf=未定义;
}
}
太空船()的功能{
//声明我们的动画函数
var move=function(){
//在不离开屏幕的情况下更新位置
//对不起,这是脏的。。。
如果(方向x){
如果(
(shipPositionX>0&&shipPositionX=canvas.width-20&&direction.x<0))
shipPositionX+=方向x;
}
如果(方向y){
如果(
(shipPositionY>0&&shipPositionY=canvas.width-20&&direction.y<0)
shipPositionY+=方向y;
}
//最后画出你的船
draw();
//更新我们的皇家空军身份证
raf=请求动画帧(移动);
};
//我们走吧!
raf=请求动画帧(移动);
}
draw();
window.addEventListener('keydown',triggerMoveSpaceShip,true);
window.addEventListener('keyup',releaseMoveSpace,true);
画布{
保证金:自动;
位置:绝对位置;
左:0;
排名:0;
右:0;
底部:0;
边框:1px纯黑;
}
身体{
溢出:无;
}