title: How to make ball bounce off wall with PyGame?
body: <p>Before you criticize me for not Googling or doing research before asking, I <strong>did</strong> research beforehand but to no avail.</p>
  <p>I am trying to create the Atari Breakout game. I am currently stuck with making the ball bounce off walls. I did research on this and I found a lot of blogs and YouTube videos (and also Stack Overflow questions: <a href="https://stackoverflow.com/questions/54256104/how-to-make-ball-bounce-off-triangle-in-pygame">this</a> and <a href="https://stackoverflow.com/questions/36368857/how-to-make-ball-bounce-off-paddle">this</a>) talking about PyGame's vector2 class. I also read the PyGame documentation on vector2 but I can't figure out how to make it work.</p>
  <p>I am currently writing a script to make the ball bounce off walls. In the beginning, the player is requested to press the spacebar and the ball will automatically move towards the north-east direction. It should bounce off the top wall when it hits it, but instead, it went inside. This is my approach:</p>
  <pre><code>import pygame
  pygame.init()
  
  screenWidth = 1200
  screenHeight = 700
  
  window = pygame.display.set_mode((screenWidth,screenHeight))
  pygame.display.set_caption('Atari Breakout')
  
  class Circle():
  
      def __init__(self, x, y, radius):
          self.x = x
          self.y = y
          self.radius = radius
          self.vel_x = 1
          self.vel_y = 1
  
  
  def check_hit():
      global hit
      if (((screenWidth-box.x)&lt;=box.radius) or ((box.x)&lt;=box.radius) or ((box.y)&lt;=box.radius) or ((screenHeight-box.y)&lt;=box.radius)):
          # meaning  hit either four walls
          if (((screenWidth-box.x)&lt;=box.radius) or ((box.x)&lt;=box.radius)):
              # hit right, left
              print('hit right, left')
              hit = True
          elif (((box.y)&lt;=box.radius) or ((screenHeight-box.y)&lt;=box.radius)):
              # hit top, bottom
              print('hit top, bottom')
              hit = True
              
  
  # main loop
  run = True
  box = Circle(600,300,10)
  hit = False
                                                    # (screenWidth-box.x)&lt;=box.radius     hit right wall
  while run:                                        # (box.x)&lt;=box.radius                 hit left wall
                                                    # (box.y)&lt;=box.radius                 hit top wall                        
      pygame.time.Clock().tick(60)                  # (screenHeight-box.y)&lt;=box.radius    hit bottom wall
  
      for event in pygame.event.get():
          if event == pygame.QUIT:
              run = False
  
      keys = pygame.key.get_pressed()
  
      if keys[pygame.K_SPACE] and (box.y)&gt;box.radius:
          while True:
              box.y -= box.vel_y        
              box.x += box.vel_x
  
              window.fill((0,0,0))
              pygame.draw.circle(window, (44,176,55), (box.x, box.y), box.radius)
              pygame.display.update()
  
              check_hit()
              if hit == False:
                  continue
              elif hit == True:
                  break
  
          if (box.y)&lt;=box.radius or (screenHeight-box.y)&lt;=box.radius:
              # hit top, bottom
              box.vel_x *= 1
              box.vel_y *= -1
              print('changed')
  
              if (box.y)&lt;=box.radius:
                  # hit top
                  print('hi')
                  while True:
                      box.x += box.vel_x               # &lt;-- myguess is this is the problem
                      box.y += box.vel_y
  
  
                      window.fill((0,0,0))
                      pygame.draw.circle(window, (44,176,55), (box.x, box.y), box.radius)
                      pygame.display.update()
                  
  
  
  
          elif (screenWidth-box.x)&lt;=box.radius or (box.x)&lt;=box.radius:
              # hit right, left
              box.vel_x *= -1
              box.vel_y *= 1
  
  
  
  
  
  
      window.fill((0,0,0))
      pygame.draw.circle(window, (44,176,55), (box.x, box.y), box.radius)
      pygame.display.update()
  
  
      print('Where are you going')
  
  pygame.quit()
  </code></pre>
  <p>I guess the problem is where I marked.  Which is here:</p>
  <pre><code>        if (box.y)&lt;=box.radius or (screenHeight-box.y)&lt;=box.radius:
              # hit top, bottom
              box.vel_x *= 1
              box.vel_y *= -1
              print('changed')
  
              if (box.y)&lt;=box.radius:
                  # hit top
                  print('hi')
                  while True:
                      box.x += box.vel_x               # &lt;-- myguess is this is the problem
                      box.y += box.vel_y
  
  
                      window.fill((0,0,0))
                      pygame.draw.circle(window, (44,176,55), (box.x, box.y), box.radius)
                      pygame.display.update()
  </code></pre>
  <p>but I don't know why. My theory is: the ball travels upwards, it hit the top wall, <code>check_hit()</code> kicks in and make <code>hit</code> = True, then the <code>vel_x</code> and <code>vel_y</code> is changed accordingly (if hit top wall, <code>vel_x</code> should remain the same while <code>vel_y</code> should be multiplied by -1). Then it will move down, hence &quot;bounce&quot; off the top wall.</p>
  <p><strong>Note:</strong> for now I only have the top wall working. The other three will be done when I can figure out how to bounce off the top wall first.</p>
  <p>Can you help me see what's the problem? And if this kind of operation requires the use of the vector2 class, can you explain it to me or give me a place to learn it?</p>