[英]Building Breakout Game (python) but I can't get bricks to delete_?
我是一个新的编码员,我正在 python 中构建一个“Breakout”游戏,除了要删除砖块外,我得到了大部分内容。 *奇怪的是,在球接触底墙(出界)并重新生成后,砖块可以通过玩游戏被删除,此外。 我需要在 3 次机会后停止游戏,我被卡住了。 有这两个问题。 请帮助:这是我的代码:
进口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()
第一个问题是由于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)
由于ball
和paddle
的值为 1 和 2(因为它们是创建的前两个 canvas 项目),因此当球击中其中一个砖块时, results
类似于(1, N)
。 因此 if 语句在第一次检查时返回 true,然后 function 通过return
语句退出。
现在让球击中底部,它将以大于现有 canvas 项目的 id 重新创建。 当球击中其中一个砖块时, 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
对于第二个问题,您需要在 while 循环之前声明一个变量,例如lives = 3
,如果球击中底部,则将其减一。 如果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.