views:

215

answers:

1

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.

+3  A: 

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.

eBusiness
I don't really understand how to construct a vector in javascript, although I see there are some libraries.So a position and velocity vector... Where in the matrix does each value go? [posX, posY, speed]? I've read that wiki page, and I'm looking at the vector math in Javascript, but I have some sort of disconnect as how to represent velocity using a vector.Thanks a bunch btw... I'll be trying to decode your post for a while i think :D
Ok, I think I understand now. What is A.m? A's mass? That's not a vector quantity is it? If not, how do I add a vector to a normal number (or is that a dumb question)
Also, how do you do vector division?
Ok, I think I have it all down, save the vector division. What operation should I do?
There is no definition of vector division, but you can divide a vector by a number. |A| (on Wikipedia it's written as ||A||) is the length of vector A, so obviously |A.p-B.p| is a number. And I'm glad to hear that you need to use your thinker, it wouldn't be fun if I gave you all the answers would it?
eBusiness
No, no it wouldn't! And I'm glad you see im not digging for the answers. Ok, I had already figured out |A.p-B-p| being a number... But I'm feeling that B.v is going to be a number!So far I have: var tempvect = this.s.vect.x( gobjs[i].s.position.subtract(this.s.position) ) / Math.pow(gobjs[i].s.position.distanceFrom(this.s.position), 3);I'm missing the +A.m, because i'm not sure what B.v is to add it to, and I still can't figure out how to add a number to a vector (in the case that A.m is mass and mass is a number).
Ok, B.v is velocity, and that is a vector, A.m is mass, that is a number, it is multiplied by the vector (A.p-B.p), number by vector gives vector. Maybe it will help if I rewrite it a bit.
eBusiness