$./invaders.py

スペースインベーダーを、
ターミナルで。

RETRO INVADERS は、Python の標準ライブラリ curses だけで描く スペースインベーダー・オマージュ。ハーフブロック文字でドット絵を表現し、 8bit 風の効果音は起動時にその場で合成します。音声ファイルも画像ファイルも不要です。

uv run invaders.py
GitHub リポジトリ
  • Python 3.10+curses だけで動作
  • 56 × 24最小ターミナルサイズ
  • 8bit効果音はすべて合成
  • 30 FPS固定フレームレート
katzkawai@penguin: ~/kklab-ds1017-samples
RETRO INVADERS のタイトル画面。大きな SPACE INVADERS のロゴ、3種類のインベーダーと得点、PRESS SPACE TO START の表示。

// gameplay

実際のプレイ画面

タイトル画面からウェーブ1の攻略まで、約1分半の録画です。音声はミュートで再生しています。

コントロールから音声をオンにすると、合成された効果音も聴けます。

// features

レトロの作り方

外部アセットに頼らず、端末の中だけで完結するように設計しています。

ターミナルだけで完結

描画は curses、ゲームロジックは標準ライブラリのみ。ウィンドウを開かず、SSH 越しの端末でもそのまま遊べます。

縦解像度2倍のドット絵

1文字を上下2ピクセルとして扱うハーフブロック(▀▄█)描画。5×4 の敵スプライトが、ブロックの継ぎ目なく動きます。

8bit サウンドを合成

pygame-ce のミキサーで、ショット・行進・UFO・被弾などの効果音を起動時に生成。音声ファイルは同梱していません。

壊れていくバンカー

4基のバンカーは当たったピクセルだけが円形に削れます。敵が降りてくると踏み潰され、防御はどんどん薄くなります。

ハイスコアを保存

スコアとサウンド設定は ~/.retro_invaders.json に保存。次に起動したときも、前回の記録から始まります。

描画とサウンドを選べる

--ascii で ASCII 文字のみ、--no-sound で消音。UTF-8 でない端末では自動的に ASCII 描画へ切り替わります。

// how to play

あそびかた

操作

←→ / AD自機を左右に移動
Space / W / ↑ショット(同時に1発)
P / Escポーズ(再開も同じキー)
Mサウンドのオン/オフ
Qタイトルへ戻る/終了

ゲームオーバー画面では Space または R でリトライ、Q でタイトルへ。

ルールと得点

  • 敵は横一列に並んで行進し、端にぶつかると一段下がります。
  • 残りが少なくなるほど行進は速くなり、ウェーブを重ねるとさらに加速します。
  • 自機は3機。全滅するか、敵が自機の位置まで降りてくるとゲームオーバー。
  • 一度に出せる自機の弾は1発だけ。狙って撃ちましょう。
  • 上段30 PTS
  • 中段20 PTS
  • 下段10 PTS
  • ミステリーシップ50–300 PTS

// under the hood

中身の話

1ファイル・約1,600行の Python スクリプトです。先頭の PEP 723 ブロックが依存関係と Python バージョンを宣言しているので、 uv run invaders.py だけで環境が整います。Game クラスは curses に依存しないため、ヘッドレスでテストできます。

スペック

エントリポイント
invaders.py(PEP 723)
描画
curses + Unicode ハーフブロック
ロジック
curses 非依存の Game クラス
オーディオ
pygame-ce で合成/失敗時はベル
保存先
~/.retro_invaders.json
オプション
--ascii / --sound / --no-sound

起動方法

# uv があればこれだけ
uv run invaders.py

# pygame-ce が無い環境でも遊べます(音はベル)
python3 invaders.py

# ASCII 描画 / 消音で起動
uv run invaders.py --ascii --no-sound

初回は pygame-ce が uv のキャッシュ環境に自動で入ります。ターミナルは UTF-8・56×24 以上(推奨 80×24 以上)で。