How can I give this element momentum / momentum?

You have a very small snippet of an asteroid game in which I am working on using only the DOM without Canvas. I have a "ship" moving quite smoothly when the arrow keys are pressed, but how can I give the ship momentum? When the user releases the key, I don't want the ship to stop. I am trying to simulate the physics of space a little. How could I get this ship to move in the direction it was going, allowing it to spin freely without moving in the direction it is currently pointing (unless the up arrow is pressed)? Ideas?

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>
      

Run codeHide result


Use the arrow keys to control the slice.

+3


source to share


1 answer


Note. The control method you use adds tons of directives translate

to your ship element style. Run your snippet, open the browser inspector and examine the game. Each frame, you add new incremental transforms. This is not a sustainable approach! Each individual transform is a separate computation that is recalculated and applied every frame, not to mention the markup expands like crazy.

The matrix order of the operations matters, so a rotation followed by translation will move in the rotated direction, whereas a translation followed by rotation will produce a different result (also not what you want).

Ideally, you completely change the movement code. If you want to stick with CSS for rendering, instead of adding new transforms for each frame, you need to update the transform property on each frame instead. You probably want to grab the math matrix library (e.g. http://glmatrix.net/ ) and then apply and store your transforms in JavaScript variables and only push the final computed transform to CSS to render (update, not add).



At this point, you can start solving the problem: you need to separate the rotation from the translation direction. The ultimate goal is to represent the ship, rotated at its own point of origin and translated into the correct world position, into 1 aggregate matrix that summarizes all transformations applied on the ship and in what order they are applied. There are several ways to do this. One very simple and common way to do this is to temporarily place your boat (via a transform) so that its origin (around which you want to rotate) is at 0, 0, apply a rotation transform, and then apply the final translation where you want the ship was actually. If you are using the matrix library as I suggested you should do this on the matrix,which represents the transformation of the ship.

I suggest you read about matrices and how they stack up, there are tons of game development tutorials that talk about this - and more specifically how you can transform transformation matrices = applied and pop out = undo (hint: subject rotation 0,0 I mentioned above that temporarily pushes a new transform which results in the total transformation position to 0.0, calculating the required ship rotation while under this transformation state and then pushing out the last transformation matrix = cancels the translation to 0, 0 which you only need temporarily).

Good luck!

+2


source







All Articles