Question

I'm making a simple pong game and I've written the majority of the code.

The problem is, once the ball falls, if you continue to move the paddle, it will bounce back up into the screen from the bottom. I need it to stay off the screen permanently once it misses the paddle.

Any feedback is appreciated! Thanks in advance!

L1_base.py (my base code):

import math
import random
import sys, pygame
from pygame.locals import *

import ball
import colors
import paddle

# draw the scene
def draw(screen, ball1, paddle1) :
   screen.fill((128, 128, 128))
   ball1.draw_ball(screen)
   paddle1.draw_paddle(screen)

#function to start up the main drawing
def main():

   pygame.init()
   width = 600
   height = 600
   screen = pygame.display.set_mode((width, height))

   ball1 = ball.Ball(300, 1, 40, colors.YELLOW, 0, 4)
   paddle1 = paddle.Paddle(200, 575, colors.GREEN, 100, 20)

   while 1:
      for event in pygame.event.get():
         if event.type == QUIT: sys.exit()
         elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
               paddle1.update_paddle('right', 35)
            if event.key == pygame.K_LEFT:
               paddle1.update_paddle('left', 35)

      ball1.test_collide_top_ball(0)
      ball1.test_collide_bottom_ball(600, paddle1)
      ball1.update_ball()
      draw(screen, ball1, paddle1)
      pygame.display.flip()

if __name__ == '__main__':
   main()

ball.py (contains ball class/methods):

import pygame

class Ball:
   def __init__(self, x, y, radius, color, dx, dy):
      self.x = x
      self.y = y
      self.radius = radius
      self.color = color
      self.dx = dx
      self.dy = dy

   def draw_ball(self, screen):
      pygame.draw.ellipse(screen, self.color,
         pygame.Rect(self.x, self.y, self.radius, self.radius))

   def update_ball(self):
      self.x += self.dx
      self.y += self.dy

   def test_collide_top_ball(self, top_height):
      if (self.y <= top_height) and (self.dy < 0):
         self.dy *= -1

   def test_collide_bottom_ball(self, coll_height, paddle):
      if (self.y >= coll_height - self.radius - (600 - paddle.y)) and (self.x  >= paddle.x) and (self.x <= paddle.x + paddle.width) and (self.dy > 0):
         self.dy *= -1

paddle.py (contains paddle class/methods):

import pygame

class Paddle:
   def __init__(self, x, y, c, w, h):
       self.x = x
       self.y = y
       self.color = c
       self.width = w
       self.height = h

   def draw_paddle(self, screen):
      pygame.draw.rect(screen, self.color,
         pygame.Rect(self.x, self.y, self.width, self.height), 0)

   def update_paddle(self, dir, dx):
      if (dir == 'left'):
         self.x = max(self.x - dx, 0)
      else:
         self.x = min(self.x + dx, 600 - self.width)

   def get_left(self):
      if (self.x < 300):
         return self.x

   def get_right(self):
      if (self.x >= 300):
         return self.x
Was it helpful?

Solution

You tried to cram too much stuff into one if statement in test_collide_bottom_ball and that made debugging much harder. Its also easier in this case to consider all the reasons not to self.dy *= -1 over the reasons you should. That switching of directions is a privilege paddle and should only happen on special occasions.

I have left my debugging code in to clarify the way i thought about the problem, also there is still another bug which can get the ball stuck in the paddle, but you should be able to fix that given a similar approach. Please see the following code:

 def test_collide_bottom_ball(self, coll_height, paddle):
    print paddle.x, paddle.width + paddle.x, self.x

    # shoot ball back to top when it has gone off the bottom
    if self.y > 600:
       self.y = 300
       return

    # ignore when the ball is far from the y access of the paddle
    if not self.y >= coll_height - self.radius - (600 - paddle.y):
       return

    # check that the current x plus raidus to find "too small" condition
    if self.x + self.radius <= paddle.x:
       print "self.x too small"
       return

    # for too big we have to consider the paddle width
    if self.x >= paddle.x + paddle.width:
       print "self.x too big"
       return

    # ok, looks like its time to switch directions!
    self.dy *= -1

P.S. use the pep8 coding standard utility. Its not any harder to code following pep8 and will save you headache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top