Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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);
			}
		}
	}

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

  • Leaders
Posted

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.

}

 

:)

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted

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?

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

Posted (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 by Himo

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

  • Leaders
Posted

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.

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted (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 by Himo

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

  • Leaders
Posted

*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.

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted

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)));
			}			
		}

	}

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

  • Leaders
Posted

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. :)

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted

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.zip

For questions about VS .net extensibility, please fire at me! :)

For readability, please use the [ CS][/CS ] tags

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...