Python Turtle shape()でつまずかない!よくあるエラーと解決策
この関数には、主に2つの使い方があります。
-
turtle.shape(name)
の形式で使います。ここでname
は文字列で、利用可能な形を指定します。- Pythonの
turtle
モジュールには、いくつかの組み込みの形が用意されています。一般的なものは以下の通りです。"arrow"
(デフォルト)"turtle"
(カメの形)"circle"
"square"
"triangle"
"classic"
(古いバージョンでのデフォルトの三角形)
- 例
import turtle screen = turtle.Screen() t = turtle.Turtle() t.shape("turtle") # カメの形にする t.forward(100) t.shape("circle") # 円の形にする t.left(90) t.forward(100) screen.mainloop()
-
現在のカメの形を返す
- 引数なしで
turtle.shape()
を呼び出すと、現在設定されているカメの形(文字列)を返します。 - 例
import turtle t = turtle.Turtle() print(t.shape()) # デフォルトの "arrow" が表示されるはずです t.shape("square") print(t.shape()) # "square" が表示されます
- 引数なしで
turtle.shape()
:現在のカメの形(文字列)を返します。turtle.shape("名前")
:カメの見た目を指定された形に変更します。
NameError: name 'turtle' is not defined
エラーの原因
turtle
モジュールが正しくインポートされていない場合に発生します。turtle.shape()
を呼び出す前に、turtle
モジュールを使用可能にする必要があります。
トラブルシューティング
スクリプトの先頭に import turtle
を追加してください。通常、カメのオブジェクトを作成する際には t = turtle.Turtle()
のように turtle
モジュールをプレフィックスとして使用します。
例
# 悪い例
# t = Turtle() # これではNameErrorになる可能性あり
# t.shape("turtle")
# 良い例
import turtle # まずモジュールをインポート
t = turtle.Turtle()
t.shape("turtle")
AttributeError: 'Turtle' object has no attribute 'shape'
エラーの原因
これはあまり一般的ではありませんが、turtle
モジュールの特定のバージョンや環境、あるいは変数名が重複している場合に起こりえます。例えば、自分で turtle.py
という名前のファイルを作成してしまい、標準の turtle
モジュールではなく自分のファイルがインポートされてしまう「モジュールのシャドウイング」が原因となることがあります。
トラブルシューティング
- 環境の確認
非常に稀ですが、Pythonのインストールが破損している可能性も考えられます。その場合はPythonの再インストールを検討してください。 - ファイル名の確認
あなたのPythonスクリプトと同じディレクトリ内にturtle.py
という名前のファイルがないか確認してください。もしあれば、そのファイルの名前を変更してください(例:my_turtle_program.py
)。
無効な形状名を指定した場合
エラーの原因
turtle.shape()
には、事前に定義されたいくつかの文字列(例: "arrow"
, "turtle"
, "circle"
, "square"
, "triangle"
, "classic"
)しか指定できません。存在しない形状名を指定すると、カメの形は変更されず、Pythonはエラーを発生させずにデフォルトの形を維持する場合があります(ただし、これはPythonのバージョンや実装に依存する可能性があります)。より古いバージョンでは、エラーになることもあります。
トラブルシューティング
- カスタムの形状(画像ファイルなど)を使用したい場合は、
screen.register_shape("filepath.gif")
のように、turtle.Screen()
オブジェクトのregister_shape()
メソッドを使って事前に登録する必要があります。その後、turtle.shape("filepath.gif")
のように登録した名前で形状を指定できます。 turtle.shape()
に渡す文字列が、上記のような組み込みの有効な形状名であることを確認してください。
例
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
# 組み込みの有効な形
t.shape("square")
t.forward(50)
# 無効な形(エラーは出ないことが多いが、形は変わらない)
t.shape("rectangle") # "rectangle" は組み込みの形ではない
t.forward(50)
# カスタムの形を登録して使用する例 (実際にはGIFファイルが必要)
# screen.register_shape("my_image.gif")
# t.shape("my_image.gif")
# t.forward(50)
screen.mainloop()
エラーの原因
turtle.shape()
自体は正しく機能しているものの、他の設定や描画のタイミングによって、期待通りに形が見えないことがあります。
- mainloop() または done() の不足
turtle
グラフィックウィンドウは、プログラムの最後にturtle.Screen().mainloop()
(またはturtle.done()
、turtle.exitonclick()
) を呼び出さないとすぐに閉じてしまうことがあります。これにより、形を設定するコードが実行されても、ウィンドウが表示される前に終了してしまうため、変化を確認できません。 - カメが画面外にいる
カメが描画領域外に移動している場合、形を確認できません。t.goto(0,0)
などで中央に戻してみると良いでしょう。 - hideturtle() が呼び出されている
t.hideturtle()
を呼び出している場合、カメは非表示になります。t.showturtle()
を呼び出して表示させる必要があります。 - tracer(0) と update() の不足
パフォーマンス向上のためにscreen.tracer(0)
を使用している場合、描画は即座に反映されません。変更を画面に表示するには、明示的にscreen.update()
を呼び出す必要があります。
トラブルシューティング
t.home()
やt.goto(x, y)
でカメを画面の中央に移動させてみる。t.showturtle()
が呼び出されていることを確認する。screen.tracer(0)
を使っている場合は、形状変更後にscreen.update()
を呼び出す。- コードの最後に
screen.mainloop()
またはturtle.done()
を追加して、ウィンドウが閉じないようにする。
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
# tracer(0) を使っている場合の例
screen.tracer(0) # 自動描画をオフにする
t.shape("turtle")
t.forward(50)
screen.update() # 変更を反映させる
t.hideturtle() # カメを非表示にする
t.forward(50)
screen.update()
t.showturtle() # カメを表示する
t.shape("circle")
t.forward(50)
screen.update()
screen.mainloop() # ウィンドウが開いたままになるようにする
turtle.shape()
は、Pythonの turtle
グラフィックモジュールで、描画を行う「カメ」の見た目を変更するために使われます。
カメの形を組み込みの形状に変更する
turtle
モジュールには、いくつかの標準的な形状が用意されています。
"classic"
"triangle"
"square"
"circle"
"turtle"
"arrow"
(デフォルト)
例コード1: 様々な組み込み形状を試す
import turtle # turtleモジュールをインポートします
# 描画スクリーンとカメのオブジェクトを作成します
screen = turtle.Screen()
t = turtle.Turtle()
# ----------------------------------------
# 1. デフォルトの形 (arrow)
print("現在の形:", t.shape()) # デフォルトは "arrow" です
t.forward(50) # 前に進みます
# ----------------------------------------
# 2. カメの形に変更
t.shape("turtle") # カメの形にします
print("現在の形:", t.shape())
t.penup() # ペンを上げます (描画しない)
t.goto(-100, 50) # 別の位置に移動します
t.pendown() # ペンを下げます (描画する)
t.forward(100) # 前に進みます
# ----------------------------------------
# 3. 円の形に変更
t.shape("circle") # 円の形にします
print("現在の形:", t.shape())
t.penup()
t.goto(0, 50)
t.pendown()
t.circle(50) # 半径50の円を描きます
# ----------------------------------------
# 4. 四角の形に変更
t.shape("square") # 四角の形にします
print("現在の形:", t.shape())
t.penup()
t.goto(100, 50)
t.pendown()
for _ in range(4): # 四角形を描きます
t.forward(50)
t.right(90)
# ----------------------------------------
# 5. 三角の形に変更
t.shape("triangle") # 三角の形にします
print("現在の形:", t.shape())
t.penup()
t.goto(-150, -50)
t.pendown()
for _ in range(3): # 正三角形を描きます
t.forward(100)
t.left(120)
# ----------------------------------------
# 6. クラシックな形 (古いバージョンのデフォルト)
t.shape("classic") # クラシックな形にします
print("現在の形:", t.shape())
t.penup()
t.goto(50, -50)
t.pendown()
t.dot(20) # ドットを描きます
# ウィンドウがすぐに閉じないようにします
screen.mainloop()
解説
この例では、turtle.Turtle()
オブジェクト t
を作成し、t.shape()
メソッドを使ってその見た目を様々に変更しています。t.penup()
と t.pendown()
は、移動中に線を描くか描かないかを切り替えるために使われます。screen.mainloop()
は、描画ウィンドウが開いたままになり、ユーザーが閉じるまでプログラムが終了しないようにするために重要です。
カスタムの形状(画像ファイル)を登録して使用する
turtle
は、GIF形式の画像ファイルをカメの形状として使用することができます。これを行うには、まず screen.register_shape()
メソッドで画像を登録し、その後 t.shape()
でその登録名を指定します。
例コード2: GIF画像をカメの形として使う
注意
このコードを実行する前に、スクリプトと同じディレクトリに my_turtle_image.gif
という名前のGIF画像ファイルがあることを確認してください。
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
# GIF画像を登録します
# 必ず、このスクリプトと同じフォルダに 'my_turtle_image.gif' というファイルがあることを確認してください。
try:
screen.register_shape("my_turtle_image.gif")
print("GIF画像が登録されました。")
except turtle.TurtleGraphicsError:
print("エラー: 'my_turtle_image.gif' ファイルが見つからないか、読み込めません。")
print("GIF画像ファイルを用意し、スクリプトと同じディレクトリに置いてください。")
print("デフォルトの形状で続行します。")
t.shape("turtle") # エラーの場合はデフォルトのカメの形にする
else:
# 登録された形状をカメに適用します
t.shape("my_turtle_image.gif")
print("カメの形をGIF画像に変更しました。")
# カメを動かしてみます
t.penup()
t.goto(-150, 0)
t.pendown()
t.forward(300)
t.right(90)
t.forward(100)
t.left(90)
t.forward(100)
screen.mainloop()
解説
screen.register_shape("my_turtle_image.gif")
:turtle.Screen
オブジェクトのregister_shape()
メソッドを使って、my_turtle_image.gif
というファイルを新しい形状として登録しています。この際、ファイル名(パスを含む)を引数として渡します。t.shape("my_turtle_image.gif")
:カメのshape()
メソッドに、先ほどregister_shape()
で登録した名前(ファイル名)を文字列として渡すことで、その画像がカメの見た目として適用されます。try...except
ブロックは、GIFファイルが見つからないなどのエラーが発生した場合にプログラムがクラッシュしないようにするためのものです。
アニメーションとtracer() update() との連携
複雑な描画やアニメーションを行う際に、screen.tracer(0)
を使って画面の自動更新を一時停止することがあります。この場合、形状の変更も即座に反映されません。変更を画面に表示するには、明示的に screen.update()
を呼び出す必要があります。
例コード3: tracer()
と update()
を使った形状変更アニメーション
import turtle
import time # 時間を制御するためにtimeモジュールをインポート
screen = turtle.Screen()
t = turtle.Turtle()
t.speed(0) # 最速に設定
# 自動描画をオフにします (これにより、処理が速くなります)
screen.tracer(0)
shapes = ["arrow", "turtle", "circle", "square", "triangle", "classic"]
colors = ["red", "orange", "yellow", "green", "blue", "purple"]
x_pos = -200
for i in range(len(shapes)):
current_shape = shapes[i]
current_color = colors[i]
t.penup()
t.goto(x_pos, 0) # 各カメの位置を設定
t.pendown()
t.color(current_color) # カメの色を設定
t.shape(current_shape) # カメの形を変更
# 形と色の変更を画面に反映させる
screen.update()
t.forward(50) # カメを少し動かす
screen.update() # もう一度更新
time.sleep(0.5) # 0.5秒間待機 (アニメーションの感覚)
x_pos += 80 # 次のカメのX位置を調整
# 最後の更新で全てを表示
screen.update()
screen.mainloop()
screen.tracer(0)
:画面の自動更新を無効にしています。これにより、t.shape()
やt.color()
などの変更がすぐに画面に反映されなくなります。time.sleep(0.5)
:各形状が切り替わる間に0.5秒の遅延を入れることで、アニメーション効果を作り出しています。
hideturtle() と dot()/stamp() を組み合わせて使う
カメ自体の形を隠し、代わりに点 (dot()
) やスタンプ (stamp()
) を使って、描画の印を残す方法です。これにより、カメの形状に縛られずに、様々なサイズの点や、カメが通過した軌跡に印を付けていくことができます。
例コード1: ドットとスタンプの活用
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
t.speed(0) # 描画速度を最速に設定
t.hideturtle() # カメのカーソルを非表示にする
# ----------------------------------------
# 1. dot() を使って点を描く
t.penup()
t.goto(-100, 50)
t.pendown()
t.color("blue")
t.dot(20) # 直径20ピクセルの青い点を描く
t.forward(50)
t.color("red")
t.dot(30) # 直径30ピクセルの赤い点を描く
t.forward(50)
# ----------------------------------------
# 2. stamp() を使ってカメの現在の形状の「スタンプ」を押す
# (hideturtle()しているので、実際には見えないカメの形状がスタンプされる)
# ただし、デフォルト形状(矢印)がスタンプされることに注意
t.penup()
t.goto(-100, -50)
t.pendown()
t.color("green")
# 現在の形状(非表示のデフォルト矢印)をスタンプ
stamp_id1 = t.stamp() # スタンプのIDを返す
t.forward(50)
t.color("purple")
stamp_id2 = t.stamp()
# スタンプを消すことも可能
# t.clearstamp(stamp_id1)
# t.clearstamp(stamp_id2)
screen.mainloop()
解説
t.stamp()
: 現在のカメの形状(hideturtle()
していても、その時の設定形状)を、現在の位置と向きで「スタンプ」のように画面に残します。これは、描画物の一部として残ります。clearstamp()
やclearstamps()
で後で消すことも可能です。t.dot(size)
: 現在のカメの位置に、指定された直径の丸い点(ドット)を描画します。t.color()
で色も指定できます。t.hideturtle()
: カメのカーソル自体を画面から隠します。これにより、カメの形状にとらわれずに描画できます。
Pen オブジェクトを複数使用する
turtle
モジュールでは、複数の Turtle
オブジェクトを作成できます。それぞれに異なる形状や色を設定することで、複数の「エージェント」を動かすような表現が可能です。
例コード2: 複数のカメと異なる形状
import turtle
screen = turtle.Screen()
screen.setup(width=600, height=400) # スクリーンサイズを設定
# 最初のカメ
t1 = turtle.Turtle()
t1.shape("turtle") # カメの形
t1.color("blue")
t1.penup()
t1.goto(-200, 0)
t1.pendown()
# 2番目のカメ
t2 = turtle.Turtle()
t2.shape("circle") # 円の形
t2.color("red")
t2.penup()
t2.goto(0, 0)
t2.pendown()
# 3番目のカメ
t3 = turtle.Turtle()
t3.shape("square") # 四角の形
t3.color("green")
t3.penup()
t3.goto(200, 0)
t3.pendown()
# それぞれのカメを動かす
t1.forward(100)
t2.left(90)
t2.forward(100)
t3.right(90)
t3.forward(100)
screen.mainloop()
解説
複数の turtle.Turtle()
オブジェクトを作成し、それぞれに独立した shape()
や color()
を設定しています。これにより、異なる見た目の複数のカメを同時に制御できます。これは、シミュレーションやゲーム開発の基本的な要素となります。
グラフィックプリミティブ(線、円、塗りつぶし)で描画する
turtle
モジュールは、カメの移動だけでなく、直接的な描画命令も持っています。これにより、カメの形状に依存せず、より自由な図形を描画できます。
例コード3: begin_fill()
/end_fill()
と circle()
でカスタム図形を描く
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
t.hideturtle() # カメを非表示にして、描画に集中
# ----------------------------------------
# 1. 塗りつぶされた星を描く
t.penup()
t.goto(-150, 50)
t.pendown()
t.color("gold", "orange") # ペンの色、塗りつぶしの色
t.begin_fill() # 塗りつぶしを開始
for _ in range(5):
t.forward(100)
t.right(144)
t.end_fill() # 塗りつぶしを終了
# ----------------------------------------
# 2. 塗りつぶされたハートを描く (少し複雑な例)
t.penup()
t.goto(50, 0)
t.pendown()
t.color("red", "pink")
t.begin_fill()
t.left(140)
t.forward(113)
for i in range(200):
t.right(1)
t.forward(1)
t.left(120)
for i in range(200):
t.right(1)
t.forward(1)
t.forward(113)
t.end_fill()
screen.mainloop()
解説
t.begin_fill()
/t.end_fill()
: これらのメソッドの間で描かれた閉じたパスが、指定されたfillcolor
で塗りつぶされます。これにより、turtle.shape()
では表現できない、より複雑な塗りつぶし図形を作成できます。t.color(pencolor, fillcolor)
: ペンの色と、begin_fill()
とend_fill()
の間で描画される図形の塗りつぶし色を設定します。t.hideturtle()
: カメの形状を見せる必要がない場合に、描画自体に集中するためにカメを非表示にします。
他のPythonグラフィックライブラリの検討
turtle
モジュールは学習には最適ですが、より高度なグラフィックやゲーム開発には向いていません。より複雑な表現やインタラクションが必要な場合は、以下のライブラリを検討してください。
- Matplotlib: データ可視化ライブラリですが、プロット機能を使って幾何学的な図形を描画することも可能です。
- Tkinter / PyQt / Kivy: これらはGUI(グラフィカルユーザーインターフェース)開発ライブラリですが、Canvasウィジェットなどを使ってグラフィックを描画することも可能です。インタラクティブなアプリケーションの一部としてグラフィックが必要な場合に適しています。
- Pyglet: Pygameと同様にゲーム開発に使われますが、よりオブジェクト指向的でOpenGLの上に構築されています。
- Pygame: 2Dゲーム開発に非常に広く使われているライブラリです。スプライト(画像)、衝突判定、サウンド、イベント処理など、ゲームに必要な機能が豊富です。