canvas python 乌龟左侧和顶部的额外像素

Extra pixels left and top of canvas python turtle

我不确定为什么,但是在 canvas 的左侧和顶部,我在使用 turtle 创建贪吃蛇游戏时出现了奇怪的行为。左侧和顶部各有 10 像素的边框。

主要代码

import functools
from turtle import Screen
import time
from Snake import Snake


# initialize screen
win = Screen()
WIDTH = HEIGHT = 800
win.setup(width=WIDTH, height=HEIGHT)
win.bgcolor("black")
canvas = win.getcanvas()
root = canvas.winfo_toplevel()
root.overrideredirect(1)
win.tracer(0)

s = Snake()


def main():
    segments = s.init_segments()
    win.update()
    move_keys = ["Right", "Up", "Left", "Down"]
    running = True
    inc = 0

    for k in move_keys:
        win.onkeypress(functools.partial(s.move, segments, inc, k), key=k)
        inc += 90

    win.listen()

    while running:
        win.update()
        time.sleep(0.1)
        s.move(segments, segments[0].heading(), "none")

        if s.crashed(win.window_width(), win.window_height(), segments):
            running = False
            break

    win.exitonclick()


main()

蛇码

from turtle import Turtle
class Snake:

    def init_segments(self):
        segs = []
        x_pos = 0
        for i in range(3):
            t = Turtle(shape="square")
            t.color("white")
            t.penup()
            t.speed(1)
            segs.append(t)
            if t != segs[0]:
                x_pos -= 20
                t.goto(x_pos, 0)
        return segs

    def __no_turn(self, h, d):
        if h - d == -180 or h - d == 180:
            return True
        else:
            return False

    def __no_skip(self, k, dir):
        if (k == "Right" and dir == 0 or k == "Up" and dir == 90
                or k == "Left" and dir == 180 or k == "Down" and dir == 270):
            return False
        else:
            return True

    def move(self, t_list , dir, k):
        for seg_num in range(len(t_list) - 1, -1, -1):
            if self.__no_turn(t_list[0].heading(), dir):
                continue
            elif seg_num > 0:
                if self.__no_skip(k, dir):
                    t_list[seg_num].goto(t_list[seg_num - 1].position())
            else:
                t_list[seg_num].setheading(dir)
                if self.__no_skip(k, dir):
                    t_list[seg_num].forward(20)


    def crashed(self, window_width, window_height, t_list):
        head_position = t_list[0].position()
        body_positions = []
        hw = window_width/2
        hh = window_height/2
        for i in range(len(t_list)):
            body_positions.append(t_list[i].position())

        body_positions.pop(0)
        for i in range(len(body_positions)):
            if head_position == body_positions[i]:
                return True

        if head_position[0] >= hw:
            print(f"Head Position: {head_position[0]} ... Wall Position: {hw}")
            return True

        elif head_position[0] <= -hw:
            print(f"Head Position: {head_position[0]} ... Wall Position: {-hw}")
            return True

        elif head_position[1] >= hh:
            print(f"Head Position: {head_position[1]} ... Wall Position: {hh}")
            return True

        elif head_position[1] <= -hh:
            print(f"Head Position: {head_position[1]} ... Wall Position: {-hh}")
            return True

在该文件中添加了打印行以尝试弄清楚发生了什么。

请帮助我了解发生了什么。

谢谢。

编辑: 我之前也没有注意到,但是底部和右侧有一个 1px 的边框。

第二次编辑以进一步说明问题。

我刚才添加了药片的代码。我所做的是,我一次生成所有药丸并隐藏它们,因为你不能在不清除屏幕的情况下摧毁乌龟,而且每次都获得乌龟位置并在屏幕上重新绘制乌龟会很奇怪之前是 0.1 秒。然后我得到了这个结果。

如您所见,药丸在屏幕外生成。

以下是我用来生成所有药丸的代码,与我用来确定屏幕边缘的代码类似。

hw = int(WIDTH/2)
hh = int(HEIGHT/2)
p_list = []
for i in range(-hw, hw, 20):
    for j in range(-hh, hh, 20):
        p = Pill((i, j))
        p.show_pill(segments)
        p_list.append(p)

当我重新订购 win.update()

时会发生什么

正如你在这里看到的,右边现在把一整段都塞进去了。如果你仔细观察,你会在这张图片中看到蛇的白色部分覆盖了 space 的额外像素这在上一张图片中没有涉及,它停在圆圈的最后一个像素上。 您还会在第二张图片和这张图片中看到,底部有一排圆圈,可以从 window 的边框边缘窥视。

如果您在 s.move(segments, segments[0].heading(), "none") 之后而不是之前移动 win.update(),它将起作用(即)在所有四堵墙上以相同的方式崩溃。

如果您不希望头部在碰撞时撞到墙上,请相应地修改碰撞边界检查。

我终于明白为什么会这样了。

第一个问题:我以前被引导相信所有海龟形状都是平等的。不,他们不是。虽然海龟的默认大小可能是 20px x 20px,但正方形和圆形都默认为 21px,因为它们需要一个不是偶数的中心点,以便它可以在海龟的 4 个象限之间平均分配 co-ordinate 系统(它有一个像素作为 x 和 y 轴)。

如何解决:

  • 使 canvas 成为 21px 的倍数。
  • 请记住 canvas,当分成 2 部分时,每条边上都有一半的海龟,这算作一只完整的海龟,但海龟只完成了 canvas,所以我们'再坐在一列和一排乌龟旁边。
  • 删除最后一列和最后一行海龟并将整个网格移动一只海龟。

如果操作正确,您将得到以下结果。不幸的是,右侧和底部的 2px 将被截断,因为它用于 Turtle 的 UI。顶部和左侧面临类似的问题,即单行像素用于 Turtle 的 UI

蛇本身是以类似的方式完成的,我不是将起始段移动 20px,而是先将其移动 11px,然后附加蛇的其他部分。我通过删除我最初移动它的 11px 来计算它的位置。这实际上解决了蛇的大部分问题,除了 Turtle 的 ui 带走的东西。