-2

I am having trouble with the exercise where you modify the already-coded game "Catch" to make it into a pong-type game. For context, see here in the section at the bottom titled "8.13. Project: pong.py".

The ball seems to zig-zag randomly. For a better picture, the ball may bounce off of one paddle and, at an arbitrary point in its path to the other side, will (sometimes hover a little) and travel back to the side it had started from. I can't figure out why or how to fix it. What part of my code is making it do that?

I have rearranged elements of the while loop in the play_round function, thinking maybe I was misunderstanding the flow of execution, and nothing improved. Is the problem an incompatibility b/w the program and the frame rate?

I am new to programming and have spent an unfortunate number of hours trying to fix this already, so I thought I'd come here and ask for help.

from gasp import *

COMPUTER_WINS = 1
PLAYER_WINS = 0
QUIT = -1


def hit(bx, by, r, px, py, h):
    if py <= by <= (py + h) and bx >= px - r:
        return True
    else:
        return False

def play_round():
    bx = 400
    by = 300
    ball = Circle((bx, by), 10, filled=True)
    r = 10
    dx = random_between(-4, 4)
    dy = random_between(-5, 5)

    px = 780
    py = random_between(30, 270)
    paddle = Box((px, py), 20, 50)
    h = 30

    px2 = 20
    py2 = random_between(30, 270)
    paddle2 = Box((px2, py2), 20, 50)
    h2 = 30

    while True:
        if by >= 590 or by <= 10:
            dy *= -1
        bx += dx
        by += dy
        if bx >= 810:
            remove_from_screen(ball)
            remove_from_screen(paddle)
            remove_from_screen(paddle2)
            return COMPUTER_WINS
        move_to(ball, (bx, by))

        if key_pressed('k') and py <= 570:
            py += 5
        elif key_pressed('j') and py > 0:
            py -= 5

        if hit(bx, by, r, px, py, h):
            dx *= -1

        if key_pressed('escape'):
            return QUIT

        move_to(paddle, (px, py))

        if key_pressed('a') and py2 <= 570:
            py2 += 5
        elif key_pressed('s') and py2 > 0:
            py2 -= 5

        move_to(paddle2, (px2, py2))

        if hit(bx, by, r, px2, py2, h2):
            dx *= -1

        if bx <= -10:
            remove_from_screen(ball)
            remove_from_screen(paddle)
            remove_from_screen(paddle2)
            return PLAYER_WINS

        update_when('next_tick')


def play_game():
    player_score = 0
    comp_score = 0

    while True:
        pmsg = Text("Player: %d Points" % player_score, (10, 570), size=24)
        cmsg = Text("Computer: %d Points" % comp_score, (640, 570), size=24)
        sleep(3)
        remove_from_screen(pmsg)
        remove_from_screen(cmsg)

        result = play_round()

        if result == PLAYER_WINS:
            player_score += 1
        elif result == COMPUTER_WINS:
            comp_score += 1
        else:
            return QUIT

        if player_score == 5:
            return PLAYER_WINS
        elif comp_score == 5:
            return COMPUTER_WINS


begin_graphics(800, 600, title="Catch", background=color.YELLOW)
set_speed(120)

result = play_game()

if result == PLAYER_WINS:
    Text("Player Wins!", (340, 290), size=32)
elif result == COMPUTER_WINS:
    Text("Computer Wins!", (340, 290), size=32)

sleep(4)

end_graphics()
Brigand
  • 84,529
  • 20
  • 165
  • 173

1 Answers1

0

Let's look at the hit function. Remember that r is 10.

def hit(bx, by, r, px, py, h):
    if py <= by <= (py + h) and bx >= px - r:
        return True
    else:
        return False

This part py <= by <= (py + h) asks "Is the top of the ball between the top edge of the paddle, and the top edge +10px?", which is far to strict, because I believe the padel is in fact 50px tall.

This part bx >= px - r asks, "Is the ball to the right of the left edge of this paddle?" That sounds okay, but it's always to the right of the leftmost paddle, and this function is called for each of them.

A hit function usually asks for x1, y2, x2, y2, tx1, ty1, tx2, ty2. Basically, the top-left and bottom right points of each object. Alternatively the x2,y2,tx2,ty2 can be replaced with w,h,tw,th (width and height).

Try writing it out on paper first if you're new to Python. Draw it, do some examples on paper, then write the code, and see if those examples work. If you still have trouble, but have at least attempted it, ask another question. Other than that, your code looks fine.

Brigand
  • 84,529
  • 20
  • 165
  • 173