Search code examples
javascripthtmlcanvas

As mass goes up, speed goes down


Trying to develop an Agar clone, and I've got a lot of it, but I can't quite figure out how to decrement the player's speed as its mass increases. I've tried several different ways, but nothing works. How would I make the speed go down as the mass goes up? Here's my jsFiddle. This is where I set the speed of of the players:

var playerOneMass = 36;
var player1X = (canvas.width / 2) + 50;
var player = new Player({
    x: player1X,
    y: canvas.height / 2,
    radius: playerOneMass,
    speed: {
        x: 5,
        y: 5
    },
    name: "player 1",
    dir: null
});
var playerTwoMass = 36;
var player2X = (canvas.width / 2) - 50;
var player2 = new Player({
    x: player2X,
    y: canvas.height / 2,
    radius: playerTwoMass,
    speed: {
        x: 5,
        y: 5
    },
    name: "player 2",
    dir: null
});

Solution

  • Let us bring some math in to help us out a little bit. When you want something to grow smaller as another grows bigger, the best option that I have found is to use an inversely proportional relationship. This will allow a smooth smaller and smaller look for you.

    new_speed = scalar * start_speed / current_mass
    

    When coming up with the scalar, I have found it best to trial and error until it looks how you want it to.


    Here is an example of the equation in action utilizing Two.js.

    var two    = new Two({width:320, height:180}).appendTo(document.getElementById("mytwo")),
        rect   = two.makeRectangle(100, 100, 10, 10),
        circ   = two.makeCircle(5, 100, 5),
        mass   = 10,
        rspeed = Math.PI / 10,
        mspeed = 14,
        scalar = 10;
    // Make it look pretty!
    rect.fill = "rgb(100,255,100)";
    circ.fill = "rgb(100,100,255)";
    // Looping...
    two.bind('update', function(fc) {
      // Prevents from growing indefinitely
      if(mass > 150) return;
      mass += 1.5;
      rect.scale += .1;
      circ.scale += .1;
      rect.rotation += scalar * rspeed / mass;
      circ.translation.addSelf(new Two.Vector(
           scalar * mspeed / mass, 0));
    }).play();
    <script src="https://cdn.jsdelivr.net/npm/two.js@latest"></script>
    
    <div id="mytwo"><div></div></div>