简体   繁体   English

构建突围游戏 (python) 但我无法删除要删除的砖块_?

[英]Building Breakout Game (python) but I can't get bricks to delete_?

I am a new coder and I am building a "Breakout" game in python and i got most of it to except getting the bricks to delete.我是一个新的编码员,我正在 python 中构建一个“Breakout”游戏,除了要删除砖块外,我得到了大部分内容。 *What is odd, is after the ball touches the bottom wall (out of bounds) and regenerates, the bricks are then able to be deleted by playing the game, Also. *奇怪的是,在球接触底墙(出界)并重新生成后,砖块可以通过玩游戏被删除,此外。 I need to stop the game after 3 chances, I'm stuck.我需要在 3 次机会后停止游戏,我被卡住了。 with those 2 problems.有这两个问题。 Help please: Here is my code:请帮助:这是我的代码:

import tkinter import time进口tkinter进口时间

# How big is the playing area?
CANVAS_WIDTH = 600  # Width of drawing canvas in pixels
CANVAS_HEIGHT = 800  # Height of drawing canvas in pixels

# Constants for the bricks
N_ROWS = 8  # How many rows of bricks are there?
N_COLS = 10  # How many columns of bricks are there?
SPACING = 5  # How much space is there between each brick?
BRICK_START_Y = 50  # The y coordinate of the top-most brick
BRICK_HEIGHT = 20  # How many pixels high is each brick
BRICK_WIDTH = (CANVAS_WIDTH - (N_COLS + 1) * SPACING) // N_COLS

# Constants for the ball and paddle
BALL_SIZE = 70
PADDLE_Y = CANVAS_HEIGHT - 40
PADDLE_WIDTH = 200


def main():
    canvas = make_canvas(CANVAS_WIDTH, CANVAS_HEIGHT, 'Brick Breaker')
    # Makes a ball
    ball = canvas.create_oval(300, 300, 350, 350, fill="red", outline="red")
    # Makes a paddle
    paddle = canvas.create_rectangle(299, PADDLE_Y, PADDLE_WIDTH, CANVAS_HEIGHT - 20, fill="black")
    # Change_X
    dx = 6
    # Change_Y
    dy = 6
    for row in range(N_ROWS):
        # Draws columns of brick
        for col in range(N_COLS):
            draw_brick(canvas, row, col)

    while True:
        # Mouse location and respond to movement
        mouse_x = canvas.winfo_pointerx()
        # Move Paddle to X location
        canvas.moveto(paddle, mouse_x, PADDLE_Y)
        # Ball movement
        canvas.move(ball, dx, dy)
        # If ball hits left of right wall, change X location
        if hit_left_wall(canvas, ball) or hit_right_wall(canvas, ball):
            dx *= -1
        # If ball hits top wall, then change Y location
        elif hit_top_wall(canvas, ball):
            dy *= -1
        elif hit_brick(canvas, ball, paddle):
            dy *= -1
        if hit_bottom(canvas, ball):
            canvas.delete(ball)
            ball = make_ball(canvas)

        # Recreates canvas
        canvas.update()
        # Pause time
        time.sleep(1 / 50.)

    canvas.mainloop()


# Finds coordinates of paddle
def hit_paddle(canvas, ball, paddle):
    paddle_coords = canvas.coords(paddle)
    x1 = paddle_coords[0]
    y1 = paddle_coords[1]
    x2 = paddle_coords[2]
    y2 = paddle_coords[3]
    # If any object begins to overlap with paddle, create a Hit
    result = canvas.find_overlapping(x1, y1, x2, y2)
    return len(result) > 1


def make_ball(canvas):
    return canvas.create_oval(300, 300, 350, 350, fill="red", outline="red")


def hit_brick(canvas, ball, paddle):
    ball_coord = canvas.coords(ball)
    x_1 = ball_coord[0]
    y_1 = ball_coord[1]
    x_2 = ball_coord[2]
    y_2 = ball_coord[3]
    results = canvas.find_overlapping(x_1, y_1, x_2, y_2)
    for object in results:
        if object == paddle or object == ball:
            return len(results) > 1
        else:
            canvas.delete(object)


def moveto(canvas, oval, x, y):
    # Get current position
    x0, y0, x1, y1 = canvas.coords(oval)
    # Sets new position
    canvas.move(oval, x - x0, y - y0)


def hit_bottom(canvas, ball):
    return get_bottom_y(canvas, ball) >= CANVAS_HEIGHT


def hit_left_wall(canvas, ball):
    return get_left_x(canvas, ball) <= 0


def hit_right_wall(canvas, ball):
    return get_right_x(canvas, ball) >= CANVAS_WIDTH


def hit_top_wall(canvas, ball):
    return get_top_y(canvas, ball) <= 0


def draw_brick(canvas, row, col):
    x = col * (BRICK_WIDTH + SPACING)
    y = row * (BRICK_HEIGHT + SPACING)
    color = "blue"
    canvas.create_rectangle(x, y, x + BRICK_WIDTH, y + BRICK_HEIGHT, fill=color, outline=color)


def get_bottom_y(canvas, ball):
    return canvas.coords(ball)[3]


def get_top_y(canvas, ball):
    """
    This friendly method returns the y coordinate of the top of an object.
    Recall that canvas.coords(object) returns a list of the object
    bounding box: [x_1, y_1, x_2, y_2]. The element at index 1 is the top-y
    """
    return canvas.coords(ball)[1]


def get_left_x(canvas, ball):
    """
    This friendly method returns the x coordinate of the left of an object.
    Recall that canvas.coords(object) returns a list of the object
    bounding box: [x_1, y_1, x_2, y_2]. The element at index 0 is the left-x
    """
    return canvas.coords(ball)[0]


def get_right_x(canvas, ball):
    """
    This friendly method returns the x coordinate of the right of an object.
    Recall that canvas.coords(object) returns a list of the object
    bounding box: [x_1, y_1, x_2, y_2]. The element at index 2 is the right-x
    """
    return canvas.coords(ball)[2]


def make_canvas(width, height, title):
    """
    Creates and returns a drawing canvas
    of the given int size with a blue border,
    ready for drawing.
    """
    top = tkinter.Tk()
    top.minsize(width=width, height=height)
    top.title(title)
    canvas = tkinter.Canvas(top, width=width + 1, height=height + 1)
    canvas.pack()
    return canvas


if __name__ == '__main__':
    main()

The first problem is due to the if statement in the for loop inside hit_brick() :第一个问题是由于hit_brick()内部 for 循环中的 if 语句:

def hit_brick(canvas, ball, paddle):
    ball_coord = canvas.coords(ball)
    x_1 = ball_coord[0]
    y_1 = ball_coord[1]
    x_2 = ball_coord[2]
    y_2 = ball_coord[3]
    results = canvas.find_overlapping(x_1, y_1, x_2, y_2)
    for object in results:
        if object == paddle or object == ball: # <-- problem here
            return len(results) > 1
        else:
            canvas.delete(object)

As the values of ball and paddle are 1 and 2 (as they are the first two canvas items created) and so results is something like (1, N) when the ball hit one of the bricks.由于ballpaddle的值为 1 和 2(因为它们是创建的前两个 canvas 项目),因此当球击中其中一个砖块时, results类似于(1, N) So the if statement returns true for the first checking and then the function exits by the return statement.因此 if 语句在第一次检查时返回 true,然后 function 通过return语句退出。

Now let the ball hits the bottom and it will be recreated with id greater than existing canvas items.现在让球击中底部,它将以大于现有 canvas 项目的 id 重新创建。 The results will be something like (N, ball) when the ball hits one of the bricks.当球击中其中一个砖块时, results将类似于(N, ball) This time the if statement will return false and the brick is deleted.这次 if 语句将返回 false 并且砖块被删除。

So hit_brick() should be modified as below:所以hit_brick()应该修改如下:

def hit_brick(canvas, ball, paddle):
    ball_coord = canvas.coords(ball)
    results = canvas.find_overlapping(*ball_coord)
    for object in results:
        if object not in (paddle, ball):
            canvas.delete(object)
    return len(results) > 1

For the second problem, you need to declare a variable, for example lives = 3 , before the while loop and decrease it by one if the ball hits the bottom.对于第二个问题,您需要在 while 循环之前声明一个变量,例如lives = 3 ,如果球击中底部,则将其减一。 The while loop should be terminated if lives == 0 :如果lives == 0则应终止 while 循环:

def main():
    ...
    lives = 3
    while lives > 0:
        ...
        if hit_bottom(canvas.ball):
            ...
            lives -= 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM