[OpenSource] AGSeggle! WiP

Started by Calin Leafshade, Thu 11/03/2010 20:15:06

Previous topic - Next topic

Calin Leafshade

This is something I was fiddling around with this morning and it's very unlikely I'll finish it so I thought I would release the engine code in case anyone wants to make a mini game out of it.

The collision code is not perfect since I couldn't figure out the resultant vector for the collision so it currently has a bit of a guess based on the collision point on the circular pegs which unfortunately ignores the angle of incidence.

Engine: http://www.thethoughtradar.com/AGS/AGSeggle.zip
Src: http://www.thethoughtradar.com/AGS/Agsegglesrc.zip

EDIT: Oh, forgot to mention what it is.. Its a Peggle clone.

EDIT2: Actually I enclosed the PPCollision module in the source by accident.. The module isnt actually used for anything and can be safely removed from the project.

Kweepa

Still waiting for Purity of the Surf II

Khris

Nice work!

Here's the code to calculate the reflection:

Code: ags
      if(DistanceBetween(MainBall.Obj, Pegs[i].Obj) < BallSize){
        
        // set vector m to ball center -> peg center
        float mx = IntToFloat(Pegs[i].Obj.X) - MainBall.x;
        float my = IntToFloat(Pegs[i].Obj.Y) - MainBall.y;
        
        // vector w, the "wall" the ball is reflected by, is perpendicular to m
        // exchange x & y, and since direction doesn't matter, negate either x or y
        float wx = my;
        float wy = -mx;
        
        // now express ball direction using wall vector and perpendicular vector
        // speed = a*w + b*m
        float a = (MainBall.speedx*my - MainBall.speedy*mx) / (my*wx - mx*wy);
        float b = (MainBall.speedx*wy - MainBall.speedy*wx) / (mx*wy - my*wx);
        
        // negate b to reflect ball by vector w
        b = -b;
        
        // calulate new speed vector
        MainBall.speedx = ((a*wx) + (b*mx) * Damping);
        MainBall.speedy = ((a*wy) + (b*my) * Damping);
        
        // calculate ball's position at time of impact
        float mlen = Maths.Sqrt(mx*mx + my*my);
        MainBall.x = IntToFloat(Pegs[i].Obj.X) - (mx*BallSize)/mlen;
        MainBall.y = IntToFloat(Pegs[i].Obj.Y) - (my*BallSize)/mlen;
      
        KillPeg(i);
      }

Calin Leafshade

Thanks for that Khris, that's much better.

The main reason I keep doing these little projects is to improve my programmatic mathematics skills so it's really helpful to look at the way you've done it and AGS is a pretty much perfect testing ground for stuff like this.

I may finish it eventually but i think to make a decent game out of it i'd need to add some polygonal bodies in there just to keep things interesting.. more physics.. yay...


Khris

Adding polygons is merely extending the existing code.

Say there's a polygon somewhere. The ball will either hit a side or a corner. Hitting a corner is the same as hitting a ball with radius 0. The only difference is the distance here.
Hitting a side requires just one additional step; calculate the point of impact, then go on as if there was a ball with radius 0 again.

To calculate the point of impact, iterate through the sides.
Say the side is [AB].
Straight line AB expressed using vectors: (A-0) + k*(B-A)
Normalize (B-A) by dividing it by its length.

Now let Ballposition + n*Ballspeed = A + k*(B-A)n
This gives you k. If 0 < k < length of [AB], the ball will hit the side.

SMF spam blocked by CleanTalk