Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript phsyics in a 2d space

So, I am working on teaching myself Canvas (HTML5) and have most of a simple game engine coded up. It is a 2d representation of a space scene (planets, stars, celestial bodies, etc). My default "Sprite" class has a frame listener like such:

"baseClass" contains a function that allows inheritance and applies "a" to "this.a". So, "var aTest = new Sprite({foo: 'bar'});" would make "aTest.foo = 'bar'". This is how I expose my objects to each other.

Sprite = baseClass.extend({
  init: function(a){
    baseClass.init(this, a);
    this.fields = new Array(); // list of fields of gravity one is in. Not sure if this is a good idea.
    this.addFL(function(tick){ // this will change to be independent of framerate soon.

      // gobjs is an array of all the Sprite objects in the "world".
      for(i = 0; i < gobjs.length; i++){

        // Make sure its got setup correctly, make sure it -wants- gravity, and make sure it's not -this- sprite.
        if(typeof(gobjs[i].a) != undefined && !gobjs[i].a.ignoreGravity && gobjs[i].id != this.id){
          // Check if it's within a certain range (obviously, gravity doesn't work this way... But I plan on having a large "space" area,
          // And I can't very well have all objects accounted for at all times, can I?
          if(this.distanceTo(gobjs[i]) < this.a.size*10 && gobjs[i].fields.indexOf(this.id) == -1){
            gobjs[i].fields.push(this.id);
          }
        }
      }
      for(i = 0; i < this.fields.length; i++){
        distance = this.distanceTo(gobjs[this.fields[i]]); 

        angletosun = this.angleTo(gobjs[this.fields[i]])*(180/Math.PI); // .angleTo works very well, returning the angle in radians, which I convert to degrees here.

        // I have no idea what should happen here, although through trial and error (and attempting to read Maths papers on gravity (eeeeek!)), this sort of mimics gravity.
        // angle is its orientation, currently I assign a constant velocity to one of my objects, and leave the other static (it ignores gravity, but still emits it).
        // This cant be right, because it just _sets_ the angle regardless of whatever it was.
        // This is where we need to find "the average of the forces".
        this.a.angle = angletosun+(75+(distance*-1)/5); //todo: omg learn math

        if(this.distanceTo(gobjs[this.fields[i]]) > gobjs[this.fields[i]].a.size*10){
          this.fields.splice(i); // out of range, stop effecting.
        }
      }
    });

    //draw objects based on new position (from fixed velocity and angle).

  }
});

Thanks in advance. The real trick is that one line, and btw I know it makes no sense whatsoever. Degrees + distance = failure.

this.a.angle = angletosun+(75+(distance*-1)/5);

This is more a physics question than Javascript, but I've searched and searched and read way to many wiki articles on orbital mathematics. It gets over my head very quickly.

like image 509
user330123 Avatar asked Apr 30 '10 22:04

user330123


1 Answers

Oh, this takes me down memory lane, playing with physics simulation is so much fun.

In any case, it sounds like you need to get your vector maths polished, that is probably the matter of most importance, this article should contain everything you need to know about vector maths, though I'm not sure if it is the easiest available source. http://en.wikipedia.org/wiki/Euclidean_vector

Your code seems a bit over-object-oriented, of course that is much a matter of preference, but I'd stick to pure data objects and keep the logic in separate functions.

And here is a little physics maths to get you started, each object should have a position as a vector, a velocity as a vector, and mass.

For every tick you do two thing, for every object you add the velocity to the position:

p=p+v

And for every object with respect to every other object you change the velocity according to the calculated gravitational pull. B's velocity would change like so because of A's gravity well:

B.v=B.v+(A.p-B.p)*(A.m/(|A.p-B.p|^3))

Once you have cracked vector maths you should be able to translate this into real code.

like image 183
aaaaaaaaaaaa Avatar answered Sep 27 '22 16:09

aaaaaaaaaaaa