N88-BASICのプログラムを再現する教材案
N88-BASIC や MS-DOS 時代の
- 少ない命令で描く
- 数式から図形を作る
- 画面メモリや保存形式を意識する
という感覚は、Pyxel ととても相性がいいです。
今の学習環境で再現すると、「昔の仕組み」と「今のPython」をつなげて見せられるのが大きな強みですね。
特に教材として見ると次の流れがとてもきれいです。
- まず数式で点を打つ
- 点を線で結んで曲線にする
- 画面を保存する
- ファイル形式の違いを学ぶ
- 昔のBASICとの共通点を比べる
高校生にも、
「昔のプログラムは古い」のではなく、
「本質が見えやすい」
と伝わりやすいと思います。
次の章立てで考えてみます。
- 第1回: Pyxelで点を打つ
- 第2回: sin, cos で円や波を描く
- 第3回: リサージュ曲線を描く
- 第4回: 画面をBMP保存する
- 第5回: 昔のBASICとの対応を見る
- 第6回: 色数・解像度・保存形式の違いを考える
教材向けに、できるだけ簡潔にまとめます。
第1回: Pyxelで点を打つ
ねらい
- 画面の座標の考え方を知る
- 1つの点を表示する
- 点を増やして図形のもとを作る
基本
Pyxelでは、画面上の位置を (x, y) で表します。
-
xは右に行くほど大きい -
yは下に行くほど大きい - 左上が
(0, 0)
点を打つには、1ピクセルを描く命令を使います。
学ぶこと
- 座標を指定すると、その場所に点が出る
- 点をたくさん並べると線や形になる
- 昔のBASICの
PSETに近い感覚で考えられる
たとえば
- 画面の中央に点を打つ
- 横に点を並べる
- 斜めに点を並べる
こうすると、「図形は点の集まりでできている」と分かります。
大事な見方
ここではまず、
「画面はマス目の集まり」
として見ることが大切です。
第2回: sin, cos で円や波を描く
ねらい
- 数学の式で図形を描く感覚をつかむ
-
sinとcosの基本的な使い方を知る - 点の集まりを、なめらかな曲線にする
基本
sin と cos は、角度に応じて値が変わる関数です。
この値を使うと、円や波を描けます。
円の考え方
中心を (cx, cy)、半径を r とすると、
x = cx + r * cos(t)y = cy + r * sin(t)
で円周上の点を求められます。
t を少しずつ変えながら点を打つと、円になります。
波の考え方
たとえば横方向に進みながら、
y = cy + A * sin(xの変化)
のようにすると、波の形になります。
-
Aは波の高さ -
sinの中身で波の細かさが変わる
学ぶこと
- 数学の式は、そのまま図形にできる
- 点をたくさん打つと曲線に見える
- 円も波も「計算した座標に点を打つ」だけで作れる
大事な見方
ここでのポイントは、
「プログラムは絵を直接描くのではなく、座標を計算している」
ということです。
2回分を通したまとめ
第1回で分かること
- 画面には座標がある
- 点を打つと絵が作れる
第2回で分かること
- 数式で座標を決めれば、円や波が描ける
- 数学とプログラミングがつながる
教材としての流れ
とても自然な流れになっています。
- まず1個の点を打つ
- 点を並べる
- 座標を計算する
- 数式から図形を作る
この順に進むと、生徒が理解しやすいです。
簡潔な解説のひとこと
- 第1回は「画面と座標の入門」
- 第2回は「数式で絵を描く入門」
と考えると分かりやすいです。
昔の N88-BASIC でいうと、
- 第1回は
PSETの感覚 - 第2回は
SIN,COSを使った作図の感覚
に近い内容です。
コード例
import math
import pyxel
class PyxelMathLesson:
def __init__(self):
self.width = 320
self.height = 240
self.mode = 1
self.t = 0.0
pyxel.init(self.width, self.height, title="Pyxel Lesson 1-2")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_1):
self.mode = 1
if pyxel.btnp(pyxel.KEY_2):
self.mode = 2
self.t += 0.03
def draw(self):
pyxel.cls(0)
if self.mode == 1:
pyxel.text(10, 10, "Lesson 1: PSET", 7)
pyxel.text(10, 20, "Press 1 or 2", 6)
# 中央の点
cx = self.width // 2
cy = self.height // 2
pyxel.pset(cx, cy, 8)
# 横に点を並べる
for x in range(30, 130, 4):
pyxel.pset(x, 60, 10)
# 斜めに点を並べる
for i in range(60):
pyxel.pset(180 + i, 50 + i, 11)
# 格子状に点を打つ
for y in range(150, 220, 10):
for x in range(40, 141, 10):
pyxel.pset(x, y, 12)
pyxel.text(cx + 6, cy - 4, "CENTER", 7)
pyxel.text(30, 70, "HORIZONTAL DOTS", 10)
pyxel.text(180, 115, "DIAGONAL DOTS", 11)
pyxel.text(40, 225, "GRID DOTS", 12)
if self.mode == 2:
pyxel.text(10, 10, "Lesson 2: SIN COS", 7)
pyxel.text(10, 20, "Press 1 or 2", 6)
# 円を描く
cx = 90
cy = 120
r = 60
prev_x = None
prev_y = None
steps = 180
for i in range(steps + 1):
a = 2 * math.pi * i / steps
x = int(cx + r * math.cos(a))
y = int(cy + r * math.sin(a))
pyxel.pset(x, y, 8)
if prev_x is not None:
pyxel.line(prev_x, prev_y, x, y, 8)
prev_x = x
prev_y = y
pyxel.circ(cx, cy, 2, 7)
pyxel.text(62, 190, "CIRCLE", 8)
# 波を描く
wave_y = 120
amp = 40
prev_x = None
prev_y = None
for x in range(170, 311):
angle = (x - 170) * 0.08 + self.t
y = int(wave_y + amp * math.sin(angle))
pyxel.pset(x, y, 11)
if prev_x is not None:
pyxel.line(prev_x, prev_y, x, y, 11)
prev_x = x
prev_y = y
pyxel.line(170, wave_y, 310, wave_y, 5)
pyxel.text(220, 190, "SINE WAVE", 11)
PyxelMathLesson()
これは、第1回と第2回を1つのプログラムにまとめた教材用のコードです。
1 キーで「点を打つ学習」、2 キーで「sin, cos で円や波を描く学習」に切り替えられます。
全体のねらい
このコードは、次の順に理解できるように作っています。
- まずは座標を指定して点を打つ
- 次に点を並べて形を作る
- さらに数式で座標を計算して、円や波を描く
つまり、
- 第1回: 座標と点
- 第2回: 数学の式と図形
を自然につなげています。
1. __init__ の役割
self.width = 320
self.height = 240
self.mode = 1
self.t = 0.0
pyxel.init(self.width, self.height, title="Pyxel Lesson 1-2")
pyxel.run(self.update, self.draw)
ここでは最初の設定をしています。
- 画面サイズを
320 x 240にする - 最初は
mode = 1にして、第1回の内容を表示する -
self.tは波を動かすための時間のような値 -
pyxel.run(self.update, self.draw)で毎フレーム処理を続ける
self.mode が、今どちらの教材画面を見せるかの切り替え役です。
2. update() の役割
def update(self):
if pyxel.btnp(pyxel.KEY_1):
self.mode = 1
if pyxel.btnp(pyxel.KEY_2):
self.mode = 2
self.t += 0.03
ここでは入力を見ています。
-
1キーを押したら第1回 -
2キーを押したら第2回
に切り替わります。
また、
self.t += 0.03
で少しずつ値を増やしています。
これは第2回の波を少し動かすためです。
ここで考えてみるとよいのは、
「同じ sin でも、中に入れる値を少しずつ変えると形が動く」ということです。
3. draw() の役割
pyxel.cls(0)
まず毎回、画面を黒で消しています。
そのあと、mode に応じて内容を描いています。
第1回: Pyxelで点を打つ
if self.mode == 1:
3-1. 中央の点
cx = self.width // 2
cy = self.height // 2
pyxel.pset(cx, cy, 8)
-
cx,cyは画面の中央座標 -
pyxel.pset(x, y, color)で1ピクセルだけ点を打つ
ここが最も基本です。
昔の BASIC の PSET とかなり近い感覚です。
「座標を決めて、そこに点を置く」という学習の出発点ですね。
3-2. 横に点を並べる
for x in range(30, 130, 4):
pyxel.pset(x, 60, 10)
ここでは y=60 を固定して、x だけ変えています。
つまり、
- 横一直線に点を並べる
という例です。
この部分から分かるのは、
-
xを変えると左右に動く -
yを固定すると同じ高さに並ぶ
という座標の基本です。
3-3. 斜めに点を並べる
for i in range(60):
pyxel.pset(180 + i, 50 + i, 11)
ここでは x も y も同時に増やしています。
その結果、
- 右へ進みながら
- 下へも進む
ので、斜めの並びになります。
これは「直線も、点の集まりで表せる」という見方につながります。
3-4. 格子状に点を打つ
for y in range(150, 220, 10):
for x in range(40, 141, 10):
pyxel.pset(x, y, 12)
これは2重ループです。
- 外側で
yを変える - 内側で
xを変える
ことで、点を縦横にたくさん並べています。
これにより、
- 画面が座標の集まりであること
- 点を規則的に並べると模様になること
が分かります。
教材としてはここで、
「では、間隔を 10 ではなく 5 にするとどうなるかな」
と問いかけると、生徒が考えやすいです。
第2回: sin, cos で円や波を描く
if self.mode == 2:
ここからは、座標を直接決めるのではなく、式で計算します。
4-1. 円を描く準備
cx = 90
cy = 120
r = 60
prev_x = None
prev_y = None
steps = 180
ここでは円の設定をしています。
- 中心は
(90, 120) - 半径は
60 -
steps = 180は円周を何分割するか
prev_x, prev_y は、1つ前の点を覚えておくためのものです。
4-2. 円の式
for i in range(steps + 1):
a = 2 * math.pi * i / steps
x = int(cx + r * math.cos(a))
y = int(cy + r * math.sin(a))
ここがとても大事です。
円は次の式で描けます。
x = cx + r * cos(a)y = cy + r * sin(a)
意味はこうです。
-
cx,cyは円の中心 -
rは半径 -
aは角度
角度 a を少しずつ変えると、円周上の点が順番に求められます。
つまり、円を直接描いているのではなく、
「円周上の座標を1個ずつ計算している」のです。
4-3. 点と線で円を描く
pyxel.pset(x, y, 8)
if prev_x is not None:
pyxel.line(prev_x, prev_y, x, y, 8)
prev_x = x
prev_y = y
-
pset()で点を打つ - 1つ前の点と
line()で結ぶ
この2つを組み合わせると、なめらかな円に見えます。
もし line() を消すと、「点の集まりの円」になります。
そこを比較すると、点と線の違いも学べます。
4-4. 中心点を表示
pyxel.circ(cx, cy, 2, 7)
円の中心が分かりやすいように、小さな丸を描いています。
教材としては、
「この中心から半径 r だけ離れた点を計算している」
と説明すると理解しやすいです。
5. 波を描く部分
wave_y = 120
amp = 40
prev_x = None
prev_y = None
ここでは波の設定をしています。
-
wave_yは波の基準の高さ -
ampは振幅、つまり波の高さ
5-1. 波の式
for x in range(170, 311):
angle = (x - 170) * 0.08 + self.t
y = int(wave_y + amp * math.sin(angle))
ここでは x を少しずつ増やしながら、y を sin で計算しています。
式の見方はこうです。
-
xは右へ進む -
sin(angle)の値で上下にゆれる - それに
ampをかけて波の高さを決める -
wave_yを足して、波全体の位置を下げたり上げたりする
つまり、
- 横には一定に進む
- 縦だけ周期的に変わる
ので、波の形になります。
5-2. 波を動かしている理由
angle = (x - 170) * 0.08 + self.t
ここで self.t を足しています。
これにより、毎フレーム少しずつ位相がずれて、波が動いて見えます。
もし + self.t を消すと、静止した波になります。
ここは教材として、
「式の中に時間を入れると、図形が動く」
という発展につながる大事なポイントです。
5-3. 波も点と線で描く
pyxel.pset(x, y, 11)
if prev_x is not None:
pyxel.line(prev_x, prev_y, x, y, 11)
円と同じ考え方です。
- 計算した点を打つ
- 点どうしを線で結ぶ
これでなめらかな波になります。
5-4. 基準線を表示
pyxel.line(170, wave_y, 310, wave_y, 5)
これは波の中心の高さを表す線です。
この線があると、
- 波がこの線より上に行く
- 下にも行く
-
sinが上下に振れる
というのが見えやすくなります。
このコードで学べること
第1回で学べること
-
pset()で点を打てる - 座標
(x, y)の意味 - 点を並べると形になる
第2回で学べること
-
sin,cosで座標を計算できる - 円や波を数式で描ける
- 点を線でつなぐと曲線らしく見える
- 数学の式を動きに使える
昔のBASICとのつながり
このコードは、感覚としてかなり昔の環境に近いです。
-
pyxel.pset()→ BASIC のPSET -
forで点を並べる → BASIC のFOR...NEXT -
sin,cosで座標計算 → 数式作図 - 点を積み重ねて図形にする → 当時の作図の基本
そのため、MS-DOS や N88-BASIC の教材との対比にも向いています。
授業での見せ方の例
簡潔に見せるなら、こんな順番が自然です。
- まず中央に1点だけ打つ
- 横に並べる
- 斜めに並べる
- 円の式を見せる
- 波の式を見せる
- 「座標を直接書く」から「座標を式で作る」へ発展させる
この流れにすると、生徒が
「数式はただの計算ではなく、絵を作る道具なんだ」
と感じやすいです。
第3回: リサージュ曲線を描く
第3回では、円や波より少し発展して、2つの周期運動を組み合わせた図形を描きます。これがリサージュ曲線です。
解説
リサージュ曲線は、次のような式で表せます。
x = cx + ax * sin(a * t + d)y = cy + ay * sin(b * t)
それぞれの意味はこうです。
-
cx, cy: 図形の中心 -
ax, ay: 横と縦の大きさ -
a, b: 横と縦の振動の回数 -
d: ずれ具合 -
t: 0 から少しずつ変える値
どこが大事か
円では、sin と cos を使って1つの回転を表しました。
リサージュ曲線では、横と縦を別々の周期で動かします。
たとえば
- 横は3回ゆれる
- 縦は4回ゆれる
のようにすると、きれいな模様になります。
学習のポイント
- 点の座標を式で計算している
- 周期の比が変わると形が変わる
- 数学の式がそのまま図形になる
見てほしいこと
コードの中の
a = 3b = 4d = math.pi / 2
を変えると、模様が変化します。
「どんな比のときにどんな形になるか」を試すと、学習が深まります。
コード
import math
import pyxel
class LissajousLesson:
def __init__(self):
self.width = 320
self.height = 240
self.a = 3
self.b = 4
self.d = math.pi / 2
self.ax = 110
self.ay = 80
pyxel.init(self.width, self.height, title="Lesson 3: Lissajous Curve")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_1):
self.a = 2
self.b = 3
if pyxel.btnp(pyxel.KEY_2):
self.a = 3
self.b = 4
if pyxel.btnp(pyxel.KEY_3):
self.a = 5
self.b = 4
if pyxel.btnp(pyxel.KEY_LEFT):
self.d -= 0.1
if pyxel.btnp(pyxel.KEY_RIGHT):
self.d += 0.1
def draw(self):
pyxel.cls(0)
cx = self.width // 2
cy = self.height // 2
pyxel.text(10, 10, "Lesson 3: Lissajous Curve", 7)
pyxel.text(10, 20, "1:(2,3) 2:(3,4) 3:(5,4)", 6)
pyxel.text(10, 30, "LEFT/RIGHT: phase", 6)
pyxel.text(10, 40, f"a={self.a} b={self.b} d={self.d:.2f}", 10)
pyxel.line(cx, 20, cx, self.height - 20, 5)
pyxel.line(20, cy, self.width - 20, cy, 5)
prev_x = None
prev_y = None
steps = 2000
for i in range(steps + 1):
t = 2 * math.pi * i / steps
x = int(cx + self.ax * math.sin(self.a * t + self.d))
y = int(cy + self.ay * math.sin(self.b * t))
pyxel.pset(x, y, 10)
if prev_x is not None:
pyxel.line(prev_x, prev_y, x, y, 8)
prev_x = x
prev_y = y
pyxel.circ(cx, cy, 2, 7)
LissajousLesson()
このコードでは、
に切り替えられます。
また、左右キーで位相差 d を変えられます。
教材としては、次の問いにすると考えやすいです。
-
aとbが同じだと、どんな形になるかな -
a:b = 2:3と3:4では、何が違うかな - 位相差
dを変えると、形はどう変わるかな
第4回: 画面をBMP保存する
第4回では、描いた画面をファイルとして保存する学習をします。
ここでは、Pyxel の画面を BMP 形式で保存します。
解説
BMP は、比較的しくみが分かりやすい画像形式です。
PNG のような圧縮を使わないので、教材として扱いやすいです。
この回のポイントは、次の4つです。
- 画面の各ピクセルの色を読む
- 色番号を RGB に変える
- BMP の形式に合わせてデータを並べる
- ファイルとして保存する
1. Pyxel の画面の色を読む
Pyxel では、pyxel.pget(x, y) を使うと、その場所の色番号を読めます。
たとえば、
-
(0, 0)は左上 -
(x, y)を変えると画面全体を順に読める
という形です。
2. 色番号を RGB に変える
Pyxel の色は 0〜15 の番号ですが、BMP には実際の色の値が必要です。
そこで、たとえば
- 8 → 赤
- 10 → 黄
- 7 → 白
のように、番号を (R, G, B) に変換する表を用意します。
3. BMP の並び方
BMP では少し注意があります。
- 1ピクセルは 3バイト
- 並びは
RGBではなくBGR - 画像の下の行から上に向かって保存する
- 1行の長さは 4バイトの倍数にそろえる
この4つが大事です。
4. ヘッダーを付けて保存する
BMP ファイルには、画素データだけでなく
- ファイルヘッダー
- 情報ヘッダー
が必要です。
これを先頭に付けて、最後に画素データを書けば BMP になります。
この教材で学べること
- 画面はピクセルの集まりである
- 色は番号だけでなく RGB で表せる
- ファイル形式には決まったルールがある
- 描画と保存は別の処理である
昔の BASIC 学習とつなげるなら、
- 画面に描く
- 画面内容を取り出す
- ファイルとして保存する
という流れが見えやすい回です。
コード
import os
import time
import struct
import pyxel
PALETTE = [
(0, 0, 0),
(43, 51, 95),
(126, 32, 114),
(25, 149, 156),
(139, 72, 82),
(57, 92, 152),
(169, 193, 255),
(238, 238, 238),
(212, 24, 108),
(211, 132, 65),
(233, 195, 91),
(112, 198, 169),
(118, 150, 222),
(163, 163, 163),
(255, 151, 152),
(237, 199, 176),
]
class SaveBmpLesson:
def __init__(self):
self.width = 320
self.height = 240
self.frame = 0
self.message = "S: save BMP"
pyxel.init(self.width, self.height, title="Lesson 4: Save BMP")
pyxel.run(self.update, self.draw)
def save_screen_bmp(self, filename):
row_size = (self.width * 3 + 3) & ~3
pixel_data_size = row_size * self.height
file_size = 14 + 40 + pixel_data_size
file_header = struct.pack(
"<2sIHHI",
b"BM",
file_size,
0,
0,
14 + 40
)
info_header = struct.pack(
"<IIIHHIIIIII",
40,
self.width,
self.height,
1,
24,
0,
pixel_data_size,
2835,
2835,
0,
0
)
pixel_bytes = bytearray()
for y in range(self.height - 1, -1, -1):
row = bytearray()
for x in range(self.width):
color_index = pyxel.pget(x, y)
r, g, b = PALETTE[color_index]
row.extend((b, g, r))
while len(row) < row_size:
row.append(0)
pixel_bytes.extend(row)
with open(filename, "wb") as f:
f.write(file_header)
f.write(info_header)
f.write(pixel_bytes)
def update(self):
self.frame += 1
if pyxel.btnp(pyxel.KEY_S):
os.makedirs("captures", exist_ok=True)
filename = time.strftime("captures/lesson4_%Y%m%d_%H%M%S.bmp")
self.save_screen_bmp(filename)
self.message = "saved: " + filename
def draw(self):
pyxel.cls(0)
pyxel.text(10, 10, "Lesson 4: Save screen as BMP", 7)
pyxel.text(10, 20, "Press S to save", 6)
pyxel.text(10, 30, self.message, 10)
pyxel.line(20, 200, 300, 200, 5)
pyxel.circ(70, 80, 30, 8)
pyxel.rect(130, 60, 60, 40, 11)
pyxel.rectb(210, 50, 70, 60, 10)
for i in range(120):
x = 30 + i * 2
y = int(140 + 20 * pyxel.sin(i * 3 + self.frame * 2))
pyxel.pset(x, y, 12)
SaveBmpLesson()
コードの見どころ
save_screen_bmp()
この関数が保存の中心です。
- BMP のヘッダーを作る
- 画面を下の行から読む
-
BGRの順に並べる - ファイルへ書く
という流れになっています。
pyxel.pget(x, y)
ここで現在の画面の色を1ピクセルずつ読んでいます。
struct.pack(...)
BMP のヘッダーをバイナリ形式で作っています。
ここは「ファイル形式には決まった並びがある」と学ぶ部分です。
S キーで保存
このプログラムでは、S キーを押したときに captures フォルダへ BMP を保存します。
教材としての問いかけ例
- なぜ BMP は下の行から保存するのだろうか
- なぜ
RGBではなくBGRなのだろうか - 保存する前と後で、画面の内容はどう関係しているだろうか
-
pyxel.pget()で全部読むのは、どんな仕組みだろうか
ひとことでまとめると
第4回は、
- 描いた画面を
- ピクセル単位で読み取り
- BMP のルールに合わせて
- ファイル保存する
という内容です。
第5回: 昔のBASICとの対応を見る
ねらい
- 今の Python + Pyxel と、昔の BASIC の共通点を見る
- 命令は違っても、考え方の本質は同じだと知る
- 座標、繰り返し、数式、描画、保存の流れを整理する
全体の見方
昔の N88-BASIC や MS-DOS 時代のプログラムでは、
- 座標を決める
- 点を打つ
- 繰り返す
- 数式で位置を計算する
- 画面に描く
という流れが基本でした。
これは、今の Pyxel でもほぼ同じです。
つまり、
「言語や書き方は変わっても、図形を作る考え方は同じ」
ということです。
対応表
1. 画面を使う
昔のBASICでは、画面モードを設定して描画を始めました。
Pyxelでは pyxel.init() で画面を用意します。
- BASIC
- 画面モード設定
- Pyxel
pyxel.init(320, 240)
ここでの共通点は、
「まず描く場所を用意する」
ことです。
2. 点を打つ
昔のBASICでは PSET を使いました。
Pyxelでは pyxel.pset(x, y, c) を使います。
- BASIC
PSET (X,Y), C
- Pyxel
pyxel.pset(x, y, c)
これはかなり直接的な対応です。
第1回の内容とつながります。
3. 線を引く
昔のBASICでは LINE 命令がありました。
Pyxelでも pyxel.line() があります。
- BASIC
LINE (X1,Y1)-(X2,Y2), C
- Pyxel
pyxel.line(x1, y1, x2, y2, c)
これも考え方は同じです。
4. 繰り返し
昔のBASICでは FOR ... NEXT を使いました。
Pythonでは for を使います。
- BASIC
FOR I=1 TO 100NEXT I
- Python
for i in range(100):
ここで学んでほしいのは、
「点をたくさん打つには繰り返しが必要」
ということです。
5. 条件分岐
昔のBASICでは IF ... THEN を使いました。
Pythonでは if を使います。
- BASIC
IF A=1 THEN ...
- Python
if a == 1:
キー入力や画面切り替えの処理は、この考え方で同じように作れます。
6. 数学関数
昔のBASICでも SIN, COS が使えました。
Pythonでは math.sin(), math.cos() を使います。
- BASIC
X=160+100*COS(T)Y=120+100*SIN(T)
- Python
x = 160 + 100 * math.cos(t)y = 120 + 100 * math.sin(t)
円や波、リサージュ曲線は、この対応がとても分かりやすいです。
7. 文字を表示する
昔のBASICでは LOCATE, PRINT などを使いました。
Pyxelでは pyxel.text() を使います。
- BASIC
LOCATE 1,1PRINT "HELLO"
- Pyxel
pyxel.text(10, 10, "HELLO", 7)
完全に同じではありませんが、
「画面に文字を出して説明する」
という役割は共通です。
8. 時間変化やアニメーション
昔のBASICでは、ループで少しずつ値を変えながら再描画しました。
Pyxelでは update() と draw() がその役割を分担しています。
- BASIC
- ループの中で値を変える
- 描画をくり返す
- Pyxel
-
update()で値を変える -
draw()で画面を描く
-
ここは見た目の書き方は違いますが、本質はかなり近いです。
9. 画面保存
昔の環境では、機種やソフトによって方法が違いました。
今は Python でファイル形式を扱えるので、BMP保存のような学習がしやすくなっています。
共通点は、
「画面の内容をデータとして扱う」
という考え方です。
ここまでの5回との対応
第1回: 点を打つ
- BASIC の
PSET - Pyxel の
pyxel.pset()
第2回: sin, cos で円や波を描く
- BASIC の
SIN,COS - Python の
math.sin(),math.cos()
第3回: リサージュ曲線
- BASIC でも数式ループで表現可能
- Python でも同じように座標を計算して描く
第4回: 画面をBMP保存する
- 昔は機種依存が強かった
- 今はファイル形式を学びながら保存処理を作れる
第5回: 昔のBASICとの対応を見る
- 命令の名前は違っても、考え方は共通
- 「座標」「繰り返し」「数式」「描画」が中心
授業で強調したいこと
この回で特に大切なのは、
「昔のプログラムは古いから価値がない」のではなく、
「基本原理が見えやすい」
ということです。
たとえば、
- 点を打つ
- 数式で位置を決める
- くり返して図形にする
という考え方は、今でもそのまま通用します。
むしろ、シンプルだからこそ本質が分かりやすいです。
生徒向けの短いまとめ
- BASIC も Python も、座標を計算して画面に描く点は同じ
- 命令の形は違っても、やっていることはよく似ている
- 昔の学び方を知ると、今のプログラムの意味も見えやすくなる
ひとことでまとめると
第5回は、
「今のPyxelの学習内容を、昔のBASICの言葉に置きかえて見直す回」
です。
これによって、ここまでの内容が単なる操作ではなく、
「昔から続くプログラミングの基本」
として整理できます。
もちろんです。第6回は、これまで描いてきた図形や保存した画像をふり返りながら、コンピュータで絵を扱うときの基本条件を整理する回です。
第6回: 色数・解像度・保存形式の違いを考える
ねらい
- 画像の見え方は、色数・解像度・保存形式で変わると知る
- 「きれいに見える/粗く見える」の理由を考える
- 昔のBASIC時代の画面環境と、今の環境の違いを比較する
1. 色数とは何か
色数とは、画面で同時に使える色の数のことです。
たとえば Pyxel は、基本的に 16色のパレットを使います。
つまり、1つの点には「0〜15のどれかの色番号」が入ります。
色数が少ないとどうなるか
- 使える色が限られる
- 表現はシンプルになる
- ドット絵のような見た目になりやすい
- 少ない情報で管理できる
色数が多いとどうなるか
- より自然な色合いを表しやすい
- グラデーションがなめらかになる
- 写真のような表現に向く
- データ量は増えやすい
教材として大事な見方
ここで大切なのは、
「色は無限に使えるのではなく、ある範囲に制限されていることがある」
と知ることです。
昔の環境では、この制限が今よりずっと強く、だからこそ工夫が必要でした。
2. 解像度とは何か
解像度とは、画面の細かさです。
たとえば 320×240 なら、
- 横に 320個
- 縦に 240個
の点で画面ができています。
つまり、画面はたくさんの小さな点の集まりです。
解像度が低いと
- 1つ1つの点が目立ちやすい
- 図形の輪郭がギザギザしやすい
- 昔の画面らしい見た目になりやすい
解像度が高いと
- 細かい表現がしやすい
- 線や曲線がなめらかに見えやすい
- 情報量が増える
たとえば
同じ円を描いても、
- 低い解像度では角ばって見える
- 高い解像度では丸く見えやすい
という違いがあります。
3. 色数と解像度は別の要素
ここは混同しやすいので大切です。
- 色数
→ 何種類の色を使えるか - 解像度
→ どれだけ細かく点を並べられるか
つまり、
- 色が多くても、点が少なければ粗く見える
- 点が多くても、色が少なければ表現が単純になる
のです。
この2つは別々に考える必要があります。
4. 保存形式とは何か
保存形式とは、画像をファイルとして保存するときのルールです。
たとえば、
- BMP
- PNG
- GIF
などがあります。
同じ画面を保存しても、形式によって特徴が違います。
5. BMPの特徴
これまで扱った BMP は、仕組みが比較的単純です。
長所
- 構造が分かりやすい
- 教材として扱いやすい
- 圧縮なしで保存しやすい
短所
- ファイルサイズが大きくなりやすい
- 保存効率はあまりよくない
学習上の意味
BMPは、
「画像ファイルには決まった並びがある」
ことを理解するのに向いています。
6. PNGの特徴
PNG は、今よく使われる画像形式です。
長所
- 圧縮されるのでファイルサイズを小さくしやすい
- 画質を落とさず保存できる
- 図や画面キャプチャに向いている
短所
- BMPより仕組みが少し複雑
- 教材として最初に内部構造を扱うには少し難しい
学習上の見方
PNGは実用的ですが、
「まず画像の仕組みを学ぶ」段階では BMP のほうが理解しやすいことがあります。
7. GIFの特徴
GIF は、色数が少ない形式としてよく知られています。
長所
- 256色までで扱える
- アニメーションGIFが作れる
- シンプルな図や短い動きに向いている
短所
- 色数が少ない
- 写真のような複雑な色表現には向きにくい
Pyxelとの相性
Pyxel はもともとレトロな見た目なので、GIF と相性がよい場面があります。
特に、動く教材や記録には便利です。
8. 昔のBASIC時代との比較
昔の環境では、
- 色数が少ない
- 解像度が低め
- 機種ごとに画面仕様が違う
- 保存方法も統一されていない
ということが多くありました。
そのため、
「限られた条件でどう表現するか」
がとても大切でした。
今は環境が豊かになりましたが、Pyxel のような学習環境では、あえて制限を持たせることで本質が見えやすくなります。
9. これまでの学習とのつながり
第1回 点を打つ
- 解像度が低いほど、1点の存在が大きく見える
第2回 円や波を描く
- 解像度によって、曲線のなめらかさが変わる
第3回 リサージュ曲線
- 複雑な曲線も、結局は点の集まりであると分かる
第4回 BMP保存
- 画面の情報は、ファイル形式に従って保存される
第5回 BASICとの対応
- 昔は色数や解像度の制約が、今より学習の前面にあった
第6回
- その制約や保存方法の違いを整理して考える
10. 授業で考えたい問い
この回では、次のような問いが考えやすいです。
- なぜ同じ図でも、画面サイズが違うと見え方が変わるのか
- なぜ色が少ないと、工夫が必要になるのか
- なぜ BMP は分かりやすいが、ファイルサイズが大きいのか
- なぜ GIF は動きを保存できるのか
- なぜ昔の画面は単純でも、学習には向いていたのか
11. 生徒向けの短いまとめ
- 色数は「使える色の種類の数」
- 解像度は「画面の細かさ」
- 保存形式は「画像をファイルにするときの決まり」
- 画像の見え方やデータ量は、これらの条件で変わる
12. ひとことでまとめると
第6回は、
「画面の絵は、色・点の数・保存方法という条件の上に成り立っている」
ことを考える回です。
ここまで図形を描いてきた経験があるからこそ、
「なぜこの見た目になるのか」
を整理して理解できる段階です。
第1回〜第6回の全体まとめ
第1回: Pyxelで点を打つ
最初の回では、画面はたくさんの点の集まりでできていることを学びました。
学んだこと
- 座標
(x, y)の意味 - 左上が
(0, 0)であること -
psetで1つの点を打てること - 点を並べると線や模様のもとになること
この回の意義
ここはすべての出発点です。
「図形を描く」といっても、まずは1点をどこに置くか、という考え方が基本になります。
昔のBASICでいうと、PSET の感覚にあたります。
第2回: sin, cos で円や波を描く
第1回では座標を直接決めましたが、第2回では数式で座標を求めました。
学んだこと
-
sin,cosを使って座標を計算すること - 円の式
- 波の式
- 点をたくさん打つと曲線に見えること
この回の意義
ここで、
「プログラムは絵を直接描くのではなく、座標を計算している」
という見方ができるようになります。
数学とプログラミングがつながる、大事な回です。
第3回: リサージュ曲線を描く
第2回の円や波をさらに発展させて、周期の異なる運動を組み合わせた図形を描きました。
学んだこと
- 横方向と縦方向で別の周期を持たせること
- 位相差を入れること
-
a:bの比によって形が変わること - 複雑な模様も、結局は座標計算の積み重ねであること
この回の意義
第2回の「数式で図形を描く」を、より深く実感できる回です。
単純な円や波から、芸術的な模様へ発展できることが見えてきます。
第4回: 画面をBMP保存する
ここでは、描いたものをその場で見るだけでなく、ファイルとして残す方法を学びました。
学んだこと
-
pgetで画面の色を読むこと - 色番号をRGBに変えること
- BMP形式の基本的な仕組み
- ヘッダーと画素データの考え方
- 描画と保存は別の処理であること
この回の意義
ここで、
「画面に見えているものもデータである」
と理解できます。
また、画像ファイルには決まった形式があることも学べます。
第5回: 昔のBASICとの対応を見る
この回では、ここまでの内容を昔のBASICと対応づけて整理しました。
学んだこと
-
PSETとpyxel.pset() -
LINEとpyxel.line() -
FOR...NEXTとfor -
SIN,COSとmath.sin(),math.cos() - 昔も今も、座標・繰り返し・数式が基本であること
この回の意義
命令の形は変わっても、本質は大きく変わっていないと分かります。
昔の学び方を知ることで、今のコードの意味も深く見えるようになります。
第6回: 色数・解像度・保存形式の違いを考える
最後に、表示や保存の条件そのものを整理しました。
学んだこと
- 色数とは何か
- 解像度とは何か
- 保存形式によって特徴が違うこと
- BMP、PNG、GIF の違いの考え方
- 昔の環境では制約が強く、その中で工夫していたこと
この回の意義
これまで描いてきた図形や保存した画像が、
- どんな色で
- どのくらい細かく
- どんな形式で残されるか
という条件の上に成り立っていることを整理できます。
6回を通した学習の流れ
この教材全体は、次の順で自然につながっています。
1. 点を知る
まず、画面は点の集まりであると理解する。
2. 点を並べる
座標を変えながら、線や模様のもとを作る。
3. 数式で座標を作る
sin, cos を使って、円や波を描く。
4. より複雑な図形に発展する
リサージュ曲線のように、複数の周期を組み合わせる。
5. 描いたものを保存する
画面をBMPとして保存し、画像データとして扱う。
6. 表示条件や時代背景を考える
色数・解像度・保存形式、そして昔のBASICとの対応を見る。
この教材全体の中心テーマ
この6回を通して、一番大事なのは次のことです。
図形は座標の集まりである
どんな絵も、結局は点の位置で表せます。
数式は図形を作る道具である
数学の式は、ただ計算するだけでなく、絵や動きを作る力があります。
画面もファイルもデータである
見えている絵は、そのままデータとして読み取り、保存できます。
昔も今も本質は同じである
言語や環境が変わっても、
- 座標
- 繰り返し
- 数式
- 描画
- 保存
という基本は共通しています。
昔のBASICとのつながりから見たまとめ
この教材は、昔のN88-BASICやMS-DOS時代の学習ともとてもよくつながります。
- 第1回は
PSET - 第2回は
SIN,COSによる作図 - 第3回は数式ループによる模様描画
- 第4回は画面データと保存
- 第5回は命令の対応整理
- 第6回は色数や解像度の制約の理解
つまり、昔の教材のよさを、今のPythonとPyxelで再構成している形です。
生徒向けの短い全体まとめ
- 画面は点の集まりでできている
- 点の位置を変えると図形になる
- 数式で座標を決めると円や波や模様が描ける
- 描いた画面は画像として保存できる
- 今のPythonも昔のBASICも、基本の考え方はよく似ている
- 色数、解像度、保存形式によって見え方や扱い方が変わる
ひとことで全体をまとめると
第1回〜第6回は、
「点から始めて、数式で図形を描き、画面データとして保存し、その意味を昔のBASICや画像の条件と結びつけて理解する学習」
になっています。
生徒向け演習問題 模範解答付き版
第1回: Pyxelで点を打つ
演習問題と模範解答
問1
画面の中央に1つ点を打つには、どんな考え方を使えばよいですか。
模範解答
画面の横幅と縦幅の半分を求めて、その座標を中央と考える。
たとえば画面が 320×240 なら、中央は (160, 120) になる。
問2
y を固定して x だけ変えると、点はどのように並びますか。
模範解答
同じ高さに横一列に並ぶ。
x は左右の位置を表すので、x だけを変えると横方向に広がる。
問3
x と y を同じだけ増やしていくと、どのような並びになりますか。
模範解答
右下へ向かう斜めの並びになる。
たとえば (10, 10), (11, 11), (12, 12) のように増えると、斜め線のように見える。
問4
格子状に点を並べるには、繰り返しを何回使うと考えやすいですか。
模範解答
2回使うと考えやすい。
1回は横方向、もう1回は縦方向のために使う。
発展問題
点の間隔を広くした場合と狭くした場合で、見え方はどう変わるでしょうか。
模範解答
間隔を広くすると、点がまばらに見えて粗い印象になる。
間隔を狭くすると、点が密になって線や面に近く見える。
第2回: sin, cosで円や波を描く
演習問題と模範解答
問1
円を描くとき、中心と半径はそれぞれどんな役割を持っていますか。
模範解答
中心は円の真ん中の位置を決める。
半径は中心から円周までの距離を決める。
この2つで、円の場所と大きさが決まる。
問2
sin と cos を使うと、なぜ円が描けるのでしょうか。簡単に説明してみましょう。
模範解答
cos で左右の位置、sin で上下の位置を表し、角度を少しずつ変えると、点が円周上を一周するから。
そのため、点を順番に打つと円になる。
問3
波を描くとき、振幅を大きくすると何が変わりますか。
模範解答
波の上下のゆれが大きくなる。
つまり、山が高くなり谷が深くなる。
問4
点だけで描いた円と、点を線で結んだ円では、見え方はどう違いますか。
模範解答
点だけの円は、点の集まりとして見える。
線で結ぶと、よりなめらかな円に見える。
発展問題
sin の式の中の値を少しずつ変えると、波はどのように動いて見えるでしょうか。
模範解答
波が横に流れるように見える。
これは、位相が少しずつ変わるためである。
第3回: リサージュ曲線を描く
演習問題と模範解答
問1
リサージュ曲線では、横方向と縦方向で何が違いますか。
模範解答
横方向と縦方向で、別々の周期の運動を使っているところが違う。
そのため、円や単純な波より複雑な図形になる。
問2
a:b = 2:3 と a:b = 3:4 では、図形にどんな違いが出そうですか。
模範解答
横と縦の振動の回数が変わるので、交わり方や模様の形が変わる。
一般に、比が変わると図形の印象も変化する。
問3
位相差を変えると、図形はどう変わりますか。
模範解答
横方向のずれ具合が変わるので、全体の形や傾き方、ふくらみ方が変わる。
問4
リサージュ曲線も、結局は何の集まりと考えられますか。
模範解答
点の集まりと考えられる。
複雑に見えても、計算した座標に点を打って作っている。
発展問題
a と b が同じ値のとき、どんな形に近づくか予想してみましょう。
模範解答
位相差の取り方によるが、円や楕円、または斜めの線に近い形になることが多い。
横と縦の周期が同じなので、規則的で単純な形になりやすい。
第4回: 画面をBMP保存する
演習問題と模範解答
問1
Pyxelの画面の色を読むとき、何を使いますか。
模範解答
pyxel.pget(x, y) を使う。
これで指定した座標の色番号を読み取れる。
問2
Pyxelの色番号を、そのままBMPに書けないのはなぜですか。
模範解答
Pyxelの色は 0〜15 の番号で表されているが、BMPでは実際の色の値、つまり RGB や BGR の形が必要だから。
問3
BMPでは、なぜ1行の長さをそろえる必要があるのでしょうか。
模範解答
BMPの形式では、各行を4バイトの倍数にそろえる決まりがあるから。
そのため、足りないぶんを埋める必要がある。
問4
「描画すること」と「保存すること」は、どう違いますか。
模範解答
描画は画面に見えるようにする処理であり、保存はその画面の内容をファイルとして記録する処理である。
見た目を出すことと、データとして残すことは別である。
発展問題
BMPとPNGでは、どちらが教材として仕組みを学びやすいと思いますか。理由も考えてみましょう。
模範解答例
BMPのほうが学びやすい。
理由は、圧縮がなく構造が比較的単純で、画素データの並び方を理解しやすいから。
PNGは実用的だが、圧縮があり仕組みが少し複雑である。
第5回: 昔のBASICとの対応を見る
演習問題と模範解答
問1
BASICの PSET と、Pyxelの pset は、どんな点で似ていますか。
模範解答
どちらも、指定した座標に1つの点を打つ命令である。
座標を指定して描くという考え方が共通している。
問2
BASICの FOR...NEXT と、Pythonの for は、どちらも何のために使いますか。
模範解答
繰り返し処理のために使う。
同じような計算や描画を何回も行うときに用いる。
問3
昔のBASICでも、円や波が描けたのはなぜですか。
模範解答
SIN や COS のような数学関数と、繰り返し処理を使って座標を計算できたから。
つまり、今と同じように数式で点の位置を求められたからである。
問4
命令の書き方が違っても、本質が同じといえる理由を説明してみましょう。
模範解答
どちらも、座標を計算し、繰り返しを使い、画面に点や線を描くという基本の流れが同じだから。
表現方法は違っても、考え方は共通している。
発展問題
昔のBASICのほうが、今より本質が見えやすい面はあるでしょうか。自分の考えを書いてみましょう。
模範解答例
あると思う。
理由は、使える命令や機能が少ないぶん、点を打つ、数式で座標を求める、繰り返す、といった基本がはっきり見えるから。
一方で、今の環境は便利だが、内部の仕組みが見えにくいこともある。
第6回: 色数・解像度・保存形式の違いを考える
演習問題と模範解答
問1
色数が少ないと、見た目にはどんな特徴が出ますか。
模範解答
使える色が限られるため、表現が単純になりやすい。
グラデーションが少なく、はっきりしたレトロな見た目になりやすい。
問2
解像度が低いと、曲線はどのように見えやすくなりますか。
模範解答
曲線がギザギザして見えやすくなる。
点の数が少ないため、なめらかさが減るからである。
問3
色数と解像度は、どう違う概念ですか。
模範解答
色数は、使える色の種類の数である。
解像度は、画面を構成する点の細かさや数である。
つまり、色の豊かさと、形の細かさは別の要素である。
問4
BMP、PNG、GIFには、それぞれどんな特徴がありますか。
模範解答
- BMP: 構造が単純で学びやすいが、ファイルサイズが大きくなりやすい
- PNG: 圧縮できて画質を保ちやすく、実用的である
- GIF: 色数は少ないが、簡単なアニメーションに向いている
発展問題
Pyxelのような16色の環境は、不便でしょうか。それとも学習に向いているでしょうか。理由も考えてみましょう。
模範解答例
学習に向いている面がある。
理由は、色数が少ないぶん、色の選び方や画面の仕組みを意識しやすいから。
また、昔の環境に近く、基本原理を学ぶ教材として使いやすい。
総合演習問題 模範解答
問1
第1回から第3回までの内容は、どのようにつながっていますか。
模範解答
第1回では点を打つ基本を学び、第2回では数式で点の位置を計算して円や波を描き、第3回ではさらに周期の違う運動を組み合わせて複雑な図形を描いた。
つまり、点から始まり、数式による図形表現へ発展している。
問2
「数式で図形を描く」とは、どういう意味ですか。自分の言葉で説明してみましょう。
模範解答
図形の形に合う座標を、数式を使って順番に計算し、その場所に点を打ったり線を引いたりして図形を作ること。
円や波を直接描くのではなく、その上にある点を求めている。
問3
画面を保存する学習は、点を打つ学習とどうつながっていますか。
模範解答
画面は点の集まりでできているので、保存するときも各点の色を順番に読み取って記録する。
つまり、描画で使った点の考え方が、そのまま保存にもつながっている。
問4
昔のBASICと今のPythonでは、何が違い、何が同じですか。
模範解答
違うのは、命令の書き方や環境の便利さである。
同じなのは、座標を計算し、繰り返しを使って、画面に点や線を描くという基本の考え方である。
問5
同じ図形でも、色数や解像度が変わると見え方が変わるのはなぜですか。
模範解答
色数が変わると使える色の種類が変わり、解像度が変わると形の細かさが変わるから。
そのため、同じ図形でも印象やなめらかさが違って見える。
記述問題 模範解答例
記述1
この教材を通して、「数学」と「プログラミング」はどのようにつながっていると感じましたか。
模範解答例
数学は、図形の形や動きを式で表すために使われ、プログラミングはその式をもとに実際の画面上に表現するために使われていると感じた。
特に sin や cos を使うと、数学の学習内容がそのまま図形や動きになることが分かった。
記述2
昔のBASICの考え方を学ぶことは、今のプログラミング学習にどんな意味があると思いますか。
模範解答例
昔のBASICは機能が少ないぶん、点を打つ、繰り返す、数式で位置を求めるといった基本が見えやすい。
そのため、今の便利な環境でも、本質的な考え方を理解する助けになると思う。
記述3
あなたが一番おもしろいと感じた回はどれですか。その理由も書いてみましょう。
模範解答例
第3回のリサージュ曲線が一番おもしろかった。
理由は、簡単な式を組み合わせるだけで、予想以上に複雑できれいな模様が描けたから。
数学と図形のつながりを強く感じた。
指導のための補足
模範解答は1つに固定されるものばかりではありません。
特に発展問題や記述問題では、生徒なりの表現ができていれば、考え方を評価するのが大切です。
たとえば、
- 用語が完全でなくても意味が合っている
- 自分の言葉で説明できている
- 比較や理由が書けている
といった点を見ていくとよいです。
全体のまとめ
この教材では、
- 点を打つ
- 数式で図形を描く
- 複雑な模様へ発展させる
- 画面を保存する
- 昔のBASICと対応づける
- 色数や解像度や保存形式を考える
という流れで、画面表現の基本を学びました。
参考資料





