我如何赋予这个元素惯性/动量?

时间:2017-05-02 15:30:30

标签: javascript html css game-physics css-transforms

有一个非常小的类似于小行星的游戏片段,我正在使用没有Canvas的DOM。我有"船"当按下箭头键时移动相当顺利,但我将如何给予船舶动力?当用户释放钥匙时,我不希望船停下来。我试图模拟太空物理学一点点。我怎么能让这艘船继续朝着它的方向移动,同时允许它自由地旋转而不朝着它当前指向的方向行进(除非向上箭头被按下)?想法?



var Keys = {
  up: false,
  down: false,
  left: false,
  right: false
}

window.onkeydown = function( e ) {
  var kc = e.keyCode;
  e.preventDefault();

  if ( kc === 37 ) Keys.left = true;
  else if ( kc === 38 ) Keys.up = true;
  else if ( kc === 39 ) Keys.right = true;
  else if ( kc === 40 ) Keys.down = true;
};

window.onkeyup = function( e ) {
  var kc = e.keyCode;
  e.preventDefault();

  if ( kc === 37 ) Keys.left = false;
  else if ( kc === 38 ) Keys.up = false;
  else if ( kc === 39 ) Keys.right = false;
  else if ( kc === 40 ) Keys.down = false;
};

@import url( "https://fonts.googleapis.com/css?family=Nunito" );

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: "Nunito", sans-serif;
  font-size: 4rem;
}

b {
  display: block;
  transform: rotate( 180deg );
}

<div>
  <b>v</b>
</div>

<script>
  function update() {
    if ( Keys.up ) {
      document.querySelector( 'div' ).style.transform += 'translateY( -1px )';
    }
    else if ( Keys.down ) {
      document.querySelector( 'div' ).style.transform += 'translateY( 1px )';
    }

    if ( Keys.left ) {
      document.querySelector( 'div' ).style.transform += 'rotate( -1deg )';
    }
    else if ( Keys.right ) { 
      document.querySelector( 'div' ).style.transform += 'rotate( 1deg )';
    }

    requestAnimationFrame( update );
  }
  
  requestAnimationFrame( update );
</script>
&#13;
&#13;
&#13;

使用箭头键控制代码段。

1 个答案:

答案 0 :(得分:2)

注意:您使用的控制方法是将translate指令添加到您的发货元素的样式中。运行您的代码段,打开浏览器检查器,然后检查游戏。每一帧,您都要添加新的增量变换。这不是一种可持续的方法!每个单独的转换代表一个单独的计算,每个帧重新计算和应用,更不用说标记正在疯狂地扩展。

矩阵运算顺序很重要,因此旋转后跟翻译将沿旋转方向移动,而翻译后跟旋转会产生不同的结果(也不是你想要的结果)。

理想情况下,您完全可以更改您的移动代码。如果你想坚持使用CSS进行渲染,而不是在每个帧上添加新的变换,那么你想要在每个帧上更新transform属性。您可能希望获得矩阵数学库(例如http://glmatrix.net/),然后将变换应用并存储在JavaScript变量中,并仅将最终计算变换推送到CSS以进行渲染(更新,而不是追加)。 / p>

此时您可以开始解决问题:您需要将旋转与平移方向分离。最终目标是能够在1个聚合矩阵中表示在其自己的原点上旋转并转换到右侧世界位置的船舶,该矩阵总结了在船上应用的所有变换,以及它们应用的顺序。有几种方法可以做到这一点。一种非常简单和常见的方法是暂时放置您的船(通过变换),使其原点(您想要旋转的周围)为0,0,应用旋转变换,然后应用最终的平移到你想要的船实际上的位置。如果您按照我的建议使用矩阵库,那么您可以在表示船舶变换的矩阵上执行此操作。

我建议你阅读关于矩阵以及它们是如何堆叠的,有大量的游戏开发教程可以讨论这个 - 更具体地说,关于如何推动转换矩阵=应用和弹出=撤消(提示:0) ,我上面提到的0旋转的事情涉及暂时推动一个新的变换,它将聚合变换位置带到0,0,在这个变换状态下计算船的所需旋转,然后弹出最后一个变换矩阵=撤消转换为0,你只需要暂时使用。)

祝你好运!