Building Breakout Game (python), но я не могу получить кирпичи для удаления_? - PullRequest
0 голосов
/ 29 мая 2020

Я новый кодировщик, и я создаю игру «Breakout» в python, и у меня есть большая часть этого, кроме удаления кирпичей. * Что странно, так это то, что после того, как мяч коснется нижней стены (за пределами поля) и восстановится, кирпичи можно будет удалить во время игры! Также мне нужно остановить игру после 3 шансов. Я застрял с этими двумя проблемами. Помогите, пожалуйста. Вот мой код:

import tkinter import time

# 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()

1 Ответ

1 голос
/ 29 мая 2020

Первая проблема возникает из-за оператора if в for l oop внутри hit_brick():

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)

Поскольку значения ball и paddle равны 1 и 2 (как это первые два созданных элемента холста), и поэтому results - это что-то вроде (1, N), когда мяч попадает в один из кирпичей. Таким образом, оператор if возвращает истину для первой проверки, а затем функция завершается с помощью оператора return.

Теперь позвольте мячу удариться о дно, и он будет воссоздан с идентификатором больше, чем существующие элементы холста. results будет чем-то вроде (N, ball), когда мяч попадает в один из кирпичей. На этот раз оператор if вернет false, и кирпич будет удален.

Итак, 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

Для второй проблемы вам необходимо объявить переменную , например lives = 3, перед while l oop и уменьшите его на единицу, если мяч упадет на дно. Операция while l oop должна быть завершена, если lives == 0:

def main():
    ...
    lives = 3
    while lives > 0:
        ...
        if hit_bottom(canvas.ball):
            ...
            lives -= 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...