支持旋转图像角色的海龟模块。

"""
   turtler.py
   支持旋转角色的海龟模块。
   本个模块重定义了原生海龟类的_rotate,__init__和shape方法
   使用pillow模块支持图形角色旋转,并且支持直接设定图片为角色的造型。
   本模块尚不支持用addshape或register_shape注册造型到型字典!
"""

__author__ = '李兴球'
__blog__ = 'www.lixingqiu.com'
__date__ = '2020/9/7'
__version__ = 0.1

import os
from PIL import Image,ImageTk
from turtle import Tbuffer,_Screen,_CFG,TNavigator,TPen,_TurtleImage,RawTurtle,Turtle,Screen,Shape

Sprite = Turtle

def _place_to_shapes(self,imagefilename):
    """用pillow模块打开图像文件,形成造型,放到造型字典中,返回在造型字典中的key"""
    self._imagename = imagefilename            # 保留原始图像文件名
    self._rawim = Image.open(imagefilename)    # 用pillow模块打开这个文件
    self._rawim = self._rawim.convert('RGBA')
    angle = self.heading()
    im = self._rawim.rotate(angle,expand=1)
    sp = Shape('image',ImageTk.PhotoImage(im))
    shapename = self._imagename + "_" + str(angle)
    self.screen.addshape(shapename,sp)
    return shapename

RawTurtle._place_to_shapes = _place_to_shapes

def __init__(self, canvas=None,shape=_CFG["shape"],
             undobuffersize=_CFG["undobuffersize"],
             visible=_CFG["visible"]):
    if isinstance(canvas, _Screen):
        self.screen = canvas
    elif isinstance(canvas, TurtleScreen):
        if canvas not in RawTurtle.screens:
            RawTurtle.screens.append(canvas)
        self.screen = canvas
    elif isinstance(canvas, (ScrolledCanvas, Canvas)):
        for screen in RawTurtle.screens:
            if screen.cv == canvas:
                self.screen = screen
                break
        else:
            self.screen = TurtleScreen(canvas)
            RawTurtle.screens.append(self.screen)
    else:
        raise TurtleGraphicsError("bad canvas argument %s" % canvas)

    screen = self.screen
    TNavigator.__init__(self, screen.mode())
    TPen.__init__(self)
    screen._turtles.append(self)
    self.drawingLineItem = screen._createline()

    if os.path.isfile(shape):                # 如果是文件
        shape = self._place_to_shapes(shape) # 第一次放到造型字典中       
    else:
        self._imagename = None              # 图片造型属性
        self._rawim = None
        
    self.turtle = _TurtleImage(screen, shape)
    self._poly = None
    self._creatingPoly = False
    self._fillitem = self._fillpath = None
    self._shown = visible
    self._hidden_from_screen = False
    self.currentLineItem = screen._createline()
    self.currentLine = [self._position]
    self.items = [self.currentLineItem]
    self.stampItems = []
    self._undobuffersize = undobuffersize
    self.undobuffer = Tbuffer(undobuffersize)
    self._update()
    
RawTurtle.__init__ = __init__

def _rotate(self, angle):
    """Turns pen clockwise by angle.
    """
    if self.undobuffer:
        self.undobuffer.push(("rot", angle, self._degreesPerAU))
    angle *= self._degreesPerAU
    neworient = self._orient.rotate(angle)
    tracing = self.screen._tracing
    if tracing == 1 and self._speed > 0:
        anglevel = 3.0 * self._speed
        steps = 1 + int(abs(angle)/anglevel)
        delta = 1.0*angle/steps
        for _ in range(steps):
            self._orient = self._orient.rotate(delta)
            self._update()
    self._orient = neworient
    
    angle = self.heading()
    shapename = self._imagename + "_" + str(angle)
    if shapename not in self.screen.getshapes():
        im = self._rawim.rotate(angle,expand=1)
        sp = Shape('image',ImageTk.PhotoImage(im))        
        self.screen.addshape(shapename,sp)
    self.shape(shapename)        
    self._update()
    
RawTurtle._rotate = _rotate

def _shape(self, name=None):
    """设定海龟的造型,用给定的文件名或造型名称"""
    if name is None:
        return self.turtle.shapeIndex
    if not name in self.screen.getshapes():
        shape = name
        if os.path.isfile(shape):           # 如果是文件        
            shapename = self._place_to_shapes(shape)                
            self.turtle._setshape(shapename)
        else:
            raise TurtleGraphicsError("There is no shape named %s" % name)
    else:
        self.turtle._setshape(name)
    self._update()
RawTurtle.shape = _shape

if __name__ == '__main__':
        
    from time import sleep
    images = [f"cats/{i}.png" for i in range(16)]

    cat = Sprite()
    cat2 = Sprite()
    i = 0
    while True:
        cat.shape(images[i])
        cat2.shape(images[i])
        i = i + 1
        i = i % 16
        sleep(0.1)
        cat.left(1)
        cat2.right(1)

关于李兴球

李兴球的博客是Python创意编程原创博客
此条目发表在python, turtle分类目录,贴了, 标签。将固定链接加入收藏夹。

发表回复