title: JavaScript, 2D game engine: Oscillate angle (up, right, down, left) to match diagonal movements based on difference between X and Y velocity
body: <p>I'll do my best to explain exactly what I need first, this is a slightly complicated one (hence why I need the help) but I'm hoping I can illustrate the situation accordingly. This is referring to a single problem with a clear and simple code case below, knowing many questions get closed for not being focused and I'd like help with an answer here please.</p>
  <p>I'm working on a game engine in HTML5 with a top-down world (RPG). The relevant part is characters which use standard sprites with 4 directions (up, down, left, right). Sprite animations are set using CSS which works fine and isn't the focus here, the important part is the JavaScript function used to determine and apply the angle.</p>
  <p>Currently I set one angle based on velocity, so the sprite faces in the direction it's moving toward the fastest. It works great but I want something more: When there's diagonal movement, the angle should alternate between those X and Y directions, spending more time in whichever has the highest velocity over the other.</p>
  <p>A representation of my system which I'm trying to integrate this change in. We have an array with two values for X and Y velocity, for example <code>[0.25, -0.5]</code> means 0.25 horizontal velocity and -0.5 vertical velocity. The angle is stored as an integer with four values representing the clockwise orientation: 0 = up, 1 = right, 2 = down, 3 = left. This is the function I use to fetch the angle from the velocity, <code>undefined</code> gets returned when there's no speed so we want no change... it works well in retrieving a fixed angle from the fastest direction:</p>
  <pre><code>// Velocity: [0] = x, [1] = y
  // Angle: 0 = top, 1 = right, 2 = bottom, 3 = left
  function vec2ang(vec) {
      if(-vec[1] &gt; Math.abs(vec[0]))
          return 0; // up
      if(+vec[0] &gt; Math.abs(vec[1]))
          return 1; // right
      if(+vec[1] &gt; Math.abs(vec[0]))
          return 2; // down
      if(-vec[0] &gt; Math.abs(vec[1]))
          return 3; // left
      return undefined;
  }
  </code></pre>
  <p>What I'd like it to do: Let's say we have an X velocity of 0.5 and an Y velocity of 1.0. Right now this means Y wins over X so 2 (down) is always returned over 1 (right). Instead I want a looping cycle in which 2 (down) is returned twice and 1 (right) is returned once given 0.5 is half of 1.0 so we give it half the time (<code>2 2 1, 2 2 1, 2 2 1, ...</code>), if both were 1.0 or 0.5 the cycle would alternate between them equally (<code>2 1, 2 1, 2 1, ...</code>), and of course only one of them if there's zero velocity in the other. That check is preformed each frame as part of a <code>setInterval</code> function... also note this example refers to a fixed speed but X and Y may change to any values each call typically transitioning slowly.</p>
  <p>I'm imagining there are two ways to achieve this: One is using some sort of counter, the other is passing the system time (milliseconds) through a sine function and mapping the 0 to 1 oscillation to represent the gap between X and Y. For what I'm doing the later option seems best, no extra variable to store and it would dynamically adapt to changes in X or Y. But I'm not sure how to write the oscillator and <code>Math.sin</code> the value of <code>new Date().getTime()</code>, then give the dominant velocity a higher threshold so it's featured for longer. What is your advice in approaching such a problem?</p>