【问题标题】:Python Pong Collision Is UncooperativePython Pong 碰撞不合作
【发布时间】:2021-12-17 11:57:21
【问题描述】:

我正在用 Python 制作乒乓球游戏,但球没有与任何一个球拍发生碰撞。我发现了类似的问题,但它们似乎都不起作用。在随机点上,球似乎变慢了,但我无法将它与任何相关的东西关联起来,除非它是错误放置的碰撞箱的情况,在这种情况下我似乎无法发现异常值。

代码:

import os
import turtle as t

playerAscore = 0
playerBscore = 0

window = t.Screen()
window.title('Game of pongs the pong game pong the game game the pong pong pong pong the EmAG')
window.bgcolor('black')
window.setup(width=800, height=600)
window.tracer(0)


leftpaddle = t.Turtle()
leftpaddle.speed(0)
leftpaddle.shape('square')
leftpaddle.color('white')
leftpaddle.shapesize(stretch_wid=5, stretch_len=1)
leftpaddle.penup()
leftpaddle.goto(-270, 0)


rightpaddle = t.Turtle()
rightpaddle.speed(0)
rightpaddle.shape('square')
rightpaddle.color('purple')
rightpaddle.shapesize(stretch_wid=5, stretch_len=1)
rightpaddle.penup()
rightpaddle.goto(270, 0)


ball = t.Turtle()
ball.speed(0)
ball.shape('circle')
ball.color('red')
ball.penup()
ball.goto(1, 1)
ball_dx = 0.1
ball_dy = 0.1


pen = t.Turtle()
pen.speed(0)
pen.color('Pink')
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write('Score', align='center', font=('Shadows into Light', 24, 'normal'))



def leftpaddleup():
    y = leftpaddle.ycor()
    y = y + 90
    leftpaddle.sety(y)


def leftpaddledown():
    y = leftpaddle.ycor()
    y = y + -90
    leftpaddle.sety(y)



def rightpaddleup():
    y = rightpaddle.ycor()
    y = y + 90
    rightpaddle.sety(y)


def rightpaddledown():
    y = rightpaddle.ycor()
    y = y + -90
    rightpaddle.sety(y)



window.listen()
window.onkeypress(leftpaddleup, 'w')
window.onkeypress(leftpaddledown, 's')
window.onkeypress(rightpaddleup, 'Up')
window.onkeypress(rightpaddledown, 'Down')

while True:
    window.update()

    # mover of balls
    ball.setx(ball.xcor() + ball_dx)
    ball.sety(ball.ycor() + ball_dy)

    if ball.ycor() > 290:
        ball.sety(290)
    ball_dy = ball_dy * -1
    if ball.ycor() < -290:
        ball.sety(-290)
    ball_dy = ball_dy * -1

    if ball.xcor() > 390:
        ball.goto(0, 0)
        ball_dx = ball_dx * -1

        os.system("afplay wallhit.wav&")
    if (ball.xcor()) < -390:  # Left width paddle Border
        ball.goto(0, 0)
        ball_dx = ball_dx * -1

        os.system("afplay wallhit.wav&")

    # paddle collision

    if (ball.xcor() < -340) and (ball.xcor() > -350) and (
            paddle_right.ycor() + 40 > ball.ycor() > paddle_right.ycor() - 40):
        ball.setx(-340)
        ball_dx = ball_dx * -1
        os.system("afplay paddle.wav&")

    if (ball.xcor() < 340) and (not ball.xcor() <= 350) and (
            paddle_left.ycor() + 0 > ball.ycor() > paddle_left.ycor() - 350):
        ball.setx(340)
        ball_dx = ball_dx * -1
        os.system("afplay paddle.wav&")

【问题讨论】:

  • (ball.xcor() &gt; -340) and (ball.xcor() &lt; -350) 永远不会为真 - 反转两个常量或两个比较运算符。
  • 球仍然通过
  • 同样的“原始”代码一遍又一遍地发布到 [turtle-graphics] 和 [python-turtle]。而且没有人引用实际来源,这可能会有所帮助。

标签: python collision turtle-graphics python-turtle pong


【解决方案1】:

此代码是您遇到的典型问题:

    if (ball.xcor() < -340) and (ball.xcor() > -350) and (
            paddle_right.ycor() + 40 > ball.ycor() > paddle_right.ycor() - 40):
        ball.setx(-340)
        ball_dx = ball_dx * -1
        #...

    if (ball.xcor() < 340) and (not ball.xcor() <= 350) and (
            paddle_left.ycor() + 0 > ball.ycor() > paddle_left.ycor() - 350):
        ball.setx(340)
        #...

首先,左桨的处理方式与右桨完全不同——右桨逻辑毫无意义。接下来,您要对照左桨的 X 位置检查球,但使用右桨的 Y 位置!?!反之亦然。接下来,您正在测试 -350

最后,上面的代码引用了不存在的paddle_rightpaddle_left——在你程序的其余部分它们被称为rightpaddleleftpaddle。如果你真的遇到了桨碰撞,你的代码就会崩溃。

下面是对代码的完全重写,使用常量来保存各种固定参数,并通过数学计算来描述事物的位置。它也被重新安排为一个有效的基于事件的海龟程序(不允许while True:)。还有一堆其他的东西:

from turtle import Screen, Turtle

FONT = ('Arial', 24, 'normal')

SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600

LEFT_PADDLE_X = -300
RIGHT_PADDLE_X = 300

PADDLE_WIDTH, PADDLE_HEIGHT = 20, 100
PADDLE_HALF_HEIGHT = PADDLE_HEIGHT/2

BALL_DIAMETER = 20
BALL_RADIUS = BALL_DIAMETER/2

SCREEN_LEFT_MARGIN = BALL_DIAMETER - SCREEN_WIDTH/2
SCREEN_RIGHT_MARGIN = SCREEN_WIDTH/2 - BALL_DIAMETER
SCREEN_TOP_MARGIN = SCREEN_HEIGHT/2 - BALL_DIAMETER
SCREEN_BOTTOM_MARGIN = BALL_DIAMETER - SCREEN_HEIGHT/2

LEFT_PADDLE_SURFACE = LEFT_PADDLE_X + PADDLE_WIDTH/2
RIGHT_PADDLE_SURFACE = RIGHT_PADDLE_X - PADDLE_WIDTH/2

PADDLE_SHIFT = PADDLE_HEIGHT - BALL_RADIUS

CURSOR_SIZE = 20

def paddle_leftup():
    paddle_left.forward(PADDLE_SHIFT)
    screen.update()

def paddle_leftdown():
    paddle_left.backward(PADDLE_SHIFT)
    screen.update()

def paddle_rightup():
    paddle_right.forward(PADDLE_SHIFT)
    screen.update()

def paddle_rightdown():
    paddle_right.backward(PADDLE_SHIFT)
    screen.update()

left_score = 0
right_score = 0

ball_dx = 2
ball_dy = 2

def move_ball():
    global left_score, right_score, ball_dx, ball_dy

    x, y = ball.position()

    x += ball_dx
    y += ball_dy

    if  x < SCREEN_LEFT_MARGIN:
        x, y = 0, 0
        ball_dx *= -1
        right_score += 1
        pen.clear()
        pen.write("Score: {}, {}".format(left_score, right_score), align='center', font=FONT)
    elif x > SCREEN_RIGHT_MARGIN:
        x, y = 0, 0
        ball_dx *= -1
        left_score += 1
        pen.clear()
        pen.write("Score: {}, {}".format(left_score, right_score), align='center', font=FONT)
    else:
        if y > SCREEN_TOP_MARGIN:
            y = SCREEN_TOP_MARGIN
            ball_dy *= -1
        elif y < SCREEN_BOTTOM_MARGIN:
            y = SCREEN_BOTTOM_MARGIN
            ball_dy *= -1

        # paddle collision

        left_y, right_y = paddle_left.ycor(), paddle_right.ycor()

        if LEFT_PADDLE_SURFACE - BALL_RADIUS/2 < x < LEFT_PADDLE_SURFACE + BALL_RADIUS:
            if left_y - PADDLE_HALF_HEIGHT < y < left_y + PADDLE_HALF_HEIGHT:
                ball_dx *= -1
                ball.setx(LEFT_PADDLE_SURFACE + ball_dx)
        elif RIGHT_PADDLE_SURFACE - BALL_RADIUS < x < RIGHT_PADDLE_SURFACE + BALL_RADIUS/2:
            if right_y - PADDLE_HALF_HEIGHT < y < right_y + PADDLE_HALF_HEIGHT:
                ball_dx *= -1
                ball.setx(RIGHT_PADDLE_SURFACE + ball_dx)

    ball.setposition(x, y)

    screen.update()
    screen.ontimer(move_ball)

screen = Screen()
screen.setup(SCREEN_WIDTH, SCREEN_HEIGHT)
screen.title("Game of pong")
screen.bgcolor('black')
screen.tracer(0)

paddle_left = Turtle()
paddle_left.speed('fastest')
paddle_left.shape('square')
paddle_left.shapesize(stretch_len=PADDLE_HEIGHT/CURSOR_SIZE, stretch_wid=PADDLE_WIDTH/CURSOR_SIZE)
paddle_left.color('white')
paddle_left.penup()
paddle_left.setheading(90)
paddle_left.setx(LEFT_PADDLE_X)

paddle_right = paddle_left.clone()
paddle_right.color('purple')
paddle_right.setx(RIGHT_PADDLE_X)

ball = Turtle()
ball.speed('fastest')
ball.shape('circle')
ball.color('red')
ball.penup()

pen = Turtle()
pen.hideturtle()
pen.speed('fastest')
pen.color('Pink')
pen.penup()
pen.sety(260)
pen.write('Score: {}, {}'.format(left_score, right_score), align='center', font=FONT)

screen.onkeypress(paddle_leftup, 'w')
screen.onkeypress(paddle_leftdown, 's')
screen.onkeypress(paddle_rightup, 'Up')
screen.onkeypress(paddle_rightdown, 'Down')
screen.listen()

move_ball()

screen.mainloop()

并不完美,但应该会给你一些基本可以工作的东西,你可以在此基础上进行构建和调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多