Python Turtle: setx()でタートルを自在に操る!基本から応用まで徹底解説
Pythonのturtle
モジュールにおけるturtle.setx()
は、タートル(描画を行うカーソルのようなもの)のx座標を設定するための関数です。
詳しく説明すると以下のようになります。
-
タートルグラフィックスとは?
turtle
モジュールは、仮想的な「タートル」と呼ばれるお絵描きロボットを画面上で動かすことで、図形を描画できるモジュールです。このタートルは、ペンを持っており、移動するとその軌跡が線として描かれます。 -
座標系 タートルの画面は、デカルト座標系(xy平面)で表されます。
- 中心が(0,0)
- 右方向が正のx軸
- 上方向が正のy軸
-
turtle.setx(x)
の機能turtle.setx(x)
関数は、タートルの現在のy座標は変更せずに、x座標だけを指定したx
の値に設定します。タートルは新しいx座標の位置へ移動します。もしペンが下がった状態(pendown()
の状態)であれば、元の位置から新しいx座標までの線が描画されます。ペンが上がった状態(penup()
の状態)であれば、線は描画されずにタートルが移動するだけです。 -
使用例
import turtle # タートルを作成 t = turtle.Turtle() # タートルを初期位置から少し移動 t.forward(50) # x=50, y=0 の位置へ移動 # x座標を -100 に設定(y座標は変わらず0のまま) t.setx(-100) # (50, 0) から (-100, 0) へ移動し、線が描かれる # x座標を 200 に設定(y座標は変わらず0のまま) t.setx(200) # (-100, 0) から (200, 0) へ移動し、線が描かれる turtle.done() # ウィンドウがすぐに閉じないようにする
このコードを実行すると、タートルが最初にx=50の位置へ移動し、次にx=-100の位置へ移動し、最後にx=200の位置へ移動する様子が、線として描画されます。y座標は常に0のままです。
AttributeError: 'module' object has no attribute 'setx' または AttributeError: 'Turtle' object has no attribute 'setx'
原因
- タートルオブジェクトを正しく作成・参照していない
turtle.Turtle()
でタートルオブジェクトを作成したものの、それを変数に格納していなかったり、間違った変数名で参照しようとしていたりする場合です。 - モジュール名を間違えている
turtle.setx()
を使おうとしているのに、turtle
モジュールそのもの(例えばimport turtle
した後)に対して直接呼び出そうとしている。setx()
は、turtle.Turtle()
で作成したタートルオブジェクトのメソッドです。
よくある間違いの例
import turtle
# 間違い1: モジュールに対してsetxを呼び出そうとしている
# turtle.setx(100) # これだとエラー
# 間違い2: タートルオブジェクトを作成していないか、参照ミス
# t.setx(100) # tが定義されていないとエラー
解決策
必ずturtle.Turtle()
でタートルオブジェクトを作成し、そのオブジェクトのメソッドとしてsetx()
を呼び出します。
import turtle
t = turtle.Turtle() # タートルオブジェクトを作成
t.setx(100) # 正しい呼び出し方
# または、手続き型プログラミングの場合
turtle.setx(100) # この場合、デフォルトのタートルオブジェクトが使用されます
TypeError: setx() missing 1 required positional argument: 'x'
原因
setx()
関数に引数(x座標の値)を渡していない場合に発生します。setx()
は、移動先のx座標を引数として必要とします。
よくある間違いの例
import turtle
t = turtle.Turtle()
# 間違い: 引数がない
# t.setx() # これだとエラー
解決策
数値(整数または浮動小数点数)を引数として渡します。
import turtle
t = turtle.Turtle()
t.setx(50) # 整数
t.setx(-20.5) # 浮動小数点数
TypeError: setx() takes exactly one argument (2 given) など
原因
setx()
関数に複数の引数を渡している場合に発生します。setx()
はx座標のみを設定するため、引数は1つだけです。xとy座標を同時に設定したい場合は、turtle.goto(x, y)
やturtle.setposition(x, y)
を使用します。
よくある間違いの例
import turtle
t = turtle.Turtle()
# 間違い: xとyの両方を渡している
# t.setx(100, 50) # これだとエラー
解決策
setx()
にはx座標だけを渡します。xとyを同時に移動させたい場合はgoto()
を使います。
import turtle
t = turtle.Turtle()
t.setx(100) # 正しい
# xとyを同時に設定したい場合
t.goto(100, 50)
-
座標が画面外になっている
設定しようとしているx座標がタートルウィンドウの描画範囲外である場合、タートルは動いても画面上には見えません。解決策
turtle.screensize()
やturtle.setup()
を使ってウィンドウサイズを調整したり、より小さいx座標で試したりします。import turtle screen = turtle.Screen() screen.setup(width=600, height=400) # ウィンドウサイズを設定 t = turtle.Turtle() t.setx(250) # 画面の端に近い位置 turtle.done()
-
ペンが上がっている (penup())
penup()
が呼び出されている場合、タートルが移動しても線は描画されません。解決策
線を描画したい場合は、pendown()
を呼び出します。import turtle t = turtle.Turtle() t.penup() # ペンを上げる t.setx(50) # 線は描かれない t.pendown() # ペンを下げる t.setx(100) # 線が描かれる turtle.done()
-
タートルの速度が速すぎる(または遅すぎる)
タートルの動きが速すぎて、描画が瞬間的に終わってしまうことがあります。逆に、非常に遅い設定になっていると、動いていないように見えることもあります。解決策
turtle.speed()
を使って速度を調整します。t.speed(0)
またはt.speed('fastest')
: 可能な限り最速t.speed(1)
またはt.speed('slowest')
: 最も遅いt.speed(6)
(デフォルト): 中間
import turtle t = turtle.Turtle() t.speed(1) # 遅めに設定して動きを確認 t.setx(100) turtle.done()
-
turtle.done() または turtle.exitonclick() を呼び出していない
スクリプトが終了するとすぐにタートルウィンドウが閉じてしまうため、タートルの動きや描画を確認できません。解決策
スクリプトの最後にturtle.done()
(またはturtle.exitonclick()
)を追加して、ウィンドウが開いたままになるようにします。import turtle t = turtle.Turtle() t.setx(100) turtle.done() # ウィンドウを閉じずに待機
例1: 基本的な setx()
の使い方
これは最も基本的な例で、タートルのx座標だけを動かす様子を示します。
import turtle
# 1. スクリーンとタートルオブジェクトの準備
screen = turtle.Screen()
screen.setup(width=600, height=400) # ウィンドウサイズを設定
screen.bgcolor("lightgray") # 背景色を設定
t = turtle.Turtle()
t.shape("turtle") # タートルの形をカメにする
t.color("blue") # タートルの色を青にする
t.speed(1) # 描画速度をゆっくりにする (0=最速)
# 2. 初期位置 (中心: 0, 0)
t.penup() # ペンを上げる
t.goto(0, 0) # 中心に移動
t.pendown() # ペンを下げる
# 3. x座標を正の方向に設定
t.setx(150) # 現在のy座標(0)は変えずに、x座標を150に設定
# (0, 0) から (150, 0) へ線が描かれる
# 4. x座標を負の方向に設定
t.setx(-100) # 現在のy座標(0)は変えずに、x座標を-100に設定
# (150, 0) から (-100, 0) へ線が描かれる
# 5. x座標をさらに正の方向に設定
t.setx(50) # 現在のy座標(0)は変えずに、x座標を50に設定
# (-100, 0) から (50, 0) へ線が描かれる
# 6. プログラム終了までウィンドウを開いたままにする
turtle.done()
説明
- 同様に、
-100
や50
へとx座標が変更され、それぞれの位置へタートルが移動します。 t.setx(150)
は、タートルを現在のy座標を保ったまま、x座標が150の位置に移動させます。ペンが下がっているので線が描かれます。t.speed(1)
は、描画がゆっくり進むように設定し、動きを確認しやすくします。
例2: setx()
と sety()
を組み合わせて四角形を描く
setx()
と sety()
を交互に使うことで、特定の座標に沿って四角形を描くことができます。
import turtle
screen = turtle.Screen()
screen.setup(width=400, height=400)
screen.bgcolor("lightblue")
t = turtle.Turtle()
t.shape("arrow")
t.color("red")
t.pensize(3) # ペンの太さ
t.speed(3) # 描画速度
# 四角形の頂点座標
# (100, 100)
# (100, -100)
# (-100, -100)
# (-100, 100)
# 初期位置に移動 (左上から開始)
t.penup()
t.goto(-100, 100)
t.pendown()
# 1. 右へ移動 (x座標のみ変更)
t.setx(100) # (-100, 100) から (100, 100) へ
# 2. 下へ移動 (y座標のみ変更)
t.sety(-100) # (100, 100) から (100, -100) へ
# 3. 左へ移動 (x座標のみ変更)
t.setx(-100) # (100, -100) から (-100, -100) へ
# 4. 上へ移動 (y座標のみ変更)
t.sety(100) # (-100, -100) から (-100, 100) へ (開始地点に戻る)
turtle.done()
説明
- これらを組み合わせることで、直角に曲がる動きを簡単に表現できます。
t.setx()
は水平方向の移動に、t.sety()
は垂直方向の移動に使用されます。
例3: for
ループと setx()
を使って平行線を引く
setx()
をループの中で使うことで、簡単に繰り返し動作を行うことができます。ここでは、異なるy座標で水平な平行線を引きます。
import turtle
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("white")
t = turtle.Turtle()
t.shape("classic")
t.color("darkgreen")
t.pensize(2)
t.speed(0) # 最速
start_x = -250 # 線の開始x座標
end_x = 250 # 線の終了x座標
# y座標を変化させながら線を引く
for y_pos in range(-150, 151, 50): # y_pos が -150, -100, ..., 150 と変化
t.penup()
t.goto(start_x, y_pos) # 各y_posの開始点に移動
t.pendown()
t.setx(end_x) # 現在のy_posを保ったまま、xをend_xに設定
turtle.done()
説明
t.speed(0)
は最速に設定されており、描画が瞬時に行われます。- ループの各イテレーションで、タートルは
goto()
で新しいy座標の開始点に移動し、setx()
で水平線を引きます。 range(-150, 151, 50)
は、-150から150まで50刻みでy座標を生成します。
ユーザーの操作に応じてタートルを動かすインタラクティブな例です。
import turtle
screen = turtle.Screen()
screen.setup(width=600, height=400)
screen.bgcolor("gold")
t = turtle.Turtle()
t.shape("circle")
t.color("purple")
t.penup() # クリックで移動するだけなのでペンは常に上げておく
t.speed(0)
# クリックされたx座標にタートルを移動させる関数
def move_to_clicked_x(x, y):
"""
スクリーンがクリックされた際に呼び出され、
クリックされた点のx座標にタートルを移動させます。
y座標は変更しません。
"""
print(f"クリックされました: x={x}, y={y}")
t.setx(x) # クリックされたx座標にタートルを移動
# スクリーンのクリックイベントに上記の関数を紐づける
screen.onclick(move_to_clicked_x)
# イベントループを開始(ウィンドウを閉じるまで待機)
screen.mainloop()
screen.mainloop()
は、turtle.done()
と同様にウィンドウを維持しますが、イベント処理ループを開始します。- 関数内で
t.setx(x)
を呼び出すことで、タートルはクリックされた位置のx座標に瞬時に移動します。y座標は元の位置のままです。 move_to_clicked_x
関数は、クリックされた点のx座標とy座標を引数として受け取ります。screen.onclick(move_to_clicked_x)
は、スクリーンがクリックされたときにmove_to_clicked_x
関数を呼び出すように設定します。
turtle.goto(x, y) または turtle.setposition(x, y)
これは、turtle.setx()
の最も直接的な代替手段であり、より柔軟です。
- 利点
任意の点に直接移動できるため、setx()
とsety()
を個別に呼び出すよりもコードが簡潔になることが多いです。 - setx()との比較
setx()
はy座標を保持しますが、goto()
/setposition()
はy座標も明示的に指定する必要があります。 - 機能
タートルのx座標とy座標の両方を、指定された(x, y)
の位置に設定します。
例
import turtle
t = turtle.Turtle()
t.speed(1)
t.penup()
t.goto(0, 0) # 初期位置
t.pendown()
# setx(100) の代わりに goto(100, t.ycor()) を使う
# t.ycor() は現在のタートルのy座標を返す
t.goto(100, t.ycor()) # x座標を100に、y座標は現在の値のまま
# setx(-50) の代わりに goto(-50, t.ycor()) を使う
t.goto(-50, t.ycor())
turtle.done()
turtle.setheading(angle) と turtle.forward(distance)
この方法は、タートルを特定の方向に向けてから移動させることで、間接的にx座標を変更します。
- 利点
直線的な動きだけでなく、任意の角度への移動を表現するのに適しています。描画パスをより制御したい場合に有用です。 - setx()との比較
setx()
が絶対座標を指定するのに対し、この方法は相対的な移動です。タートルの向きを調整し、その向きに移動することで、結果的にx座標が変化します。y座標も変化する可能性があります。 - 機能
setheading(angle)
: タートルの向きを角度(0度が東、90度が北)で設定します。forward(distance)
: 現在の向きにdistance
だけ移動します。
例
import turtle
t = turtle.Turtle()
t.speed(1)
t.penup()
t.goto(0, 0)
t.pendown()
# x座標を100に移動する(東に100歩進む)
t.setheading(0) # 東(右)を向く
t.forward(100) # 100歩進む -> x=100, y=0 になる
# x座標を-50に移動する(西に150歩進む)
# 現在の位置は (100, 0) なので、-50にするには左に150歩進む
t.setheading(180) # 西(左)を向く
t.forward(150) # 150歩進む -> x=-50, y=0 になる
turtle.done()
turtle.left(angle) / turtle.right(angle) と turtle.forward(distance)
これは上記の2番目の方法と似ていますが、相対的な角度変更を使用します。
- 利点
複雑な図形やパターンを描画する際に、相対的な回転と移動の組み合わせが非常に強力です。 - setx()との比較
setx()
が絶対座標を指定するのに対し、この方法は現在のタートルの向きからの相対的な回転と移動を組み合わせます。 - 機能
left(angle)
: 現在の向きから左にangle
度回転します。right(angle)
: 現在の向きから右にangle
度回転します。forward(distance)
: 回転後の向きにdistance
だけ移動します。
例
import turtle
t = turtle.Turtle()
t.speed(1)
t.penup()
t.goto(-100, 0) # 初期位置を少し左に設定
t.pendown()
# x座標を0に移動する(右に100歩進む)
t.forward(100) # x=-100 から x=0 へ
# その場で左に90度回転し、y座標を100にする(上に100歩進む)
t.left(90)
t.forward(100) # x=0 から y=100 へ
# その場で左に90度回転し、x座標を-100にする(左に100歩進む)
t.left(90)
t.forward(100) # x=0, y=100 から x=-100, y=100 へ
turtle.done()
turtle.goto(x, y)
と全く同じ機能を持つエイリアス(別名)です。
- 機能
goto()
と全く同じで、x座標とy座標を同時に設定します。
import turtle
t = turtle.Turtle()
t.speed(1)
t.penup()
t.setpos(0, 0) # goto(0,0) と同じ
t.pendown()
t.setpos(100, t.ycor()) # setx(100) と同じ効果
turtle.done()
- turtle.left(angle) / turtle.right(angle) と turtle.forward(distance)
現在の向きからの相対的な回転と移動を組み合わせてX座標(およびY座標)を変更したい場合に、複雑な描画パターンに非常に有用です。 - turtle.setheading(angle) と turtle.forward(distance)
特定の向きに直線的に移動することでX座標を変更したい場合に、より細かい方向制御が可能です。Y座標も変化します。 - turtle.turtle.goto(x, y) / turtle.setposition(x, y) / turtle.setpos(x, y)
XとYの両方を絶対的に設定したい場合に最も一般的で柔軟です。 - turtle.setx(x)
Y座標を保持しつつ、X座標だけを絶対的に設定したい場合に最適です。