Python Ball Physics Problem

I am trying to correctly throw the ball in the box, especially when processing angles at a certain angle and processing the angular head. I have a problem because my ball goes out of the box all the time. I have this function which says that my ball is out of the box and it processes corners and walls. The code looks like this:

if ((self._x > self._Grid.getWidth()) or (self._x < 0)): print("RandomNode:outside paramaters: x! self._x = %s , self._velx = %s" % (self._x , self._velx)) if ((self._y > self._Grid.getLength()) or (self._y < 0)): print("RandomNode:outside paramaters: y!") if ((self._velx + self._x) > self._Grid.getWidth()): diff = self._Grid.getWidth()-self._x self._velx *= -1 if (diff == 0): self._x -= self._velx else: self._x+= diff tampered = True #print("eqn1: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) if (self._velx + self._x < 0): diff = self._x self._velx *= -1 if (diff == 0): self._x += self._velx else: self._x-= diff tampered = True #print("eqn2: self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) if ((self._vely + self._y) > self._Grid.getLength()): diff = self._Grid.getLength()-self._y self._vely *= -1 if (diff == 0): self._y -= self._vely if (tampered == True): if ((self._velx * -1 == self._vely) or (self._velx == self._vely)): self._x += self._velx self._y += self._vely #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._x += (self._velx - diff) self._y += self._vely #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: tampered = True #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._y+= diff if (tampered == True): if ((self._velx * -1 == self._vely) or (self._velx == self._vely)): self._x += self._velx self._y += self._vely #print("eqn31:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._x += (self._velx - diff) self._y += self._vely #print("eqn32:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: tampered = True #print("eqn33:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) if (self._vely + self._y < 0): diff = self._y self._vely *= -1 if (diff == 0): self._y += self._vely if (tampered == True): if ((self._velx * -1 == self._vely) or (self._velx == self._vely)): self._x += self._velx self._y += self._vely #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._x += (self._velx + diff) self._y += self._vely #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: tampered = True #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._y-= diff if (tampered == True): if ((self._velx * -1 == self._vely) or (self._velx == self._vely)): self._x += self._velx self._y += self._vely #print("eqn41:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: self._x += (self._velx + diff) self._y += self._vely #print("eqn42:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) else: tampered = True #print("eqn43:self._x = %s , self._y = %s , self._velx= %s, self._vely= %s" % (self._x, self._y, self._velx, self._vely)) return tampered 

I do not know why it does not work. x and y are obviously its coordinates. Velx and Vely are the speeds of x and y. Tampered is a boolean that prevents the ball from moving correctly and only moving within the test.

Here is my question. What is wrong with this code? OR .... is there a template written in python somewhere on the net or somewhere else, or the code you used that does what I'm trying to process and do? Please make changes to the code, just let me know. Any links to this have already been resolved. Thanks.

+4
source share
2 answers

Rewrite this code. This is too complicated for the simple problem you are trying to solve.

The first , 2D ball movement is just 2 1D problems. You can completely separate X and Y. For example, hitting a corner is completely equivalent to hitting the wall along the X axis + hitting the wall along the Y axis. Hitting the wall in X just changes the speed of X (and maybe loses some energy if you want to simulate this ) Pressing the wall in Y changes the speed of Y.

Second , since the handling of X and Y is so similar, extract the method from it

 def handle_axis_movement(location, velocity): "returns updated location and velocity" ... self.x, self.vel_x = handle_axis_movement(self.x, self.vel_x) self.y, self.vel_y = handle_axis_movement(self.y, self.vel_y) 

This will reduce the amount of code (and errors) in half.

Third , you do not need to consider diff == 0 and diff <0 separately. Both cases mean that the ball hits the wall and must deflect its speed. You must then correct the location to account for the fact that it could not pass through the wall.

 location += velocity if location > max_bound: location = max_bound - (location - max_bound) velocity *= -1 if location < min_bound: location = min_bound - (location - min_bound) velocity *= -1 
+7
source

You should not reinvent this wheel when pymunk does it so well for you.;)

+1
source

All Articles