タートルグラフィックスで学ぶ Python のキホン 第 11 章
教材コード
第 11 章

文字と図形で表現する

線を引くだけが絵ではありません.文字・姿・足跡・塗りで,作品に仕上げます.

ここまで,かめは線を引く道具でした.今回はそれ以外の表現手段を覚えます. 画面に文字を書く,かめの姿を変える, その場に足跡(スタンプ)を押す,図形の内側を塗る. 命令はどれも 1 行で書けるものばかりですが,組み合わせると 「プログラムの出力」ではなく「作品」に見えてきます.

とくに大事なのが write です. 第 12 章でゲームを作るとき,スコアや残り時間を画面に出すのに必ず使います. 数が変わるたびに書き換える方法まで,ここで押さえておきましょう.

この章でできるようになること
  • write で画面に文字を書き,大きさ・書体・そろえ方を指定できる
  • f-string で数と文字をつなげて表示できる
  • clear() して書き直すことで,スコア表示を更新できる
  • shapeshapesizecolor でかめの見た目を変えられる
  • stampdotbegin_fill で図形を「置く」「塗る」ことができる
  • 姿を順番に切り替えて,ぱらぱら漫画のようなアニメーションが作れる
前の章とのつながり 前の章(第 10 章)は ontimer動かすことを覚えました. 今回は見せることがテーマです. 最後の節で 2 つを合わせて,「動いて,数字が増えていく画面」を作ります. 前の章と同じく def step():global が出てきますが, まだ決まり文句のままで大丈夫です. 仕組みは第 13 章・第 14 章でしっかり習います.

11.1 画面に文字を書く — write

11.1.1 write の基本

write("文字") と書くと,かめが今いる場所に文字が書かれます. ペンが上がっていても下がっていても関係なく書かれますし,かめは動きません.

write1.py
from turtle import *

ht()                    # かめの姿は消しておく

write("こんにちは")

pu()
goto(0, -40)
write("Hello, turtle!")

done()
こんにちはHello, turtle!
図 11.1 write は「今いる場所」に文字を書く.かめは動かないので,次の行を書くには自分で移動する.
ヒント 文字は書いた場所から右へ,上に向かって伸びます. かめの位置が文字の左下だと思ってください. だから 2 行目を書くときは,gotoy を下げてから書きます.

11.1.2 大きさと書体を変える — font

既定の文字はとても小さいので,実際にはほとんどいつも font= を付けて使います.書き方は決まっていて, (書体の名前,大きさ,太さ)の 3 つを丸かっこで並べます.

font の書き方
write("スコア", font=("Arial", 20, "bold"))
#                 ~~~~~~~  ~~  ~~~~~~
#                 書体     大きさ  太さ
書く場所書けるもの説明
書体"Arial" "Times" "Courier" "Georgia" など文字の形.日本語はどの指定でも表示できる書体に置き換わる
大きさ8 16 24 40数が大きいほど大きい文字になる.画面いっぱいなら 40〜60 くらい
太さ"normal" "bold" "italic"bold は太字,italic は斜体
write2.py
from turtle import *

ht()
pu()

goto(-240, 60)
write("normal 28", font=("Arial", 28, "normal"))

goto(-240, 10)
write("bold 28", font=("Arial", 28, "bold"))

goto(-240, -40)
pencolor("crimson")
write("bold 44", font=("Arial", 44, "bold"))

done()
normal 28bold 28bold 44
図 11.2 大きさ・太さ・色を変えた文字.色は pencolor で決まる.
文字の色はペンの色 文字の色は write では指定しません. そのときのペンの色(pencolorで書かれます. 色を変えたいときは,writepencolor("crimson") のように書いてください.

11.1.3 位置をそろえる — align

align= を付けると,かめの位置に対して文字をどうそろえるかを指定できます. "left"(既定・かめの右へ伸びる),"center"(かめを中心に左右へ), "right"(かめの左へ伸びる)の 3 つです.

align.py
from turtle import *

ht()
pensize(2)
pencolor("#c0c6d0")

# 目印の枠と中心線を引く
pu()
goto(-200, -90)
pd()
goto(200, -90)
goto(200, 120)
goto(-200, 120)
goto(-200, -90)
pu()
goto(0, 120)
pd()
goto(0, -90)

pencolor("black")
pu()

goto(0, 70)
write("left", align="left", font=("Arial", 26, "normal"))

goto(0, 10)
write("center", align="center", font=("Arial", 26, "normal"))

goto(0, -50)
write("right", align="right", font=("Arial", 26, "normal"))

done()
leftcenterright
図 11.3 同じ x にいても align で見え方が変わる.得点を右そろえにすると,桁が増えても数字の右端がずれない.
使い分けの目安 題名は "center",得点や残り時間は "right" が定番です. 左そろえのまま数を表示すると,910100 と 桁が増えるたびに文字がにじり出て,見ていて落ち着きません.

11.1.4 数と文字をつなげる — f-string

表示したいのはたいてい「スコア」ではなく 「スコア: 120」のように,文字と変数の組み合わせです. Python では文字列の前に f を付け, 変数を { } でくくって埋め込みます.これを f-string(エフ文字列)といいます.

f-string の書き方
score = 120

write(f"スコア: {score}")          #  スコア: 120
write(f"あと {60 - 15} 秒")        #  あと 45 秒       (計算も書ける)
write(f"{score} 点 / {200} 点満点")  #  120 点 / 200 点満点
f-string のつまずきどころ
  • 先頭の f を書き忘れると,{score} がそのまま文字として出ます.出力がおかしいときはまずここを疑ってください.
  • { } の中に書くのは変数か式です.{"score"} のようにクォートで囲むと,ただの文字になってしまいます.
  • write("スコア: " + score)エラーになります.文字と数はそのままではつなげません(str(score) が要ります).f-string ならその手間が要りません.
fstring.py
from turtle import *

ht()
pu()

name = "たろう"
score = 1280
stage = 3

# 目印の枠
goto(-270, -100)
pd()
pensize(2)
pencolor("#c0c6d0")
goto(270, -100)
goto(270, 120)
goto(-270, 120)
goto(-270, -100)
pu()
pencolor("black")

goto(-250, 60)
write(f"プレイヤー: {name}", font=("Arial", 26, "normal"))

goto(-250, 0)
pencolor("crimson")
write(f"スコア: {score}", font=("Arial", 34, "bold"))

goto(-250, -60)
pencolor("navy")
write(f"ステージ {stage} / 全 8 面", font=("Arial", 22, "normal"))

done()
プレイヤー: たろうスコア: 1280ステージ 3 / 全 8 面
図 11.4 変数の中身が文字の中に埋め込まれる.score の値を変えれば表示も変わる.
虫食い虫食い 11-A 名札を作る

名前と学年を画面の中央にそろえて表示します. ____ を埋めてください. 中央ぞろえにするのは align,太字の 40 ポイントにするのは font,変数を埋め込むのは f-string でしたね.

fill9_nametag.py
from turtle import *

ht()
pu()

name = "おのみち はなこ"
grade = 1

goto(0, 20)
pencolor("navy")
write(name, align="____", font=("Arial", ____, "bold"))

goto(0, -40)
pencolor("dimgray")
write(f"情報工学科 {____} 年", align="center", font=("Arial", 22, "normal"))

done()

11.2 書いた文字を書き換える

ここが今回いちばん大事なところです. write で書いた文字は絵の具のように画面に焼き付きます. 同じ場所にもう一度書いても,前の文字は消えません.重なって読めなくなるだけです.

overlap.py
from turtle import *

ht()
pu()
goto(-120, 0)

write("スコア: 0", font=("Arial", 36, "bold"))
write("スコア: 120", font=("Arial", 36, "bold"))    # 上に重なるだけ

done()
スコア: 0スコア: 120
図 11.5 同じ場所に 2 回書いた結果.前の文字は消えない.

11.2.1 clear() して書き直す

文字だけを消す命令はありません.そこで clear() で画面をまるごと消してから,もう一度書く という方法をとります.テレビの画面を毎回描き直すのと同じ考え方です.

rewrite.py
from turtle import *

ht()
pu()

# 1 回目の表示
goto(-120, 0)
write("スコア: 0", font=("Arial", 36, "bold"))

# いったん全部消す
clear()

# 2 回目の表示
goto(-120, 0)
pencolor("crimson")
write("スコア: 120", font=("Arial", 36, "bold"))

done()
スコア: 120
図 11.6 clear() をはさむと,最後に書いたものだけが残る.
clear() は文字だけを消すのではない clear()それまでに描いた線も全部消します. 背景の絵まで消えてしまうので,「消して書き直す」やり方をとるときは, 1 コマぶんの絵を毎回まるごと描き直すと決めてしまうのが確実です. 次の節のプログラムがその形になっています.

11.2.2 増えていくスコアを表示する

前の章の ontimer と組み合わせます. 「消す → 数を計算する → 書く」を 0.5 秒ごとに繰り返すと, 数字が増えていく表示になります.これをカウンターといいます.

counter.py
from turtle import *

ht()
score = 0

def step():
    global score

    clear()                 # 前のコマを消す

    pu()
    goto(0, 20)
    pencolor("navy")
    write(f"スコア: {score}", align="center", font=("Arial", 40, "bold"))

    goto(0, -50)
    pencolor("dimgray")
    write("0.5 秒ごとに 10 点ずつ増えます", align="center",
          font=("Arial", 18, "normal"))

    score = score + 10      # 次のコマの準備
    ontimer(step, 500)      # 0.5 秒後にもう一度 step を呼ぶ

step()
done()
global を忘れずに global score は,「この関数の中で使う score は, 関数の外にあるあの score のことだ」という宣言です. これを書かないと,関数の中だけで通用する別の変数ができてしまい, 数がいつまでも増えません.関数の中で外の変数を書き換えるときに必要です. 第 10 章と同じ決まり文句です. 「書き換える外の変数は 1 行目に global で並べる」とだけ覚えておけば, 今回は困りません(仕組みは第 13 章で習います).

やってみようontimer(step, 500) の 500 を 100 にすると どうなるでしょうか.score + 10score + 1 にしたら? clear() の行を # でコメントにすると,何が起きるでしょうか.

虫食い虫食い 11-B カウントダウン

10 から 1 ずつ減っていくカウントダウンを作ります. ____ を埋めてください. 毎コマ消すことと,外の変数を書き換える宣言を 忘れないでください.

ヒント 0 になったら「ぼかーん!!」と出して止めます. 止めるには,ontimer呼ばなければよいだけです.
fill9_countdown.py
from turtle import *

ht()
rest = 10

def step():
    ____ rest

    ____()                 # 前のコマを消す

    pu()
    goto(0, 0)
    if rest > 0:
        pencolor("navy")
        write(f"あと {____}", align="center", font=("Arial", 60, "bold"))
        rest = rest - 1
        ontimer(step, ____)     # 1 秒後
    else:
        pencolor("crimson")
        write("ぼかーん!!", align="center", font=("Arial", 60, "bold"))

step()
done()

11.3 かめの見た目を変える — shape

11.3.1 姿を選ぶ

shape("名前") で,かめの姿を選べます.使える姿は次の 6 つです.

図 11.7 "classic"(最初の姿)
図 11.8 "turtle"
図 11.9 "arrow"
図 11.10 "circle"
図 11.11 "square"
図 11.12 "triangle"
ヒント このほかに shape("blank") があります.姿が何も描かれなくなるので, ht() と似た働きをします(ただし stamp も押せなくなります).

11.3.2 大きさを変える — shapesize

shapesize(縦, 横) で姿を拡大・縮小します. は進む向きへの伸び,は左右への広がりです. shapesize(3) のように 1 つだけ書くと,縦横とも同じ倍率になります.

shapesize.py
from turtle import *

shape("turtle")
color("seagreen")

pu()
goto(-180, 0)
shapesize(1)
stamp()          # 等倍

goto(-60, 0)
shapesize(2)
stamp()          # 2 倍

goto(80, 0)
shapesize(3)
stamp()          # 3 倍

goto(220, 0)
shapesize(1, 4)  # 縦 1 倍・横 4 倍(平たいかめ)
stamp()

ht()
done()
図 11.13 shapesize で大きさが変わる.いちばん右は縦横の倍率を別々にしたもの.

11.3.3 姿の色 — color / fillcolor / pencolor

姿の色は 2 つに分かれています.内側の色fillcolorふちの色pencolor です. color("赤") と 1 つだけ書くと両方が, color("赤", "白") と 2 つ書くとふち・内側の順に決まります.

shapecolor.py
from turtle import *

shape("circle")
shapesize(3)

pu()
goto(-160, 0)
color("crimson")            # ふちも内側も赤
stamp()

goto(0, 0)
color("crimson", "white")   # ふちは赤・内側は白
stamp()

goto(160, 0)
color("navy", "gold")       # ふちは紺・内側は金
stamp()

ht()
done()
図 11.14 color の引数が 1 つのときと 2 つのときの違い.
注意 colorペンの色も一緒に変えます. 姿だけ赤くしたつもりが線まで赤くなった,というのはよくある勘違いです. 線の色を変えたくないときは fillcolor("red") を使ってください.
虫食い虫食い 11-C 信号機

3 つの丸を横に並べて信号機を作ります. ____ を埋めてください. 丸の姿は "circle",大きさは shapesize, 置くのは stamp() でしたね.

fill9_signal.py
from turtle import *

bgcolor("#222831")
shape("____")
shapesize(____)

pu()

goto(-110, 0)
color("____")        # 赤
stamp()

goto(0, 0)
color("gold")
____()

goto(110, 0)
color("limegreen")
stamp()

ht()
done()

11.4 足跡を残す — stamp

11.4.1 stamp でその場に姿を押す

stamp() は,今の姿・今の色・今の大きさ・今の向きのまま, その場にはんこを押します.かめ自身は動きません. 線を引かずに形を並べるときにとても便利です.

stamp.py
from turtle import *

shape("turtle")
color("seagreen")
shapesize(1.5)
pu()                    # 線は引かない

goto(-220, -60)

for i in range(8):
    stamp()             # その場に足跡を残す
    fd(56)
    lt(12)              # 少しずつ向きを変える

ht()
done()
図 11.15 pu() で線を消し,stamp だけを並べた.向きも一緒に記録されるので,弧を描いて進む様子が残る.
押したはんこを消す stamp() は押したはんこの番号を返します. sid = stamp() と受け取っておけば, clearstamp(sid) でそのはんこ 1 つだけを消せます. 全部まとめて消すなら clearstamps() です.

11.4.2 clearstamps で消す

clearstamps()はんこだけを消します. clear() と違って,線や文字は残ります. 動くものは stamp,動かない背景は線で描く,と分けておくと, 毎コマ「はんこだけ消して押し直す」ことができます.

stampmove.py
from turtle import *

# --- 動かない背景(1 回だけ描く)---
pencolor("#c0c6d0")
pensize(3)
pu()
goto(-260, -120)
pd()
goto(260, -120)
pu()

# --- 動く星 ---
star = Turtle()
star.shape("triangle")
star.color("gold")
star.shapesize(2)
star.pu()
star.ht()
star.goto(-240, -80)

def step():
    star.clearstamps()      # 前の足跡だけ消す(線は残る)
    star.fd(12)
    star.lt(3)
    if star.xcor() > 260:
        star.goto(-240, -80)
        star.seth(0)
    star.stamp()
    ontimer(step, 60)

step()
done()

11.4.3 姿を切り替えて「ぱらぱら漫画」にする

なぜ画像を使わないのか もとの教材では,8 枚の絵(man1.gif …… man8.gif)を 順番に切り替えて,人が歩くぱらぱら漫画を作っていました. この教材のランタイムは画像ファイルを表示できませんので, かわりにかめの姿・大きさ・色を順番に切り替えることで同じことをします. こうしておけば,画像ファイルを配る必要がなく,どの環境でもそのまま動きます. 「何コマかを用意して,順番に見せる」という考え方そのものは同じです.

コマの切り替えには,第 7 章で習った余り(%を使います. i % 40, 1, 2, 3, 0, 1, 2, 3, … を繰り返すので, 「4 コマぶんの姿」をぐるぐる回せます.

flipbook.py
from turtle import *

ht()
bgcolor("#f6f7fb")
i = 0

man = Turtle()
man.pu()
man.goto(0, 0)
man.color("seagreen")

def step():
    global i

    # --- 1 コマの処理:i に応じて姿を変える ---
    if i % 4 == 0:
        man.shape("turtle")
        man.shapesize(2, 2)
    elif i % 4 == 1:
        man.shape("turtle")
        man.shapesize(2.6, 1.6)
    elif i % 4 == 2:
        man.shape("triangle")
        man.shapesize(2.2, 2.2)
    else:
        man.shape("triangle")
        man.shapesize(1.6, 2.8)

    i = i + 1
    ontimer(step, 150)

step()
done()

動いているものは本のページに載せられないので, 4 コマを止めて並べた図を見てください. うすい枠はどのコマも同じ大きさで描いてあります. このコマを 0.15 秒ずつ順番に見せると,中で何かがもぞもぞ動いて見えます.

① i % 4 が 0
② i % 4 が 1
③ i % 4 が 2
④ i % 4 が 3

1 コマずつ見るとただの図形ですが, 縦長・横長がかわるがわる現れるので, 切り替えると伸び縮みしているように見えます. ぱらぱら漫画は,1 コマだけ見ても何も分からないのが普通です.

やってみよう:コマ数を 4 から 6 に増やしてみましょう (i % 6 にして elif を足します). 色も一緒に変えると,もっと変化が出ます. ontimer の 150 を 400 にすると,動きがどう変わるでしょうか.

点滅させたいときは 点滅も同じやり方でできます. i % 2 == 0 のとき st(), そうでないとき ht() を呼べば,かめが点滅します.

11.4.4 背景を動かして「歩いている」ように見せる

ぱらぱら漫画だけだと,その場で足踏みしているように見えます. ここに背景を足しましょう. 人は画面の真ん中に置いたまま,背景のほうを左へ流すと, 人が右へ歩いているように見えます.

やり方は,11.2.1 でやった「消して書き直す」とまったく同じです. 毎コマ clear() して,少しだけずらした背景を描き直します. ずれの量を変数 sx で持ち, % を使って端まで行ったら先頭に戻すのがこつです.

scroll.py
from turtle import *

ht()
bgcolor("#eaf4ff")

i = 0            # 何コマ目か
sx = 0           # 背景のずれ

man = Turtle()
man.shape("turtle")
man.color("seagreen")
man.shapesize(2, 2)
man.pu()
man.goto(0, -40)

back = Turtle()  # 背景をかくかめ
back.ht()
back.pu()

def keshiki():
    """地面と木を,sx だけずらして描く"""
    back.pensize(3)
    back.pencolor("#9aa5b1")
    back.pu()
    back.goto(-290, -70)
    back.seth(0)
    back.pd()
    back.fd(580)
    for k in range(4):
        x = (k * 160 + sx) % 640 - 320      # ← 端まで行ったら先頭へ
        back.pu()
        back.goto(x, -70)
        back.seth(90)
        back.pencolor("#8d6e63")
        back.pd()
        back.fd(60)                          # 幹
        back.pu()
        back.dot(50, "#7cb342")              # 葉

def step():
    global i, sx

    clear()              # ① 前のコマを消す
    sx = sx - 6          # ② 背景を少し左へずらす
    keshiki()            # ③ 背景を描き直す

    if i % 2 == 0:       # ④ 人の姿を切り替える
        man.shapesize(2.0, 2.0)
    else:
        man.shapesize(2.6, 1.6)

    i = i + 1
    ontimer(step, 120)

step()
done()
① はじめのコマ
② 13 コマ後.木が左へ流れた
③ 27 コマ後.さらに流れた

人の位置は3 コマとも同じです. 動いているのは木だけなのに,人が歩いているように見えます. 横スクロールのゲームは,どれもこの仕掛けでできています.

% で輪にする (k * 160 + sx) % 640 - 320% が効かせどころです. sx をどんどん小さくしても, % 640 で 0〜639 に折り返されるので, 木は画面の左端から消えると右端から出てきます. 第 7 章で習った「あまり」が,ここで輪のような動きを作っています.
虫食い虫食い 11-D 信号が点滅する

赤・黄・緑の 3 色を順番に切り替える信号機を作ります. 3 コマを繰り返したいので,3 で割った余りを使います. ____ を埋めてください.

fill9_blink.py
from turtle import *

ht()
bgcolor("#222831")
i = 0

lamp = Turtle()
lamp.shape("circle")
lamp.shapesize(5)
lamp.pu()

def step():
    global i

    if i % ____ == 0:
        lamp.color("red")
    elif i % 3 == ____:
        lamp.color("gold")
    else:
        lamp.color("____")

    i = i + 1
    ontimer(step, 700)

____()
done()

11.5 点を打つ・内側を塗る

11.5.1 dot — 丸い点を打つ

dot(大きさ, 色) は,その場に丸い点を打ちます. stamp と違って向きは関係なく,いつでもまん丸です. 大きさは直径(ピクセル),色は省略するとペンの色になります.

dot.py
from turtle import *

ht()
pu()

goto(-200, 0)
dot(20, "crimson")

goto(-100, 0)
dot(40, "darkorange")

goto(30, 0)
dot(70, "gold")

goto(180, 0)
dot(100, "#4c9f70")     # 16 進数でも指定できる

done()
図 11.16 dot は直径と色を指定して打つ.

11.5.2 begin_fill と end_fill — 内側を塗る

図形の内側を塗るには,描き始める前に begin_fill(), 描き終わったら end_fill() と書きます. この 2 つにはさまれた部分でかめが通った道のりが,1 つの図形として塗られます. 塗る色は fillcolor(または color の 2 つめ)です.

塗りつぶしの型
fillcolor("gold")
begin_fill()
# ← ここで図形を描く
end_fill()
fillshape.py
from turtle import *

ht()
pensize(3)
pu()

# 塗った正方形
goto(-220, -70)
pd()
pencolor("navy")
fillcolor("#8ec5ff")
begin_fill()
for i in range(4):
    fd(120)
    lt(90)
end_fill()

# 塗った星
pu()
goto(20, 40)
pd()
pencolor("darkgoldenrod")
fillcolor("gold")
begin_fill()
for i in range(5):
    fd(150)
    rt(144)
end_fill()

done()
図 11.17 begin_fillend_fill ではさむと内側が塗られる.星のように交差する図形もきれいに塗れる.
注意 end_fill() を書き忘れるといつまでも塗られません. また,図形が閉じていなくても,始点と終点を結んだものとして塗られます. 思っていない形に塗られたときは,どこで begin_fill したかを 確かめてください.

11.5.3 色の指定 — 名前と #rrggbb

色の指定には 2 とおりあります. 名前で指定する方法と,16 進数で指定する方法です.

書き方説明
名前"red" "gold" "seagreen" "navy" "hotpink"覚えやすい.よく使う色はだいたい名前がある
#rrggbb"#ff8800" "#222831" "#8ec5ff"赤・緑・青の強さを 00ff(0〜255)で並べたもの.細かい色を作れる

#rrggbb は最初とっつきにくいですが,考え方は単純です. #ff0000 は赤だけ全開なので赤,#00ff00 は緑, #0000ff は青.3 つとも同じ値なら灰色で, #000000 が黒,#ffffff が白になります.

図 11.18 赤の強さを変えた(#rr0000
図 11.19 3 つとも同じ値にすると灰色

11.5.4 背景色を変える — bgcolor

bgcolor("色") で画面全体の背景色を変えられます. 背景を暗くして明るい色で描くと,まるで別の作品のように見えます. プログラムのいちばん最初に書くのが普通です.

bgcolor.py
from turtle import *

bgcolor("#1b2430")      # 濃い紺

ht()
pu()

goto(0, 40)
pencolor("#ffd369")
write("MIDNIGHT", align="center", font=("Arial", 48, "bold"))

goto(0, -20)
pencolor("#eeeeee")
write("背景を変えるだけで雰囲気が変わる", align="center",
      font=("Arial", 20, "normal"))

# 星をちりばめる
goto(-240, 120)
dot(8, "white")
goto(-160, 150)
dot(5, "white")
goto(190, 130)
dot(7, "white")
goto(230, -120)
dot(5, "white")
goto(-210, -130)
dot(6, "white")

done()
MIDNIGHT背景を変えるだけで雰囲気が変わる
図 11.20 bgcolor で背景を変えた画面.
虫食い虫食い 11-E 塗った六角形

オレンジで塗りつぶした正六角形を,濃い背景の上に描きます. ____ を埋めてください. 正六角形の曲がる角度は 360 ÷ 6 でしたね.

fill9_hexfill.py
from turtle import *

____("#2b2b3c")          # 背景を濃くする

ht()
pensize(4)
pencolor("#ffd369")
____("#ff8800")          # 塗る色

pu()
goto(-70, -60)
pd()

____()                   # 塗り始め
for i in range(6):
    fd(120)
    rt(____)
____()                   # 塗り終わり

done()

11.6 組み合わせて作品にする

11.6.1 ポスターを作る

ここまでの命令を全部使うと,1 枚のポスターが作れます. 作るときの順番は,背景 → 帯や飾り → 文字です. 文字を先に書くと,あとから描いた図形に隠れてしまいます.

poster.py
from turtle import *

bgcolor("#10203a")
ht()
pu()

# --- 上の帯を塗る ---
fillcolor("#ffd369")
goto(-290, 60)
begin_fill()
goto(290, 60)
goto(290, 150)
goto(-290, 150)
goto(-290, 60)
end_fill()

# --- 飾りの点 ---
goto(-240, -150)
dot(26, "#ff6b6b")
goto(-180, -150)
dot(26, "#4ecdc4")
goto(-120, -150)
dot(26, "#ffe66d")

# --- 文字 ---
goto(0, 85)
pencolor("#10203a")
write("PROGRAMMING I", align="center", font=("Arial", 42, "bold"))

goto(0, 0)
pencolor("white")
write("文字と図形で表現する", align="center", font=("Arial", 34, "bold"))

goto(0, -60)
pencolor("#9fb3c8")
write("Python とタートル", align="center", font=("Arial", 20, "normal"))

done()
PROGRAMMING I文字と図形で表現するPython とタートル
図 11.21 背景・帯・点・文字を重ねたポスター.描く順番が重なりの順番になる.
ペンを上げたまま塗る 帯は goto を 4 回続けて長方形の道をたどり, begin_fill / end_fill ではさんで塗っています. ペンを上げたままでも塗りは効きます (通った道のりが記録されるため).線を出したくないときに便利です.

11.6.2 スコアボードを作る

第 12 章のゲームで使う形です. 画面の上のほうに情報をまとめて出すとゲームらしく見えます. clear() して書き直す形に最初からしておくと,あとが楽です.

scoreboard.py
from turtle import *

bgcolor("#101820")
ht()

score = 1280
life = 3
stage = 2

def draw_board():
    pu()

    # 左:スコア
    goto(-280, 170)
    pencolor("#ffd369")
    write(f"SCORE  {score}", font=("Arial", 26, "bold"))

    # 中央:ステージ
    goto(0, 170)
    pencolor("#4ecdc4")
    write(f"STAGE {stage}", align="center", font=("Arial", 26, "bold"))

    # 右:残機(右そろえにすると桁が増えてもずれない)
    goto(280, 170)
    pencolor("#ff6b6b")
    write(f"LIFE {life}", align="right", font=("Arial", 26, "bold"))

    # 区切り線
    goto(-290, 155)
    pd()
    pencolor("#33475b")
    pensize(3)
    goto(290, 155)
    pu()

draw_board()

# プレイ画面のつもり
goto(0, -30)
pencolor("#9fb3c8")
write("ここがゲームの画面になる", align="center", font=("Arial", 22, "normal"))

done()
SCORE 1280STAGE 2LIFE 3ここがゲームの画面になる
図 11.22 スコアボード.左・中央・右でそろえ方を変えている.

画面を描く手順に draw_board という名前を付けてあるのが要点です. 第 10 章で覚えた def の決まり文句を,そのまま使っています. こうしておけば,スコアが変わったときに clear()draw_board() と 2 行書くだけで表示を更新できます. 第 12 章では,まさにこの形でゲームの画面を毎コマ描き直します.

11.7 この章で出てきた命令

命令意味
write(文字)今いる場所に文字を書く
write(文字, align="center")そろえ方を指定する.leftcenterright
write(文字, font=("Arial", 20, "bold"))書体・大きさ・太さを指定する
f"スコア: {score}"f-string.{ } の中の変数や式を文字に埋め込む
clear()画面に描いたものを全部消す(かめの位置は変わらない)
shape("turtle")姿を変える.classicturtlecirclesquaretrianglearrowblank
shapesize(縦, 横)姿を拡大・縮小する.1 つだけ書くと縦横とも同じ倍率
color(色)ペンの色と塗りの色をまとめて変える
color(線の色, 塗りの色)2 つ書くと,ふちと内側を別々に指定できる
fillcolor(色)塗りの色だけを変える
stamp()今の姿・色・大きさ・向きで,その場にはんこを押す
clearstamps()押したはんこを全部消す(線と文字は残る)
clearstamp(番号)はんこを 1 つだけ消す
dot(大きさ, 色)その場に丸い点を打つ.大きさは直径
begin_fill()ここから塗る,の合図
end_fill()ここまで塗る,の合図.はさんだ道のりの内側が塗られる
bgcolor(色)画面全体の背景色を変える
ontimer(関数, ミリ秒)指定した時間のあとに関数を 1 回呼ぶ(第 10 章)
画像は使えません この教材では画像ファイル(GIF・JPEG)を貼ることはできません. ブラウザの中だけで動くようにしてあるためです. そのかわり,姿・大きさ・色・塗りを組み合わせれば,かなりの表現ができます. 「絵を用意する」ではなく「形を組み立てる」と考えてください.

演習

「▶ この演習を開く」で右側に読み込み,発展させてください. できあがったら「⤓ 保存」でファイルに保存して,手元に残しておきましょう.

演習演習 11-1 自分の名刺

自分の名刺(または名札)を作ってください.出発点のプログラムには 枠と名前だけが入っています.次の条件を満たすように発展させてください.

  • 2 種類以上の文字の大きさを使うこと
  • align を使って,どこかをそろえること
  • dotstamp で飾りを入れること
  • 背景色(bgcolor)を変えること
演習演習 11-2 メダルを作る

begin_fill / end_filldot を使って, 金メダルを描くプログラムを与えます.これを発展させ, 金・銀・銅の 3 つのメダルを横に並べてください. それぞれに 1 2 3 の数字を書き入れましょう.

1
出発点の金メダル
演習演習 11-3 はんこで模様を作る

stamp() だけを使って模様を描くプログラムを与えます. shapeshapesizecolor を変えながら, 自分なりの模様に発展させてください. 繰り返しの回数や角度を変えるだけでも,まったく違う模様になります.

出発点の模様
演習演習 11-4 カウントダウンを仕上げる

虫食い 11-B のカウントダウンを,作品として仕上げてください. 出発点のプログラムは,ただ数が減るだけです.次の条件を満たすようにしてください.

  • 残りが 3 以下になったら文字の色を赤に変えること
  • 背景色を変えること
  • 数字のまわりに図形(dot や塗った円など)を置くこと
  • 0 になったら,好きな文字を大きく表示すること
ヒント 毎コマ clear() しているので, 背景の飾りも毎コマ描き直す必要があります. bgcolor だけは clear() で消えません.
演習演習 11-5 ぱらぱら漫画

姿を切り替えるアニメーションを作ります. いきなり完成形を目指さず,3 段階に分けて作ってください. 1 段階ごとに必ず実行して,動くことを確かめてから次へ進みます.

  1. 第 1 段階 — コマを 1 つだけ出す.まだ動かしません.好きな姿・大きさ・色のものを,好きな場所に 1 つ出すところまで作ります.
  2. 第 2 段階 — コマを 3 つにする.i % 3 で 3 つの姿を順番に切り替えます.出発点のプログラムがちょうどここです.
  3. 第 3 段階 — コマを 4 つ以上に増やして仕上げる.位置や色も一緒に変えて,作品にします.

仕上げるのは第 3 段階のものです.次の条件を満たしてください.

  • コマ数を 4 以上に増やすこと(i % 4 などに直す)
  • shapesizecolor も変えること
  • write で題名を出すこと
ヒント 画像ファイルは使えませんが,「何コマかを順番に見せる」という ぱらぱら漫画の考え方は同じです. コマを何枚用意するか,1 コマを何ミリ秒見せるかを変えて, いちばん気持ちよく見える組み合わせを探してください. 11.4.4 のように背景を流すと,さらにアニメーションらしくなります.
演習演習 11-6 スコアボードつきの画面

第 12 章のゲームの練習です. スコアが自動で増えていくスコアボードを作ってください. 出発点はスコアだけが増える単純なものです.

  • スコアのほかに,残り時間ステージ番号も表示すること
  • align を使って,きちんとそろえること
  • 区切り線か帯を入れて,スコアボードと画面を分けること
  • スコアが一定の数を超えたら,色か文字を変えること
自由演習 11-7 自由制作:動くポスター

ここまでの命令を自由に組み合わせて,動くポスターを作ってください. 題材は何でもかまいません.部活の勧誘,好きな食べ物の紹介, 自分の自己紹介 — 何か人に見せたくなるものにしてください.

  • write で題名と説明を出すこと(2 種類以上の大きさ)
  • bgcolor で背景を決めること
  • dotstampbegin_fill のうち2 つ以上を使うこと
  • ontimer で,どこかが動くこと(文字が変わる・色が変わる・姿が変わる・位置が変わる,のどれでもよい)
  • 先頭にコメントで,題名・氏名・日付を書くこと
ヒント 動かすところは,1 か所で十分です.たとえば 「題名の色が 1 秒ごとに変わる」だけでも,止まっている絵とは印象がまるで違います. 欲張るより,1 つの動きをていねいに作るほうがよい作品になります.
作品例 たとえば,こんな作りにできます.ねたに困ったら真似してみてください.
  1. 画面に「注目→」という文字と,数字を出す
  2. 1 秒ごとに数字を 10, 9, 8 …… と減らす
  3. 残りが 3 になったら数字を赤にする
  4. 0 になったら絵の見た目をがらりと変え,「ぼかーん!!」と大きく書く

数字を減らすのは演習 11-4,見た目を変えるのは 10.3・11.4 でやったことです. すでに習ったものの組み合わせだけでできています.

まとめ

  • write(文字, align=, font=) で画面に文字を書く.色は pencolor で決まる.
  • f-stringf"スコア: {score}")で,数と文字をつなげて表示する.
  • 書いた文字は消せないので,clear() して書き直す.1 コマぶんをまるごと描き直すのが確実.
  • shapeshapesizecolor でかめの見た目を変えられる.姿を順番に切り替えるとぱらぱら漫画になる.
  • stamp は姿のはんこ,dot は丸い点,begin_fill/end_fill は内側の塗りつぶし.
  • 色は名前でも #rrggbb でも指定できる.bgcolor で背景を変えると雰囲気が一変する.
  • 作品を作るときは背景 → 図形 → 文字の順に描く.

次の回はいよいよゲームを作ります. キーボードやマウスで操作して,当たったかどうかを判定する. 第 10 章の ontimer と,今回の write によるスコア表示が, そのまま土台になります. ここまでに習った変数・if・繰り返しを全部つないで,1 本の作品にしましょう.