Python 通过 "not in" 列表进行海龟碰撞检测。为什么它不起作用?
Python Turtle Collision Detection via "not in" list. Why doesn't it work?
此测试代码的目标是让玩家使用 W、A、S、D 移动,并使用 ENTER 键开始或停止建造一堵墙。如果有人能告诉我为什么他只是偶尔撞到他的墙壁,我将不胜感激。也可以从一般意义上随意批评我的代码!提前致谢。
import turtle
grid_size = 10
t1 = turtle.Pen()
t1.width(grid_size)
t1.up()
walls = [[0,0]]
walls.clear()
def toggle_building():
if t1.isdown():
t1.up()
else:
t1.down()
def lay_brick():
if t1.isdown() and t1.pos() not in walls:
walls.append(t1.pos())
print("Brick layed.")
def print_pos():
print(t1.pos())
def move_up():
t1.setheading(90)
if t1.pos() + [0, grid_size] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_left():
t1.setheading(180)
if t1.pos() - [grid_size, 0] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_down():
t1.setheading(270)
if t1.pos() - [0, grid_size] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_right():
t1.setheading(0)
if t1.pos() + [grid_size, 0] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
turtle.onkeypress(move_up, "w")
turtle.onkeypress(move_left, "a")
turtle.onkeypress(move_down, "s")
turtle.onkeypress(move_right, "d")
turtle.onkeypress(toggle_building, "Return")
turtle.listen()
如您问题的评论中所述,乌龟在浮点平面上徘徊,即使您认为它已返回到与之前完全相同的位置,该位置总会添加一点浮点噪声.将位置转换为 int
进行比较肯定有帮助,但可能还不够。
下面是我尝试通过更改坐标系本身来使其稳健,因此看起来我们正在移动 1 而不是 10。它还尝试减少浮点到整数转换需要发生的位置数:
from turtle import Screen, Turtle
GRID_SIZE = 10
def toggle_building():
if turtle.isdown():
turtle.penup()
else:
turtle.pendown()
def lay_brick(position):
if turtle.isdown():
walls.add(position)
def move_up():
turtle.setheading(90)
position = int(turtle.xcor()), int(turtle.ycor()) + 1
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_left():
turtle.setheading(180)
position = int(turtle.xcor()) - 1, int(turtle.ycor())
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_down():
turtle.setheading(270)
position = int(turtle.xcor()), int(turtle.ycor()) - 1
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_right():
turtle.setheading(0)
position = int(turtle.xcor()) + 1, int(turtle.ycor())
if position not in walls:
turtle.goto(position)
lay_brick(position)
screen = Screen()
WIDTH, HEIGHT = (screen.window_width() / 2) // GRID_SIZE, (screen.window_height() / 2) // GRID_SIZE
screen.setworldcoordinates(-WIDTH, -HEIGHT, WIDTH, HEIGHT)
turtle = Turtle()
turtle.width(GRID_SIZE)
turtle.fillcolor('red')
turtle.penup()
walls = set()
screen.onkeypress(move_up, "w")
screen.onkeypress(move_left, "a")
screen.onkeypress(move_down, "s")
screen.onkeypress(move_right, "d")
screen.onkeypress(toggle_building, "Return")
screen.listen()
screen.mainloop()
它还使用 set
来包含墙壁。由于顺序无关紧要,这将使测试更快。
此测试代码的目标是让玩家使用 W、A、S、D 移动,并使用 ENTER 键开始或停止建造一堵墙。如果有人能告诉我为什么他只是偶尔撞到他的墙壁,我将不胜感激。也可以从一般意义上随意批评我的代码!提前致谢。
import turtle
grid_size = 10
t1 = turtle.Pen()
t1.width(grid_size)
t1.up()
walls = [[0,0]]
walls.clear()
def toggle_building():
if t1.isdown():
t1.up()
else:
t1.down()
def lay_brick():
if t1.isdown() and t1.pos() not in walls:
walls.append(t1.pos())
print("Brick layed.")
def print_pos():
print(t1.pos())
def move_up():
t1.setheading(90)
if t1.pos() + [0, grid_size] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_left():
t1.setheading(180)
if t1.pos() - [grid_size, 0] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_down():
t1.setheading(270)
if t1.pos() - [0, grid_size] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
def move_right():
t1.setheading(0)
if t1.pos() + [grid_size, 0] not in walls:
t1.forward(grid_size)
lay_brick()
else:
print("wall")
print_pos()
turtle.onkeypress(move_up, "w")
turtle.onkeypress(move_left, "a")
turtle.onkeypress(move_down, "s")
turtle.onkeypress(move_right, "d")
turtle.onkeypress(toggle_building, "Return")
turtle.listen()
如您问题的评论中所述,乌龟在浮点平面上徘徊,即使您认为它已返回到与之前完全相同的位置,该位置总会添加一点浮点噪声.将位置转换为 int
进行比较肯定有帮助,但可能还不够。
下面是我尝试通过更改坐标系本身来使其稳健,因此看起来我们正在移动 1 而不是 10。它还尝试减少浮点到整数转换需要发生的位置数:
from turtle import Screen, Turtle
GRID_SIZE = 10
def toggle_building():
if turtle.isdown():
turtle.penup()
else:
turtle.pendown()
def lay_brick(position):
if turtle.isdown():
walls.add(position)
def move_up():
turtle.setheading(90)
position = int(turtle.xcor()), int(turtle.ycor()) + 1
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_left():
turtle.setheading(180)
position = int(turtle.xcor()) - 1, int(turtle.ycor())
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_down():
turtle.setheading(270)
position = int(turtle.xcor()), int(turtle.ycor()) - 1
if position not in walls:
turtle.goto(position)
lay_brick(position)
def move_right():
turtle.setheading(0)
position = int(turtle.xcor()) + 1, int(turtle.ycor())
if position not in walls:
turtle.goto(position)
lay_brick(position)
screen = Screen()
WIDTH, HEIGHT = (screen.window_width() / 2) // GRID_SIZE, (screen.window_height() / 2) // GRID_SIZE
screen.setworldcoordinates(-WIDTH, -HEIGHT, WIDTH, HEIGHT)
turtle = Turtle()
turtle.width(GRID_SIZE)
turtle.fillcolor('red')
turtle.penup()
walls = set()
screen.onkeypress(move_up, "w")
screen.onkeypress(move_left, "a")
screen.onkeypress(move_down, "s")
screen.onkeypress(move_right, "d")
screen.onkeypress(toggle_building, "Return")
screen.listen()
screen.mainloop()
它还使用 set
来包含墙壁。由于顺序无关紧要,这将使测试更快。