Javascript 不断地添加变换

Javascript 不断地添加变换,javascript,css,animation,game-physics,css-transforms,Javascript,Css,Animation,Game Physics,Css Transforms,我正在用CSS和JS创建一个简单的类似小行星的游戏,使用画布上的DOM进行实验 在本例中,我的代码非常小,因此很容易看到下面发生的事情。最终目标:让箭头键围绕窗口平滑旋转和平移宇宙飞船,而无需创建无限量的变换我想我90%都在那里: 使用箭头键控制下面的代码段 “严格使用”; 函数定义状态(){ var距离={}; 距离.up=-1; 距离。右=1; 距离。向下=1; 距离左=-1; 返回距离; } 函数defineKeys(){ var键={}; keys.up=38; keys.right=

我正在用CSS和JS创建一个简单的类似小行星的游戏,使用画布上的DOM进行实验

在本例中,我的代码非常小,因此很容易看到下面发生的事情。最终目标:让箭头键围绕窗口平滑旋转和平移宇宙飞船,而无需创建无限量的变换我想我90%都在那里

使用箭头键控制下面的代码段

“严格使用”;
函数定义状态(){
var距离={};
距离.up=-1;
距离。右=1;
距离。向下=1;
距离左=-1;
返回距离;
}
函数defineKeys(){
var键={};
keys.up=38;
keys.right=39;
keys.down=40;
keys.left=37;
返回键;
}
功能检查键(e){
var triBx=document.getElementById('v-wrp'),
keys=defineKeys(),
距离=定义距离();
开关(如钥匙代码){
case key.up:
triBx.style.transform+='translateY('+distance.up+'px');
打破
case key.right:
triBx.style.transform+='旋转('+distance.right+'deg');
打破
case key.down:
triBx.style.transform+='translateY('+distance.down+'px');
打破
case key.left:
triBx.style.transform+='旋转('+distance.left+'deg');
打破
}
}
功能检测移动(e){
设定间隔(
函数(){
检查键(e);
},
1000/24
);  
}
函数start(){
窗口。addEventListener('keydown',detectMovement);
preventBrowserWindowScroll()
}
start()
@导入url(“https://fonts.googleapis.com/css?family=Nunito" );
html{
显示器:flex;
证明内容:中心;
对齐项目:居中;
身高:100%;
字体系列:“Nunito”,无衬线;
字号:2rem;
}
五{
显示:块;
变换:旋转(180度);
}

v
函数preventBrowserWindowScroll(){
window.addEventListener('keydown',函数(e){
//空格键和箭头键
if([32,37,38,39,40].indexOf(e.keyCode)>-1){
e、 预防默认值();
}
},错)
}

我认为问题在于detectMovement使用相同的事件e在无限循环中一次又一次地调用检查键

我尝试为keyup、keydown、keyleft和keyright添加侦听器,以便仅在按下这些键时调用checkkeys

如果我理解错误,请评论

“严格使用”;
函数定义状态(){
var距离={};
距离.up=-1;
距离。右=1;
距离。向下=1;
距离左=-1;
返回距离;
}
函数defineKeys(){
var键={};
keys.up=38;
keys.right=39;
keys.down=40;
keys.left=37;
返回键;
}
功能检查键(e){
e、 预防默认值();
var triBx=document.getElementById('v-wrp'),
keys=defineKeys(),
距离=定义距离();
开关(如钥匙代码){
case key.up:
triBx.style.transform+='translateY('+distance.up+'px');
打破
case key.right:
triBx.style.transform+='旋转('+distance.right+'deg');
打破
case key.down:
triBx.style.transform+='translateY('+distance.down+'px');
打破
case key.left:
triBx.style.transform+='旋转('+distance.left+'deg');
打破
}
}
功能检测移动(e){
设定间隔(
函数(){
检查键(e);
},
1000/24
);  
}
函数start(){
window.addEventListener('keydown',checkKeys);
window.addEventListener('keyup',checkKeys);
addEventListener('keyright',checkKeys);
window.addEventListener('keyleft',checkKeys);
}
start()
@导入url(“https://fonts.googleapis.com/css?family=Nunito" );
html{
显示器:flex;
证明内容:中心;
对齐项目:居中;
身高:100%;
字体系列:“Nunito”,无衬线;
字号:2rem;
}
五{
显示:块;
变换:旋转(180度);
}

v
函数preventBrowserWindowScroll(){
window.addEventListener('keydown',函数(e){
//空格键和箭头键
if([32,37,38,39,40].indexOf(e.keyCode)>-1){
e、 预防默认值();
}
},错)
}

我已经做了一个快速的回答-可能有一些方面需要平滑,但你会明白的:(ES6代码)

“严格使用”
班轮{
构造器(elem){
this.posX=0;
this.posY=0;
该度数=0;
这1.rad=0;
这个速度=0;
}
更新(事件){
开关(event.key){
案例“ArrowUp”:
这个速度+=5;
打破
案例“箭头向下”:
这个速度-=5;
如果(this.speed<0)this.speed=0;
打破
案例“ArrowRight”:
这是1.deg+=3;
打破
案例“箭头左”:
这是0.deg-=3;
打破
}
this.rad=(this.deg+90)*Math.PI/180;
}
移动(){
this.posX+=this.speed*Math.cos(this.rad);
this.posY+=this.speed*Math.sin(this.rad);
如果(此速度>0){
该速度-=0.1;
}
if(this.elem==未定义){
this.elem=document.getElementById('ship');
}
var translation='translation('+this.posX+'px',+this.posY+'px');
变量旋转='旋转('+this.deg+'deg');
this.elem.style.transform=平移+旋转;
}
}
新船
功能更新(e){
船舶更新(e);
返回false;
}
函数start(){
addEventListener('keydown',update);
设定间隔(
函数(){
ship.move();
},
1000/24
);  
}
start()
#船舶{
位置:绝对位置;
左:50%;
最高:50%;
}

V
有关更多信息和答案演示,请参阅下面的


使用CSS变换:矩阵函数 如果给定对象位置,则缩放和旋转是最快的设置方式
const setElementTransform = (function(){
    const matrix = [1,0,0,1,0,0]; // predefine the array (helps ease the GC load
    const m = matrix; // alias for code readability.
    return function(element, x, y, scale, rotation);
        m[3] = m[0] = Math.cos(rotation) * scale;     // set rotation and scale
        m[2] = -(m[1] = Math.sin(rotation) * scale);  // set rotation and scale
        m[4] = x;
        m[5] = y;
        element.style.transform = `matrix(${m.join(",")})`;
    }
}());
const keys = {
    ArrowLeft : false,  // add only the named keys you want to listen to.
    ArrowRight: false,  
    ArrowUp   : false,  
    ArrowDown : false,  
    stopKeyListener : (function(){  // adds a listener and returns function to stop key listener if needed.
        function keyEvent(e){
            if(keys[e.code] !== undefined){ // is the key on the named list
                keys[e.code] = e.type === "keydown"; // set true if down else false
                e.preventDefault(); // prevent the default Browser action for this key.
        }
        addEventListener("keydown",keyEvent);
        addEventListener("keyup",keyEvent);
        return function(){
            removeEventListener("keydown",keyEvent);
            removeEventListener("keyup",keyEvent);
        }
    }()) //
}
requestAnimationFrame(mainLoop);  // will start the animation once code below has been parse and executed.
var player = {  // the player
    x : 0,
    y : 0,
    scale : 1,
    rotate : 0,
    speed : 0,
    element : document.getElementById("thePlayer")
}
function mainLoop(time){ // requestAnimationFrame adds the time as the first argument for the callback
     if(keys.ArrowLeft){ player.rotate -= 1 }
     if(keys.ArrowRight){ player.rotate += 1 }
     if(keys.ArrowUp){ player.speed  += 1 }
     if(keys.ArrowRight){ player.speed -= 1 }
     player.x += Math.cos(player.rotate) * player.speed;
     player.y += Math.sin(player.rotate) * player.speed;
     setElementTransform(
         player.element,
         player.x, player.y,
         player.scale,
         player.rotate
     );
     requestAnimationFrame(mainLoop);
}