首页 > 解决方案 > 关于碰撞检测和更新标签的说明

问题描述

我正在尝试进行桨球比赛,该比赛需要尽可能长时间地让球远离底部弹跳。在这个游戏中,有 5 条生命,当球击中屏幕底部时会耗尽生命,一旦达到 0 生命就会自动重置。然而,球并没有按应有的方式从球拍上反弹,得分的标签也没有按应有的方式更新。我目前如何尝试实现碰撞的代码与球的垂直放置有关,其相关部分如下:

        if vertical_direction == "south":
            top_y += dy 
            if top_y >= (self.canvas_height - ball_diameter) - 20:
                if self.top_paddle <= top_y and self.top_paddle + 80 >= top_y:
                    top_y = self.canvas_height - ball_diameter
                    vertical_direction = "north"
                elif top_y >= self.canvas_height - ball_diameter:
                    lives -= 1
                    if (lives >= 0):
                        top_x = 2
                        top_y = 2
                        self.canvas.delete("ball")
                        ball = self.canvas.create_oval(top_x, top_y, top_x + ball_diameter,
                                                       top_y + ball_diameter, fill = "blue", tags = "ball")
                        var.set("Lives: " +lives_Label)

                    else:
                        lives= 5
                        top_x = 2
                        top_y = 2
                        self.canvas.delete(ball)
                        ball = self.canvas.create_oval(top_x, top_y, top_x + ball_diameter,
                                                       top_y + ball_diameter, fill = "blue", tags = "ball")

我查看了一些我发现与我的最相似的代码,并尝试实现其检测碰撞的方法,如上所示。我唯一的猜测是我没有注意到一些明显的逻辑不一致,这对于更有经验的编码人员来说是显而易见的,这就是我的两个问题的原因。

作为参考,这是迄今为止的完整代码:

from tkinter import *
import tkinter.font
class BallBounce (Frame):

    def __init__(self):
        Frame.__init__(self)
        self.master.title("Bouncing Ball")
        self.grid()

        lives = 5
        lives_Label = str(lives)

        var = StringVar()
        font = tkinter.font.Font(family = "Verdana", size = 20)
        self._label = Label(self, font = font, textvariable = var)
        var.set("Lives: "+lives_Label)
        self._label.grid(row = 0, column = 0)

        self.canvas_width = 800
        self.canvas_height = 400

        self.canvas = Canvas(self, width = self.canvas_width, height = self.canvas_height, 
            bg = "white")
        self.canvas.grid(row = 1, column = 0)

        frame = Frame(self)
        frame.grid(row = 1, column = 0)


        top_x = 0
        top_y = 0

        ball_diameter = 20

        self.canvas.create_oval(top_x, top_y, ball_diameter, ball_diameter, fill = "blue", tags = "ball")

        horizontal_direction = "east"
        vertical_direction = "south"


        self.canvas.create_rectangle (self.canvas_width / 2, self.canvas_height - 20, self.canvas_width / 2 + 80,
                                         self.canvas_height, fill = "black", tags = "paddle")
        self.top_paddle = self.canvas_width/2


        self.canvas.bind("<Left>", lambda event: self.canvas.move("paddle", -5, 0))

        self.canvas.bind("<Right>", lambda event: self.canvas.move("paddle", 5, 0))

        self.canvas.focus_set()



        dx = 2
        dy = 2
        while True:

            if horizontal_direction == "east":
                top_x += dx # dx is 2 because the ball moves 2 pixels horizontally every 15 milliseconds
                if top_x >= self.canvas_width - ball_diameter: # ball has hit east wall
                    top_x = self.canvas_width - ball_diameter
                    horizontal_direction = "west" # change direction
                self.canvas.move("ball", dx, 0) # move ball horizontally dx pixels to the right/east
            else: # i.e., horizontal_direction is "west"
                top_x -= dx 
                if top_x <= 0: # ball has hit west wall
                    top_x = 0 # you may need to adjust this a little
                    horizontal_direction = "east" # change direction
                self.canvas.move("ball", -dx, 0) # move ball horizontally dx pixels to the left/west


            if vertical_direction == "south":
                top_y += dy 
                if top_y >= (self.canvas_height - ball_diameter) - 20:
                    if self.top_paddle <= top_y and self.top_paddle + 80 >= top_y:
                        top_y = self.canvas_height - ball_diameter
                        vertical_direction = "north"
                    elif top_y >= self.canvas_height - ball_diameter:
                        lives -= 1
                        if (lives >= 0):
                            top_x = 2
                            top_y = 2
                            self.canvas.delete("ball")
                            ball = self.canvas.create_oval(top_x, top_y, top_x + ball_diameter,
                                                           top_y + ball_diameter, fill = "blue", tags = "ball")
                            var.set("Lives: " +lives_Label)

                        else:
                            lives= 5
                            top_x = 2
                            top_y = 2
                            self.canvas.delete(ball)
                            ball = self.canvas.create_oval(top_x, top_y, top_x + ball_diameter,
                                                           top_y + ball_diameter, fill = "blue", tags = "ball")

                self.canvas.move("ball", 0, dy)
            else: 
                top_y -= dy
                if top_y <= 0:
                    top_y = 0 
                    vertical_direction = "south"
                self.canvas.move("ball", 0, -dy) 

            self.canvas.after(15) 
            self.canvas.update() 

def main():
    BallBounce().mainloop()

main()

标签: pythontkinterlabelcollision-detection

解决方案


推荐阅读