Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Calin Leafshade on Thu 11/03/2010 20:15:06

Title: [OpenSource] AGSeggle! WiP
Post by: Calin Leafshade on Thu 11/03/2010 20:15:06
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.
Title: Re: [OpenSource] AGSeggle! WiP
Post by: Kweepa on Thu 11/03/2010 22:17:22
You can also check out this for some ball/peg action:
http://www.kweepa.com/step/ags/games/MegaDemo.zip
http://www.kweepa.com/step/ags/tech/megademosrc.zip
Title: Re: [OpenSource] AGSeggle! WiP
Post by: Khris on Thu 11/03/2010 22:18:16
Nice work!

Here's the code to calculate the reflection:

      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);
      }
Title: Re: [OpenSource] AGSeggle! WiP
Post by: Calin Leafshade on Thu 11/03/2010 22:34:49
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...

Title: Re: [OpenSource] AGSeggle! WiP
Post by: Khris on Thu 11/03/2010 22:57:09
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.