Himo Posted January 6, 2005 Posted January 6, 2005 Hi, I'm making this pinball game, just to further hone my gamemaking skills. I'm first trying to figure out how things like bouncing works. I got this form with one object on it(An Image) and the ball(PC(Player Character). I'm trying to let the ball bounce of the image at an angle, but this only works with the form. It just passes through the Image(Slightly changing it's angle) and doesn't arc of in the opposite way like he does when colliding with the form. Below I posted my phsyics piece. Thanks for your help :) Notes: Objects[] is an PictureBox array that holds all the object that are on the table(like bumps and blackholes) vspeed is the vertical speed hspeed is the horizontal speed pc is the ball(a PictureBox) angle is the angle in degrees radians is that translated into radians public void mover_Tick(object sender, System.EventArgs e) { pc.Top+=vspeed; pc.Left+=(int)(hspeed*Math.Tan(radians)); if((pc.Top<=0))//Top vspeed=(-vspeed); if((pc.Top + pc.Height + this.Top)>=(this.Bounds.Bottom))//Bottom vspeed=(-vspeed); if((pc.Left<=0))//Left hspeed=(-hspeed); if((pc.Left + pc.Width + this.Left)>=(this.Bounds.Right))//Right hspeed=(-hspeed); if(vspeed>20) vspeed=5; if(vspeed<(-20)) vspeed=(-5); if(hspeed>20) hspeed=5; if(hspeed<(-20)) vspeed=(-5); if(pc.Bounds.IntersectsWith(objects[0].Bounds)) { if(pc.Bounds.Bottom>objects[0].Bounds.Top) { vspeed=(-vspeed); vspeed+=5; angle+=5; radians = angle * (Math.PI/180); } if(pc.Bounds.Top<objects[0].Bounds.Bottom) { vspeed=(-vspeed); vspeed+=5; angle-=15; radians = angle * (Math.PI/180); } if(pc.Bounds.Left<objects[0].Bounds.Right) { hspeed=(-hspeed); hspeed+=5; angle-=20; radians = angle * (Math.PI/180); } if(pc.Bounds.Right>objects[0].Bounds.Left) { hspeed=(-hspeed); hspeed+=5; radians = angle * (Math.PI/180); } } } Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Leaders Iceplug Posted January 7, 2005 Leaders Posted January 7, 2005 So, when the pc collides with the object, you want it to rebound off of the object right? Well, a pretty good way to do this is to do either your horizontal or vertical movement all at once, but not both. Between the horizontal and vertical movement phases, you check if they collide. // Horizontal movement code. if (pc.IntersectsWith(obj[0]) { // horizontal collision... invert the horizontal speed. angle = 180 - angle hspeed = -hspeed // or however you are doing it. } // vertical movement code if (pc.IntersectsWith(obj[0]) { // vertical collision... invert the vertical speed. angle = -angle vspeed = -vspeed // or however you are doing it. } :) Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Himo Posted January 10, 2005 Author Posted January 10, 2005 And what about integrating downfall gravity? I think it should be something like this: Fres = (Fup - Fg) * tan(angle) Fres = 1/2*v^2 v = Math.Sqrt(2*Fres) Where Fres is the resulting power vector you get when substracting the gravitational force from the upgoing force.(As in Fup = 1/2*v^2 and Fg = g*height, because mass is static I left it out) I'm I somewhere right? Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Himo Posted January 10, 2005 Author Posted January 10, 2005 (edited) An update on my function, now trying to incorporate gravity. This goes horribly wrong, but this way you can take a look at my thoughts. Edit: Did the seperate axis collission detection, but now I don't know anymore which axis I have to invert what for. :o Btw: Is it practical to have a vertical and horizontal speed? On gamedev.net hey said no, but I see no other option, because my collision detection is dependant on it. public void mover_Tick(object sender, System.EventArgs e) { double Fres = ((0.50 * Math.Pow(speed,2))-(((this.Height-pc.Top)/20.00)*g)); if(Fres<0) vspeed = (-(int)Math.Sqrt(2*(-Fres))); else vspeed = (int)Math.Sqrt(2*Fres); hspeed=(int)(vspeed * Math.Cos(radians)); if((pc.Top<=0))//Top vspeed=(-vspeed); if((pc.Top + pc.Height + this.Top)>=(this.Bounds.Bottom))//Bottom vspeed=(-vspeed); if((pc.Left<=0))//Left hspeed=(-hspeed); if((pc.Left + pc.Width + this.Left)>=(this.Bounds.Right))//Right hspeed=(-hspeed); pc.Top-=vspeed; pc.Left-=hspeed; if(pc.Bounds.IntersectsWith(objects[0].Bounds)) { Random temp = new Random(); if(pc.Bounds.Bottom>objects[0].Bounds.Top) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); } if(pc.Bounds.Top<objects[0].Bounds.Bottom) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); } Fres = ((0.50 * Math.Pow(speed,2))-(((this.Height-pc.Top)/20.00)*g)); if(Fres<0) vspeed = (-(int)Math.Sqrt(2*(-Fres))); else vspeed = (int)Math.Sqrt(2*Fres); pc.Top+=vspeed; } if(pc.Bounds.IntersectsWith(objects[0].Bounds)) { Random temp = new Random(); if(pc.Bounds.Left<objects[0].Bounds.Right) { hspeed=(-hspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); pc.Top-=vspeed; } if(pc.Bounds.Right>objects[0].Bounds.Left) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); pc.Top-=vspeed; } Fres = ((0.50 * Math.Pow(speed,2))-(((this.Height-pc.Top)/20.00)*g)); if(Fres<0) hspeed = (-(int)Math.Sqrt(2*(-Fres)* Math.Cos(radians))); else hspeed = (int)(Math.Sqrt(2*Fres) * Math.Cos(radians)); pc.Left+=hspeed; } } Edited January 10, 2005 by Himo Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Leaders Iceplug Posted January 10, 2005 Leaders Posted January 10, 2005 double Fres = vspeed * vspeed / 2R - (this.Height-pc.Top) * g; // That's energy. vspeed=(int)Math.Sqrt(Fres+Fres); hspeed=(int)(Fres * Math.Tan(radians)); But for implementing gravity, seems like all you'd need to do is add some value to the vspeed at every tick. vspeed += gangle; // Where gangle represents the downward acceleration at this board leveling angle due to gravity. You can make gangle whatever value looks good to you. It ultimately comes from the formula: mg * sin(boardlevelingangle) if you're interested. :) P.S. Yes, I think it is practical to have horizontal and vertical speed at times. Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Himo Posted January 10, 2005 Author Posted January 10, 2005 (edited) *Bounces off chair So you say, my formula is essentially worthless? :p Damn, anymore tips before I start coding another stupid formula? (I'm trying this while highschool proved an physics average of D+(5 out 10)) Edit: When testing my speed remains the same, but the object seems to go faster anyways. Does this has something to do with the angle? How can this be prevented? Edited January 10, 2005 by Himo Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Leaders Iceplug Posted January 12, 2005 Leaders Posted January 12, 2005 *shrug* Perhaps it's because you aren't spending all of your time calling all of those Trig functions. ;) The part about adding a portion to the vspeed will likely cause the ball to move faster in the vertical direction, but aside from that, I don't see much change that it'd make at the moment. Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Himo Posted January 13, 2005 Author Posted January 13, 2005 Okay, I've implemented the gravity in the example, but now when I hit the sample bumper, my collision detection goes wacky and my gravity is reversed. :confused: How can I adjust the gravitational force correct when hitting an object? It works on walls... My gravity mechanism is a variable that is decremented each time the movement is calculated when more then 0, the ball goes up, when less then 0 then ball goes down. When hitting the bottom, it's 'energy' is refueled. public void mover_Tick(object sender, System.EventArgs e) { //double Fres = ((0.50 * Math.Pow(speed,2))-(((this.Height-pc.Top)/20.00)*g)); pc.Top+=(int)(vspeed * (gforce / (Convert.ToDouble(multiplier)*speed))); pc.Left+=(int)(hspeed * Math.Tan(radians)); if((pc.Top<=0))//Top vspeed=(-vspeed); if((pc.Top + pc.Height + this.Top)>=this.Bounds.Bottom)//Bottom { vspeed=(-vspeed); gforce = speed * multiplier; pc.Top=this.Height - pc.Height; } if((pc.Left<=0))//Left hspeed=(-hspeed); if((pc.Left + pc.Width + this.Left)>=this.Bounds.Right)//Right hspeed=(-hspeed); gforce-=speed; if(pc.Bounds.IntersectsWith(objects[0].Bounds)) { Random temp = new Random(); if(pc.Bounds.Left<=objects[0].Bounds.Right) { hspeed=(-hspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); pc.Top-=vspeed; pc.Left+=(int)(hspeed * Math.Tan(radians)); } if(pc.Bounds.Right>=objects[0].Bounds.Left) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); pc.Top-=(int)(vspeed * (gforce / (Convert.ToDouble(multiplier)*speed))); } } if(pc.Bounds.IntersectsWith(objects[0].Bounds)) { Random temp = new Random(); if(pc.Bounds.Bottom>=objects[0].Bounds.Top) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); } if(pc.Bounds.Top<=objects[0].Bounds.Bottom) { vspeed=(-vspeed); angle+=temp.Next(-10,10); radians = angle * (Math.PI/180); pc.Top-=(int)(vspeed * (gforce / (Convert.ToDouble(multiplier)*speed))); } } } Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Leaders Iceplug Posted January 17, 2005 Leaders Posted January 17, 2005 Gravity should be constant... why are you changing it? Tilt? :p But, why are you using: pc.Top+=(int)(vspeed * (gforce / (Convert.ToDouble(multiplier)*speed))); pc.Left+=(int)(hspeed * Math.Tan(radians)); instead of just: pc.Top+= vspeed; pc.Left+= hspeed; ? and then, it seems pretty odd for a horizontal check if(pc.Bounds.Right>=objects[0].Bounds.Left) to cause the vspeed to change. Let me know if any of those fix the reverse gravity. :) Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Himo Posted January 18, 2005 Author Posted January 18, 2005 I did it! I have created life from nought! In normal terms, I finally got it to work. Thanks for all your tips, iceplug. For all you guys around, I attached my sample project for all to see and learn from. Note to the mods: There's still a /bin/debug directory there because there are some picture files in it. I was to lazy to check for the actual program directory when loading the pictures, so this has to do. ;) pinball.zipFetching info... Quote For questions about VS .net extensibility, please fire at me! :) For readability, please use the [ CS][/CS ] tags
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.