turtle.speed()
turtle.speed()
とは?
この関数は、タートルが画面上を移動したり、線を描画したりする際のアニメーションの速さを制御します。引数に整数値、または特定の文字列を渡すことで速度を調整できます。
引数と速度
speed()
に渡せる引数は、主に以下の通りです。
-
文字列
"fastest"
:0
と同じ。アニメーションなし。"fast"
:10
と同じ。"normal"
:6
と同じ。"slow"
:3
と同じ。"slowest"
:1
と同じ。
-
0
: アニメーションなし。タートルは瞬時に移動します。これが最も速い設定です。1
: 最も遅い速度です。タートルの動きが非常にゆっくりとアニメーションされます。1
から10
の間で数値を大きくすると、速度が速くなります。3
: 通常より遅い6
: デフォルトの速度10
: 最速のアニメーション(ただし0
よりは遅い)
使用例
import turtle
# タートルオブジェクトを作成
t = turtle.Turtle()
# 速度を最も遅く設定
t.speed(1)
t.forward(100) # ゆっくり進む
# 速度をノーマルに設定
t.speed("normal")
t.left(90)
t.forward(100) # ノーマルな速さで進む
# 速度を最速(アニメーションなし)に設定
t.speed(0)
t.right(90)
t.forward(100) # 瞬時に進む
turtle.done() # ウィンドウが開いたままにする
- デバッグ
タートルの動きが意図した通りになっているかを確認するために、速度を調整することが役立ちます。 - 高速な描画
複雑な図形やパターンを素早く描画したい場合は、speed(0)
に設定することで、アニメーションの待機時間をなくし、すぐに結果を表示できます。 - 描画のデモンストレーション
描画プロセスをゆっくり見せたい場合に、速度を遅く設定します。
速度が期待通りに設定されない
問題
turtle.speed()
に値を設定しても、タートルの速度が思ったように変わらない、または最速(アニメーションなし)になってしまう。
考えられる原因と解決策
-
誤ったオブジェクトに対してspeed()を呼び出している
- 複数のタートルオブジェクトを作成している場合、意図したタートルに対して
speed()
を呼び出しているか確認してください。 - 解決策
my_turtle = turtle.Turtle()
のようにタートルオブジェクトを作成し、my_turtle.speed(5)
のようにそのオブジェクトのメソッドとして呼び出していることを確認してください。
- 複数のタートルオブジェクトを作成している場合、意図したタートルに対して
-
浮動小数点数の使用
turtle.speed()
は整数値を期待します。t.speed(0.5)
のような浮動小数点数を指定すると、最も近い整数に丸められるか、または最速(0
)として扱われることがあります。例えば、0.5
より大きい値は1
に丸められることが多いですが、動作は保証されません。- 解決策
整数値を使用してください。より細かい速度制御が必要な場合は、次に説明するscreen.delay()
を検討してください。
-
speed()
に渡せる数値は0
から10
までです。10
より大きい数値(例:t.speed(100)
)や0
より小さい数値(例:t.speed(-5)
)を渡すと、多くの場合、自動的に最速(0
または"fastest"
)として扱われます。- 解決策
引数が0
から10
の範囲内の整数、または有効な文字列("fastest"
,"fast"
,"normal"
,"slow"
,"slowest"
)であることを確認してください。
描画が遅すぎる、または全くアニメーションしない
問題
描画が非常に遅い、またはspeed(0)
を設定したのに瞬時に描画されない。
考えられる原因と解決策
-
プログラムがフリーズしたように見える
speed(0)
を設定するとアニメーションが瞬時に行われるため、描画が終わった後に何も起こらないとプログラムがフリーズしたように感じられることがあります。特に、描画後にturtle.done()
を呼び出していない場合、ウィンドウがすぐに閉じてしまうこともあります。- 解決策
描画終了後にturtle.done()
(またはscreen.exitonclick()
)を呼び出し、ウィンドウが閉じずに結果を確認できるようにしてください。
-
turtle.delay()の設定
turtle.delay()
は、各タートルの移動ステップの間にどれだけ遅延を入れるかをミリ秒単位で設定します。これはspeed()
とは独立して動作し、speed()
を最速に設定していても、delay()
の値が大きいと描画が遅くなります。- 解決策
turtle.delay(0)
を設定して、余分な遅延を取り除いてください。デフォルトは10
ミリ秒です。
-
描画処理の多さ
- 非常に多くの線を引いたり、複雑な計算を伴う描画を行う場合、
speed(0)
(最速)を設定しても、Pythonの実行速度やPCの処理能力が追いつかず、描画が遅く感じられることがあります。 - 解決策
- turtle.tracer(0)とturtle.update()の使用
これが最も効果的な高速化手法です。turtle.tracer(0)
を呼び出すと、タートルのアニメーション更新が一時停止されます。全ての描画コマンドを実行した後でturtle.update()
を呼び出すと、一度に全ての変更が画面に反映されます。これにより、アニメーションなしで非常に高速な描画が可能になります。import turtle t = turtle.Turtle() screen = turtle.Screen() screen.tracer(0) # アニメーションをオフにする for _ in range(360): t.forward(1) t.left(1) screen.update() # 全ての描画を一度に更新 turtle.done()
turtle.tracer(n, delay)
:n
フレームごとに描画を更新し、delay
ミリ秒の遅延を設定することもできます。デフォルトはtracer(1)
で、毎フレーム更新されます。- 描画ロジック自体を最適化する。
- turtle.tracer(0)とturtle.update()の使用
- 非常に多くの線を引いたり、複雑な計算を伴う描画を行う場合、
問題
AttributeError: 'NoneType' object has no attribute 'speed'
や AttributeError: 'module' object has no attribute 'speed'
などのエラーが発生する。
考えられる原因と解決策
- 変数名のスペルミス
- タートルオブジェクトの変数名を間違えている場合も、同様のエラーが発生する可能性があります。
- 解決策
変数名が正しく、大文字・小文字が一致しているか確認してください。
- turtle.Turtle()オブジェクトを作成していない
turtle.speed()
は、turtle
モジュールそのものではなく、作成したタートルオブジェクトのメソッドです。t = turtle.Turtle()
のようにオブジェクトを作成し、そのオブジェクトに対して呼び出す必要があります。- 解決策
import turtle # 正しい例: タートルオブジェクトを作成し、そのメソッドを呼び出す my_turtle = turtle.Turtle() my_turtle.speed(5) my_turtle.forward(100) # 間違った例: モジュール自体に対して呼び出すとエラーになる # turtle.speed(5) # これはエラーになる
turtle.speed()
の基本的な使い方
まずは、最も基本的な使い方を見ていきましょう。
import turtle
import time # 処理の遅延を確認するために使用
# 1. スクリーンとタートルオブジェクトを作成
screen = turtle.Screen()
t = turtle.Turtle()
# 2. 速度を最も遅く設定 (1)
print("速度: 1 (最も遅い)")
t.speed(1)
t.forward(100)
t.left(90)
# 3. 速度をノーマルに設定 (6)
print("速度: normal (デフォルト、中程度)")
t.speed("normal") # または t.speed(6)
t.forward(100)
t.left(90)
# 4. 速度を最速のアニメーション (10)
print("速度: fastest (アニメーションありで最速)")
t.speed(10) # または t.speed("fast")
t.forward(100)
t.left(90)
# 5. 速度をアニメーションなし (0)
print("速度: 0 (アニメーションなし、瞬時に描画)")
t.speed(0) # または t.speed("fastest")
t.forward(100)
t.left(90)
# 6. ウィンドウを閉じるまで待機
screen.mainloop() # または turtle.done()
解説
screen.mainloop()
: タートルグラフィックスのウィンドウが開いたままになり、ユーザーが閉じるまで待機します。t.left(90)
: タートルを左に90度回転させます。t.forward(100)
: タートルを100ピクセル前進させます。t.speed(引数)
: タートルの速度を設定します。1
: 最も遅いアニメーション。"normal"
(または6
): デフォルトの速度。10
(または"fast"
): アニメーションがある中での最速。0
(または"fastest"
): アニメーションなしで瞬時に描画されます。
t = turtle.Turtle()
: タートル(描画するペン)オブジェクトを作成します。screen = turtle.Screen()
: 描画を行うスクリーン(ウィンドウ)オブジェクトを作成します。import turtle
: turtleモジュールをインポートします。
応用例1: 速度の違いを比較する
複数のタートルを使って、異なる速度での描画を比較してみましょう。
import turtle
screen = turtle.Screen()
screen.setup(width=600, height=400) # ウィンドウサイズを設定
# 最初のタートル (遅い)
t1 = turtle.Turtle()
t1.color("red")
t1.penup()
t1.goto(-200, 50)
t1.pendown()
t1.speed(1) # 遅い
t1.write("Slow (Speed 1)", font=("Arial", 12, "normal"))
# 2番目のタートル (ノーマル)
t2 = turtle.Turtle()
t2.color("blue")
t2.penup()
t2.goto(-200, 0)
t2.pendown()
t2.speed("normal") # ノーマル
t2.write("Normal (Speed 'normal')", font=("Arial", 12, "normal"))
# 3番目のタートル (速い)
t3 = turtle.Turtle()
t3.color("green")
t3.penup()
t3.goto(-200, -50)
t3.pendown()
t3.speed(10) # 速い
t3.write("Fast (Speed 10)", font=("Arial", 12, "normal"))
# 各タートルに描画させる
for _ in range(4):
t1.forward(50)
t1.left(90)
t2.forward(50)
t2.left(90)
t3.forward(50)
t3.left(90)
screen.mainloop()
解説
t.write()
は、現在のタートルの位置にテキストを表示します。t.penup()
とt.pendown()
は、ペンを上げたり下ろしたりして、移動中に線を描くかどうかを制御します。- 同じ描画コマンドを各タートルに実行させることで、それぞれの速度の違いが視覚的に確認できます。
t1.speed(1)
、t2.speed("normal")
、t3.speed(10)
と、それぞれ異なる速度を設定しています。- 3つの異なるタートルオブジェクトを作成し、それぞれに異なる色と開始位置を設定しています。
非常に複雑な図形や多数の描画コマンドを実行する場合、speed(0)
だけでは不十分なことがあります。そのような場合に最も効果的なのがscreen.tracer(0)
とscreen.update()
の組み合わせです。
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
t.hideturtle() # タートル(矢印)を非表示にする
# アニメーションなし (0) での描画 (それでも数が多いと遅延が起こる)
print("速度0で螺旋を描画 (アニメーションはオフだが更新は行われる)")
t.speed(0) # アニメーションはオフだが、画面の更新はステップごとに行われる
t.penup()
t.goto(-200, 0)
t.pendown()
for i in range(200):
t.forward(i)
t.left(91)
t.clear() # 描画をクリア
# tracer(0) と update() を使った超高速描画
print("tracer(0)とupdate()で高速描画")
screen.tracer(0) # アニメーション更新を完全にオフにする
t.penup()
t.goto(100, 0)
t.pendown()
for i in range(200):
t.forward(i)
t.left(91)
screen.update() # 全ての描画を一度に画面に反映
screen.mainloop()
t.clear()
: タートルの描画を全て消去します。- screen.update()
screen.tracer(0)
で更新を停止した後、全ての描画が完了した後にscreen.update()
を呼び出すことで、それまでに行われた全ての変更が一度に画面に描画されます。これにより、アニメーションなしで非常に高速な描画が可能になります。 - screen.tracer(0)
これがポイントです。screen.tracer(0)
を呼び出すと、タートルグラフィックスの画面更新が完全に停止します。これにより、全ての描画コマンドがメモリ上で高速に実行されます。 - t.speed(0)の限界
最初の螺旋ではt.speed(0)
を使用していますが、それでもタートルの内部的な描画ステップごとの画面更新は行われるため、描画コマンドの数が多いと遅延が発生する可能性があります。 t.hideturtle()
: タートル(矢印)自体を非表示にすることで、描画の邪魔にならないようにします。
screen.tracer()とscreen.update()
これは、turtle.speed(0)
(アニメーションなし)よりもさらに高速な描画を可能にする最も強力な方法です。特に複雑な図形や多数の描画コマンドを実行する場合に非常に有効です。
screen.update()
:screen.tracer(0)
で画面の自動更新をオフにした後、このメソッドを呼び出すと、それまでに行われた全ての描画が一度に画面に表示されます。
screen.tracer(n=None, delay=None)
:n
: 画面の更新頻度を設定します。0
を指定すると、画面の自動更新が完全にオフになります。これが最も重要です。1
がデフォルトで、各ステップごとに画面を更新します。N
(1より大きい整数) を指定すると、Nステップごとに画面を更新します。
delay
: 各更新間の遅延時間(ミリ秒)を設定します。デフォルトは0
です。
使用例
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
t.hideturtle() # タートル(矢印)を非表示にする
# 描画を完全に停止し、高速化する
screen.tracer(0)
# 大量の描画コマンドを実行
for i in range(360):
t.forward(i)
t.left(91)
# 全ての描画を一度に表示
screen.update()
screen.mainloop()
利点
- プログラムの高速化
大量の描画ステップがある場合に、処理時間を大幅に短縮できます。 - 最速の描画
アニメーションを完全にスキップするため、非常に複雑な図形も瞬時に描画できます。
欠点
- 描画プロセスのアニメーションを見ることができません。デモンストレーション目的でタートルの動きを見せたい場合には不向きです。
screen.delay()
これはturtle.speed()
とは異なるレベルでアニメーションの遅延を制御します。turtle.speed()
は「ステップごとのアニメーションの速さ」を調整するのに対し、screen.delay()
は「各タートル操作間のミリ秒単位の遅延」を設定します。
screen.delay(delay=None)
:delay
(ミリ秒): 各タートル操作(移動や回転など)の間に挿入される遅延時間を設定します。- デフォルトは
10
ミリ秒です。 0
に設定すると、この遅延はなくなります。
使用例
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
print("デフォルトの遅延 (10ms) + Speed 6")
t.speed(6) # デフォルト速度
t.forward(100)
t.left(90)
print("遅延なし (0ms) + Speed 6")
screen.delay(0) # 遅延をなくす
t.forward(100)
t.left(90)
# delay を元に戻すことも可能
screen.delay(10)
print("遅延を元に戻す (10ms) + Speed 6")
t.forward(100)
t.left(90)
screen.mainloop()
利点
delay(0)
は、speed()
が0
でない場合でも描画を速くするのに役立ちます。speed()
と組み合わせて、アニメーションの「滑らかさ」を微調整できます。
欠点
speed(0)
やtracer(0)
ほど劇的な高速化は期待できません。あくまでアニメーションの「間」を調整するものです。
これは直接的な速度制御ではありませんが、描画のパフォーマンスに影響を与える可能性があります。undo
機能のためにタートルの動きを記録するバッファのサイズを設定します。
turtle.setundobuffer(size)
:size
: アンドゥバッファの最大サイズ。None
または0
を設定すると、アンドゥバッファが無効になり、わずかながらメモリ使用量を減らし、非常に長い描画シーケンスでのパフォーマンスに影響を与える可能性があります。
使用例
import turtle
t = turtle.Turtle()
# アンドゥバッファを無効にする (描画が非常に長い場合にわずかに高速化する可能性)
t.setundobuffer(0)
# 通常通り描画
for _ in range(100):
t.forward(10)
t.left(10)
turtle.done()
利点
- 非常に長い描画シーケンスで、アンドゥ機能が不要な場合に、ごくわずかなパフォーマンス改善が期待できるかもしれません。
欠点
- 通常の使用では、体感できるほどの速度改善にはつながりません。
- アンドゥ機能が使えなくなります。
turtle.speed()
はタートルの「アニメーション速度」を設定する基本的な方法です。それに対して、
turtle.setundobuffer(0)
: 特殊なケースで、アンドゥ機能が不要な場合にわずかなパフォーマンス改善が期待できるかもしれません。screen.delay(0)
: アニメーションの「間」の遅延をなくし、speed()
と組み合わせてアニメーションを少し速く見せたい場合に有効です。screen.tracer(0)
とscreen.update()
: アニメーションを完全にスキップし、超高速で最終結果を表示したい場合に最適な方法です。ほとんどの場合、これが最も望ましい高速化手段となります。