Turtle Graphics入門:shapesize()でPythonカメの大きさを操る方法

2025-06-06

この関数は、タートルの現在の形状(デフォルトでは矢印)の大きさを変更します。引数を指定しない場合、現在のサイズ設定を返します。

引数:

turtle.shapesize() には以下の引数を指定できます。

  • outline: 形状のアウトライン(輪郭)の幅。
  • stretch_len: 形状の長さ方向のストレッチ係数(横方向の拡大/縮小)。
  • stretch_wid: 形状の幅方向のストレッチ係数(縦方向の拡大/縮小)。

これらの引数はすべてオプションで、指定しない場合はデフォルト値が使用されます。通常、stretch_widstretch_len に同じ値を設定することで、アスペクト比を維持したまま形状を拡大縮小できます。

使用例:

import turtle

# タートルオブジェクトを作成
t = turtle.Turtle()

# デフォルトのサイズ(通常は1倍)
# t.shapesize()

# 幅と長さを2倍に拡大 (アスペクト比を維持)
t.shapesize(stretch_wid=2, stretch_len=2)

# 幅を3倍、長さを1倍(横に細長く)
# t.shapesize(stretch_wid=3, stretch_len=1)

# アウトラインの幅を5ピクセルに設定
# t.shapesize(outline=5)

# 幅を2倍、長さを2倍、アウトラインを3ピクセルに設定
# t.shapesize(stretch_wid=2, stretch_len=2, outline=3)

turtle.done()

上記の例では、t.shapesize(stretch_wid=2, stretch_len=2) を実行すると、タートルの形状が縦横ともに2倍の大きさになります。



turtle.shapesize() は比較的使いやすい関数ですが、いくつか注意すべき点や、予期せぬ挙動を招く可能性のあるケースがあります。

引数の型エラー (TypeError)

エラーの状況
shapesize() に数値以外の値を渡した場合。


import turtle
t = turtle.Turtle()
# t.shapesize("two", 2) # TypeError: must be real number, not str

原因
stretch_wid, stretch_len, outline の引数は、すべて数値(整数または浮動小数点数)である必要があります。文字列などの無効な型を渡すと TypeError が発生します。

トラブルシューティング

  • 変数を使用している場合は、その変数の型が正しいかを確認してください。
  • 引数に渡す値が数値であることを確認してください。

引数の不足または過多 (TypeError)

エラーの状況
shapesize() の呼び出し時に、期待される引数の数と異なる数の引数を渡した場合。


import turtle
t = turtle.Turtle()
# t.shapesize(2, 2, 2, 2) # TypeError: shapesize() takes at most 3 positional arguments (4 given)

原因
shapesize() は、stretch_wid, stretch_len, outline の3つのオプション引数を取ります。それ以上の引数を渡すとエラーになります。また、必須引数はありませんが、意図しない引数渡しはエラーにつながります。

トラブルシューティング

  • 各引数が正しい位置にあり、キーワード引数(例: stretch_wid=2)を使っている場合はスペルミスがないか確認してください。
  • shapesize() に渡す引数の数が3つ以内であることを確認してください。

負の値の指定

エラーの状況
stretch_wid, stretch_len, outline に負の値を指定した場合。


import turtle
t = turtle.Turtle()
# t.shapesize(-2, 2) # 形状が反転したり、予期せぬ表示になる可能性があります。
# t.shapesize(2, 2, -1) # エラーにはなりませんが、アウトラインが描画されない、または表示されないことがあります。

原因
通常、ストレッチ係数やアウトラインの幅は正の値で指定します。負の値を指定すると、タートルの形状が反転したり(ミラーリング)、アウトラインが表示されなかったりする可能性があります。エラーにはならないことが多いですが、意図しない視覚的結果を招きます。

トラブルシューティング

  • 形状を反転させたい場合は、setheading()left(), right() などでタートルの向きを変更するか、t.setx(-t.xcor()) のように座標を直接操作することを検討してください。
  • shapesize() の引数には、0または正の値を指定してください。

形状の変更が反映されない

エラーの状況
shapesize() を呼び出したにもかかわらず、タートルの形状のサイズが変わらないように見える。

原因

  • 同じ形状を何度も設定している
    既に設定されているサイズと同じ値を再度設定しても、視覚的な変化はありません。
  • 画面の更新が行われていない
    非常に高速な処理で形状サイズを変更し、画面の更新が間に合っていない場合、変更が見えにくいことがあります。
  • タートルの形状がカスタム形状である場合
    turtle.shape() でカスタム形状(例えば、turtle.addshape() で追加した画像など)を設定している場合、shapesize() はそのカスタム形状には適用されません。shapesize() は主にデフォルトの「矢印」形状や、turtle.shape("circle"), turtle.shape("square") などの組み込み形状に効果があります。

トラブルシューティング

  • 意図したサイズになっているか、または既にそのサイズに設定されていないかを確認してください。
  • 描画が完了した後に turtle.done() または turtle.exitonclick() を呼び出して、画面が適切に表示されていることを確認してください。アニメーションの場合は、turtle.update()turtle.tracer() を使うことで描画の最適化を検討してください。
  • turtle.shape() で設定している形状が、shapesize() が適用される組み込み形状であることを確認してください。カスタム形状の場合は、画像編集ソフトウェアでサイズを調整するか、画像を別の方法でスケーリングする必要があります。

形状の見た目の問題(ピクセル化など)

エラーの状況
shapesize() でタートルを大きくしすぎると、形状がピクセル化して見える、または粗く見える。

原因
turtle モジュールが描画する形状は、多くの場合ベクターグラフィックス(線や単純な幾何学図形)ですが、内部的にはピクセルに変換されて描画されます。特に小さな基本形状を非常に大きくストレッチすると、その変換プロセスでピクセル化が目立つことがあります。

  • ある程度のピクセル化は避けられないものとして受け入れるか、あるいは形状を最初から大きく定義し直すことを検討してください(ただし、これはturtleモジュールのデフォルト形状では難しい場合が多いです)。
  • turtle グラフィックスは、複雑な画像処理や高解像度の描画には向いていません。より高品質なグラフィックスが必要な場合は、Pyglet や Pygame などの他のライブラリの利用を検討してください。


例1: タートルの基本的なサイズ変更

最も基本的な使い方で、タートルの縦横のサイズを均等に拡大・縮小します。

import turtle

# 画面とタートルを設定
screen = turtle.Screen()
screen.setup(width=600, height=400) # 画面サイズを設定
screen.bgcolor("lightblue") # 背景色を設定
screen.title("基本的なサイズ変更")

t = turtle.Turtle()
t.shape("turtle") # タートルの形状を「カメ」に設定
t.color("green")  # 色を設定

# デフォルトのサイズで描画
t.penup()
t.goto(-200, 0)
t.pendown()
t.write("デフォルトサイズ", align="center", font=("Arial", 12, "normal"))
t.forward(50)

# 2倍のサイズに変更
t.penup()
t.goto(0, 0)
t.pendown()
t.shapesize(stretch_wid=2, stretch_len=2) # 縦横2倍に拡大
t.write("2倍サイズ", align="center", font=("Arial", 12, "normal"))
t.forward(50)

# 0.5倍のサイズに変更
t.penup()
t.goto(200, 0)
t.pendown()
t.shapesize(stretch_wid=0.5, stretch_len=0.5) # 縦横0.5倍に縮小
t.write("0.5倍サイズ", align="center", font=("Arial", 12, "normal"))
t.forward(50)

# 描画終了
screen.exitonclick() # クリックでウィンドウを閉じる

説明

  • shapesize(stretch_wid=0.5, stretch_len=0.5) は、0.5倍に縮小します。
  • shapesize(stretch_wid=2, stretch_len=2) は、タートルの幅(垂直方向)と長さ(水平方向)をそれぞれ2倍に拡大します。
  • t.shape("turtle") でタートルの形状をカメにします。デフォルトの矢印形状でも shapesize() は機能しますが、カメの形状の方が変化が分かりやすいです。

例2: 幅と長さを別々に変更(アスペクト比の変更)

タートルの形状を縦長や横長に引き伸ばすことができます。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightyellow")
screen.title("幅と長さの個別の変更")

t = turtle.Turtle()
t.shape("square") # 形状を四角に設定すると、変化が分かりやすい
t.color("red")

# デフォルトのサイズで描画
t.penup()
t.goto(-200, 0)
t.pendown()
t.write("デフォルト", align="center", font=("Arial", 12, "normal"))
t.forward(50)

# 幅を3倍、長さを1倍(縦長)
t.penup()
t.goto(0, 0)
t.pendown()
t.shapesize(stretch_wid=3, stretch_len=1) # 幅を3倍、長さはそのまま
t.write("縦長 (幅3倍)", align="center", font=("Arial", 12, "normal"))
t.forward(50)

# 幅を1倍、長さを3倍(横長)
t.penup()
t.goto(200, 0)
t.pendown()
t.shapesize(stretch_wid=1, stretch_len=3) # 幅はそのまま、長さを3倍
t.write("横長 (長さ3倍)", align="center", font=("Arial", 12, "normal"))
t.forward(50)

screen.exitonclick()

説明

  • shapesize(stretch_wid=1, stretch_len=3) は、タートルの幅(縦方向)は元のままにし、長さ(横方向)を3倍にします。
  • shapesize(stretch_wid=3, stretch_len=1) は、タートルの幅(縦方向)を3倍にし、長さ(横方向)は元のままにします。
  • t.shape("square") を使うことで、四角形の形状がどのように伸び縮みするかが分かりやすくなります。

例3: アウトラインの太さの変更

タートルの形状のアウトライン(輪郭線)の太さを変更します。

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightgray")
screen.title("アウトラインの太さの変更")

t = turtle.Turtle()
t.shape("circle") # 形状を円に設定
t.color("blue", "cyan") # ペン色と塗りつぶし色を設定

# デフォルトのアウトライン
t.penup()
t.goto(-200, 0)
t.pendown()
t.write("デフォルトアウトライン", align="center", font=("Arial", 12, "normal"))
t.circle(30) # 半径30の円を描画

# アウトラインを太くする
t.penup()
t.goto(0, 0)
t.pendown()
t.shapesize(outline=5) # アウトラインの太さを5ピクセルに設定
t.write("アウトライン太さ5", align="center", font=("Arial", 12, "normal"))
t.circle(30)

# アウトラインをさらに太くする(サイズも変更)
t.penup()
t.goto(200, 0)
t.pendown()
t.shapesize(stretch_wid=1.5, stretch_len=1.5, outline=10) # サイズも1.5倍、アウトラインは10ピクセル
t.write("サイズ1.5倍、アウトライン10", align="center", font=("Arial", 12, "normal"))
t.circle(30)

screen.exitonclick()

説明

  • shapesize(stretch_wid=1.5, stretch_len=1.5, outline=10) のように、複数の引数を組み合わせて使用することも可能です。
  • shapesize(outline=5) は、アウトラインの太さを5ピクセルに設定します。ストレッチ係数を指定しない場合、デフォルト値(通常1.0)が使われます。
  • t.color("blue", "cyan") は、ペン色(アウトラインの色)を青に、塗りつぶし色をシアンに設定します。
  • t.shape("circle") を使うと、円の形状のアウトラインの太さの変化が分かりやすいです。

例4: アニメーションでサイズ変更を行う

shapesize() をループの中で使うことで、タートルが脈動するようなアニメーションを作成できます。

import turtle
import time

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("darkblue")
screen.title("サイズ変更アニメーション")
screen.tracer(0) # 画面の自動更新をオフにする(スムーズなアニメーションのため)

t = turtle.Turtle()
t.shape("circle")
t.color("gold")
t.penup() # 線を描かずに移動

# サイズ変更アニメーション
for i in range(100):
    # サイズを変化させる(例: 0.5から2.0の間で変動)
    scale = 1 + 0.5 * (1 + (i % 20 - 10) / 10) # 0.5から1.5の範囲で変化
    t.shapesize(stretch_wid=scale, stretch_len=scale)

    screen.update() # 画面を手動で更新
    time.sleep(0.05) # 少し待機

# アニメーション終了後、元のサイズに戻す
t.shapesize(stretch_wid=1, stretch_len=1)
screen.update()

screen.exitonclick()
  • scale の計算: ここでは i の値に基づいて scale の値を周期的に変化させています。これにより、タートルが拡大・縮小を繰り返す脈動効果が生まれます。
  • time.sleep(0.05): 各フレームの間に短い間隔を置くことで、アニメーションの速度を制御します。
  • screen.update(): tracer(0) を使用している場合、変更を画面に反映させるためには手動で screen.update() を呼び出す必要があります。
  • screen.tracer(0): これが最も重要なポイントです。画面の自動更新をオフにすることで、描画処理が速くなり、よりスムーズなアニメーションを実現できます。


turtle.shapesize() の代替方法

タートルの代わりにスタンプ (turtle.stamp()) を使用し、異なるサイズのスタンプを押す

turtle.stamp() は、現在のタートルの形状と向きで画面上に「スタンプ」を押す機能です。タートルそのもののサイズを変更するのではなく、異なるサイズのスタンプを複数押すことで、サイズのバリエーションを表現できます。

特徴

  • バリエーション
    異なるサイズのオブジェクトを同時に表示するのに適しています。
  • 静的
    一度押されたスタンプは、タートルの動きやサイズ変更の影響を受けません(ただし、クリアすることはできます)。
  • 非破壊的
    元のタートルのサイズは変わりません。


import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightgreen")
screen.title("スタンプでサイズを表現")

t = turtle.Turtle()
t.shape("circle") # 円の形状
t.color("purple")
t.penup() # 線を描かない

# 小さいサイズのスタンプ
t.shapesize(stretch_wid=0.5, stretch_len=0.5)
t.goto(-150, 0)
t.stamp()

# 中くらいのサイズのスタンプ
t.shapesize(stretch_wid=1.0, stretch_len=1.0) # デフォルトサイズ
t.goto(0, 0)
t.stamp()

# 大きいサイズのスタンプ
t.shapesize(stretch_wid=2.0, stretch_len=2.0)
t.goto(150, 0)
t.stamp()

# 注意: タートル自身のサイズは最後に設定されたshapesize()のまま
t.shapesize(stretch_wid=1, stretch_len=1) # タートルをデフォルトサイズに戻す
t.goto(0, -100)
t.color("black")
t.pendown()
t.circle(20) # タートル自身のサイズで円を描く

screen.exitonclick()

複数の異なるタートルオブジェクトを作成する

それぞれのタートルオブジェクトに異なる shapesize() を設定することで、複数の異なるサイズのオブジェクトを同時に管理できます。

特徴

  • 管理
    オブジェクト指向プログラミングの考え方に基づき、複数の要素を管理するのに適しています。
  • 動的
    それぞれのタートルを個別に動かしたり、サイズを変更したりできます。
  • 独立性
    各タートルが独自のサイズ、色、向き、位置を持つことができます。


import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightgray")
screen.title("複数のタートルオブジェクト")

# 小さいタートル
small_turtle = turtle.Turtle()
small_turtle.shape("arrow")
small_turtle.color("blue")
small_turtle.penup()
small_turtle.goto(-150, 50)
small_turtle.shapesize(stretch_wid=0.5, stretch_len=0.5) # 小さいサイズ

# 中くらいのタートル
medium_turtle = turtle.Turtle()
medium_turtle.shape("triangle")
medium_turtle.color("red")
medium_turtle.penup()
medium_turtle.goto(0, 50)
medium_turtle.shapesize(stretch_wid=1.0, stretch_len=1.0) # デフォルトサイズ

# 大きいタートル
large_turtle = turtle.Turtle()
large_turtle.shape("square")
large_turtle.color("green")
large_turtle.penup()
large_turtle.goto(150, 50)
large_turtle.shapesize(stretch_wid=2.0, stretch_len=2.0) # 大きいサイズ

# それぞれのタートルを動かす例
small_turtle.pendown()
small_turtle.forward(50)
medium_turtle.pendown()
medium_turtle.left(90)
medium_turtle.forward(50)
large_turtle.pendown()
large_turtle.right(90)
large_turtle.forward(50)

screen.exitonclick()

カスタム形状を異なるサイズで作成する (turtle.addshape())

turtle.shapesize() は主に組み込みの形状("arrow", "circle", "square" など)に対して機能します。もし画像ファイルやカスタムのベクター形状(タートルの頂点リストで定義されるもの)を使用している場合、shapesize() は適用されません。この場合、異なるサイズの画像ファイルを準備するか、プログラムで形状の頂点をスケーリングして新しい形状として登録する必要があります。

特徴

  • 複雑性
    画像ファイルの準備や頂点リストの操作が必要になるため、やや複雑になります。
  • 静的または動的
    一度追加された形状は静的ですが、必要に応じてプログラムで動的に新しいサイズの形状を生成・登録できます。
  • 高度な制御
    完全に独自の形状や画像を使用できます。

例 (概念的、具体的な画像ファイルや複雑な頂点リストは省略)

import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("lightyellow")
screen.title("カスタム形状のサイズ変更 (概念)")

# 例1: 異なるサイズの画像ファイルを読み込む場合
# (これはPythonのTurtleで画像を扱う標準的な方法であり、shapesize()の代替となる)
# screen.addshape("small_image.gif")
# screen.addshape("medium_image.gif")
# screen.addshape("large_image.gif")

# t1 = turtle.Turtle()
# t1.shape("small_image.gif")
# t1.goto(-150, 0)
# t1.stamp()

# t2 = turtle.Turtle()
# t2.shape("medium_image.gif")
# t2.goto(0, 0)
# t2.stamp()

# t3 = turtle.Turtle()
# t3.shape("large_image.gif")
# t3.goto(150, 0)
# t3.stamp()


# 例2: プログラムで頂点リストをスケーリングして新しい形状を登録する場合 (より高度)
# 例えば、元の三角形の頂点: ((0, 0), (10, 0), (5, 10))
# スケーリング後の三角形の頂点: ((0, 0), (20, 0), (10, 20))

# screen.register_shape("custom_small_triangle", ((0, 0), (10, 0), (5, 10)))
# screen.register_shape("custom_large_triangle", ((0, 0), (20, 0), (10, 20)))

# t = turtle.Turtle()
# t.shape("custom_small_triangle")
# t.goto(-100, 0)
# t.stamp()

# t.shape("custom_large_triangle")
# t.goto(100, 0)
# t.stamp()

# 注: 上記は概念的なコードです。実際の画像ファイルや頂点リストが必要です。

t_info = turtle.Turtle()
t_info.hideturtle()
t_info.penup()
t_info.goto(0, 0)
t_info.write("カスタム形状のサイズ変更は、\n画像ファイルの準備や\n頂点のスケーリングが必要です。",
             align="center", font=("Arial", 16, "normal"))

screen.exitonclick()

描画する図形のサイズを調整する (circle(), forward() など)

shapesize() はタートル「自体」の見た目を変更しますが、タートルが描画する線や図形のサイズは、forward(), circle(), dot() などのメソッドの引数で直接制御します。

特徴

  • 柔軟性
    描画中に異なるサイズの図形を簡単に切り替えて描画できます。
  • 描画の制御
    タートルのサイズに関わらず、描画される要素の大きさを細かく調整できます。


import turtle

screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("antiquewhite")
screen.title("描画する図形のサイズ調整")

t = turtle.Turtle()
t.shape("arrow") # タートルの形状はデフォルト(shapesizeは使用しない)
t.color("darkblue")
t.speed(0) # 描画速度を最速に

t.penup()
t.goto(-200, 50)
t.pendown()

# 小さい円を描画
t.circle(20)

t.penup()
t.forward(100)
t.pendown()

# 中くらいの円を描画
t.circle(50)

t.penup()
t.forward(150)
t.pendown()

# 大きい円を描画
t.circle(80)

# タートルの線幅も調整可能
t.penup()
t.goto(-200, -100)
t.pendown()

t.pensize(1) # ペン幅1
t.forward(50)
t.write("ペン幅1", font=("Arial", 10, "normal"))

t.penup()
t.forward(100)
t.pendown()

t.pensize(5) # ペン幅5
t.forward(50)
t.write("ペン幅5", font=("Arial", 10, "normal"))

screen.exitonclick()
  • t.pensize() を使うと、描画する線の太さを変更できます。
  • t.circle(20)t.circle(50)t.circle(80) のように、circle() メソッドの引数で半径を指定することで、異なるサイズの円を描画します。タートルの shapesize() は変更していません。
  • タートルが描画する「線」や「図形」のサイズを制御したい場合
    forward(), circle(), dot() などのメソッドの引数や、pensize() を使用します。
  • カスタムの画像や複雑な形状のサイズを制御したい場合
    turtle.addshape() で異なるサイズの形状を登録するか、画像ファイルを事前に準備する必要があります。
  • 複数の独立した、異なるサイズのオブジェクトを動的に制御したい場合
    複数のタートルオブジェクトを作成するのが適切です。
  • 複数の異なるサイズのオブジェクトを静的に表示したい場合
    turtle.stamp()shapesize() と組み合わせて使うと効率的です。
  • タートル自身の見た目をシンプルに拡大・縮小したい場合
    turtle.shapesize() が最適です。