Python 蟒蛇龟变色

Python 蟒蛇龟变色,python,turtle-graphics,Python,Turtle Graphics,我现在正在玩pythons-turtle模块,我正在尝试制作一个不透明的正方形网格,比如说30x30,它可以根据一些属性(不管是什么属性)改变颜色。我的问题是,在画布上绘制一个形状后,是否有必要改变它的颜色 我试着将所有的方形形状添加到一个数组中,包括图章和多边形,但是一旦它们被绘制出来,似乎就不可能改变它们中任何一个的颜色 我知道stamp不起作用,因为它就像海龟的脚印,但有没有任何方法可以让多边形或其他我不知道的方法实现这一点 我没有添加任何代码片段,因为这是一个非常基本的问题,可以用于很多

我现在正在玩pythons-turtle模块,我正在尝试制作一个不透明的正方形网格,比如说30x30,它可以根据一些属性(不管是什么属性)改变颜色。我的问题是,在画布上绘制一个形状后,是否有必要改变它的颜色

我试着将所有的方形形状添加到一个数组中,包括图章和多边形,但是一旦它们被绘制出来,似乎就不可能改变它们中任何一个的颜色

我知道stamp不起作用,因为它就像海龟的脚印,但有没有任何方法可以让多边形或其他我不知道的方法实现这一点


我没有添加任何代码片段,因为这是一个非常基本的问题,可以用于很多事情。

海龟的想法是,图像一旦绘制,就会变成像素,并提交到画布上-即使海龟命令本身是“向量”命令,当人们谈论“向量”与“光栅”图形时

这意味着海龟绘图上下文无法知道“自己”已绘制的内容-您无法引用已绘制的形状或多边形并更改其属性。(更新:但是对于邮票-海龟对象确实记录了这些邮票的信息-谢谢@cdlane)

在本例中,您需要做的是在代码数据上注释您希望进一步修改的任何形状,并在需要时以某种方式重新绘制它们。换言之:您可以为矢量图形模型开发代码,这样您就可以做到这一点

然而,你应该注意到,海龟在上面奔跑(至少,我相信),它本身就是一个向量模型——所以它可能更适合你的想法。不过,它的文档和工作方式可能很难掌握

因此,回到“拥有自己的矢量图形实现”,您可以利用Python面向对象和数据模型构建“历史乌龟”——它可以记录日志并在相同位置上下文中回放命令块(但允许不同的颜色、宽度等设置)

这是一个比所说的更卑鄙的骗局,但是,这里有一个例子:

from turtle import Turtle

"""
Python Turtle with logging and replay capabilities

Author: João S. O. Bueno <gwidion@gmail.com>
License: LGPL 3.0+

This implements HistoryTurtle - a subclass of
Python's turtle.Turtle wich features a simple
command history and   new `replay` and `log`
methods -
`turtle.replay(<start>, <end>)` will reissue
the commands logged in those positions of the history,
but with the current Pen settings.

The optional kwarg `position_independent` can be passed
as `True` to `replay` so that the turtle's position
and heading are not restored to the ones recorded
along with the command.

https://gist.github.com/jsbueno/cb413e985747392c460f39cc138436bc

"""


class Command:
    __slots__ = ( "method_name", "args", "kwargs", "pos", "heading")

    def __init__(self, method_name, args=(),
                 kwargs=None, pos=None, heading=None):
        self.method_name = method_name
        self.args = args
        self.kwargs = kwargs or {}
        self.pos = pos
        self.heading = heading

    def __repr__(self):
        return "<{0}> - {1}".format(self.pos, self.method_name)


class Instrumented:
    def __init__(self, turtle, method):
        self.turtle = turtle
        self.method = method

    def __call__(self, *args, **kwargs):
        command = Command(self.method.__name__, args, kwargs,
                          self.pos(), self.heading())
        result = self.method(*args, **kwargs)
        if (self.method.__name__ not in self.turtle.methods_to_skip or
                not kwargs.pop('skip_self', True)):
            self.turtle.history.append(command)
        return result

    def pos(self):
        return self.turtle._execute(Command('pos'), True)

    def heading(self):
        return self.turtle._execute(Command('heading'), True)


class HistoryTurtle(Turtle):

    methods_to_skip = ('replay', '_execute', 'log')

    def __init__(self, *args, **kw):
        self._inited = False
        super().__init__(*args, **kw)
        self.history = []
        self._replaying = [False]
        self._inited = True

    def __getattribute__(self, attr):
        result = super().__getattribute__(attr)
        if (not callable(result) or
                attr.startswith('_') or
                not self._inited or
                self._replaying[-1]):
            return result
        return Instrumented(self, result)

    def replay(self, start, end=None, *,
               position_independent=False,
               skip_self=True,
               restore=True
               ):
        results = []

        self._replaying.append(True)
        if restore:
            pos, heading, state = self.pos(), self.heading(), self.pen()['pendown']
        for command in self.history[start:end]:
            results.append(
                self._execute(command, position_independent))
        if restore:
            self.setpos(pos)
            self.setheading(heading)
            (self.pendown() if state else self.penup())
        self._replaying.pop()
        return results

    def log(self, start=0, end=None):
        for i, command in enumerate(self.history[start:end], start):
            print(i, command)

    def _execute(self, command, position_independent):
        """ Execute a method without triggering the log
        """
        # Warning: not thread-safe:
        self._replaying.append(True)
        method = getattr(self, command.method_name)
        if not position_independent:
            state = self.pen()['pendown']
            self.setpos(command.pos)
            self.setheading(command.heading)
            (self.pendown() if state else self.penup())
        result = method(*command.args, **command.kwargs)
        self._replaying.pop()
        return result
从海龟进口海龟
"""
具有日志记录和重播功能的Python Turtle
作者:João.o.Bueno
许可证:LGPL 3.0+
这实现了HistoryTurtle—的一个子类
Python的turtle.turtle wich具有一个简单的
命令历史记录和新的“replay”和“log”`
方法-
`海龟。重播(,)`将重新发行
记录在这些历史位置的命令,
但是使用当前的笔设置。
可以传递可选的kwarg“位置独立”
与“回放”相同,因此海龟的位置
航向和航向不会恢复到记录的航向
伴随着命令。
https://gist.github.com/jsbueno/cb413e985747392c460f39cc138436bc
"""
类命令:
__插槽=(“方法名称”、“参数”、“kwargs”、“位置”、“标题”)
def uu init uu(self,method_name,args=(),),
kwargs=无,pos=无,标题=无):
self.method\u name=方法\u name
self.args=args
self.kwargs=kwargs或{}
self.pos=pos
self.heading=航向
定义报告(自我):
返回“-{1}”。格式(self.pos,self.method\u name)
插入指令的类:
定义初始化(自我、乌龟、方法):
乌龟
self.method=方法
定义调用(self,*args,**kwargs):
command=command(self.method.\u__;u name\u___;、args、kwargs、,
self.pos(),self.heading())
结果=self.method(*args,**kwargs)
if(self.method.\uuuuu name\uuuuuu不在self.turtle.methods\u中)到\u跳过或
不是kwargs.pop('skip_self',True)):
self.turtle.history.append(命令)
返回结果
def位置(自身):
返回self.turtle.\u执行(命令('pos'),True)
def标题(自我):
返回self.turtle.\u执行(命令('heading'),True)
甲鱼类:
方法\u到\u跳过=('replay'、'u execute'、'log')
定义初始值(自,*args,**kw):
self.\u inited=False
超级()
self.history=[]
self.\u回放=[假]
self.\u inited=True
定义获取属性(自身,属性):
结果=超级()
如果(不可调用(结果)或
属性开始使用(“”)或
不是自己发起的或
自我重放[-1]):
返回结果
返回检测(自身、结果)
def回放(自、开始、结束=无,*,
位置_独立=假,
跳过self=True,
还原=真
):
结果=[]
self.\u replaying.append(真)
如果恢复:
pos,heading,state=self.pos(),self.heading(),self.pen()['pendown']
对于self.history[开始:结束]中的命令:
结果.append(
自执行(命令、位置、独立)
如果恢复:
self.setpos(pos)
自我设置标题(标题)
(self.pendown()如果状态为else self.penup())
self.\u replaying.pop()
返回结果
def日志(self,start=0,end=None):
对于i,枚举中的命令(self.history[start:end],start):
打印(i,命令)
def_执行(自身、命令、位置独立):
“”“在不触发日志的情况下执行方法
"""
#警告:非线程安全:
self.\u replaying.append(真)
method=getattr(self,command.method\u name)
如果位置不独立:
state=self.pen()['pendown']
self.setpos(command.pos)
self.setheading(命令标题)
(self.pendown()如果状态为else self.penup())
结果=方法(*command.args,**command.kwargs)
self.\u replaying.pop()
返回结果

是的,你能做到。钥匙
from turtle import Turtle, Screen
from random import randrange, choice
from collections import namedtuple
from math import ceil

GRID = 15  # GRID by GRID of squares
SIZE = 30  # each square is SIZE by SIZE

INCREASE = 1.5  # how much to lighten the square's color
WHITE = [255, 255, 255]  # color at which we stop changing square
DELAY = 100  # time between calls to change() in milliseconds
DARK = 32 # range (ceil(INCREASE) .. DARK - 1) of dark colors

def change():
    block = choice(blocks)
    blocks.remove(block)

    color = [min(int(primary * INCREASE), WHITE[i]) for i, primary in enumerate(block.color)]  # lighten color

    turtle.color(color)
    turtle.setposition(block.position)
    turtle.clearstamp(block.stamp)

    stamp = turtle.stamp()

    if color != WHITE:
        blocks.append(Block(block.position, color, stamp))  # not white yet so keep changing this block

    if blocks:  # stop all changes if/when all blocks turn white
        screen.ontimer(change, DELAY)

HALF_SIZE = SIZE // 2

screen = Screen()
screen.colormode(WHITE[0])
screen.register_shape("block", ((HALF_SIZE, -HALF_SIZE), (HALF_SIZE, HALF_SIZE), (-HALF_SIZE, HALF_SIZE), (-HALF_SIZE, -HALF_SIZE)))
screen.tracer(GRID ** 2)  # ala @PyNuts

turtle = Turtle(shape="block", visible=False)
turtle.speed("fastest")
turtle.up()

Block = namedtuple('Block', ['position', 'color', 'stamp'])

blocks = list()

HALF_GRID = GRID // 2

for x in range(-HALF_GRID, HALF_GRID):
    for y in range(-HALF_GRID, HALF_GRID):
        turtle.goto(x * SIZE, y * SIZE)
        color = [randrange(ceil(INCREASE), DARK) for primary in WHITE]
        turtle.color(color)
        blocks.append(Block(turtle.position(), color, turtle.stamp()))

screen.ontimer(change, DELAY)

screen.exitonclick()