【徹底解説】Pyxelで作るレトロゲーム|Pythonゲームエンジン完全ガイド

 

 

Pyxelについて – レトロゲームエンジンガイド

以下の記事は、Python製のレトロゲームエンジン「Pyxel」について、読者がはじめて触れる段階から高度な応用まで深く理解できるように構成しています。Pyxelの概要や特徴、インストール方法、基本的なゲームループ構造、グラフィックスの扱い、サウンド機能、エディタの使い方、実践的なテクニックまで網羅しているので、この記事ひとつでPyxelを使いこなし、レトロテイストのゲーム開発を始められるはずです。ぜひ最後までご覧ください。

目次

  1. Pyxelとは何か?
  2. Pyxelの特徴・メリット
  3. インストール方法
  4. 最小構成のプログラム例
  5. 画面の基本(解像度・カラーパレット)
  6. ゲームループ(update関数とdraw関数)
  7. 入力処理(キーボード・マウス・ゲームパッド)
  8. 画像・スプライトの扱い
  9. サウンド・音楽の扱い
  10. Pyxel Editor(内蔵エディタ)の使い方
  11. タイルマップを使ったステージ作成
  12. 衝突判定(簡易的なコリジョン処理)
  13. 実践的なサンプルコード
  14. デバッグ・テストのコツ
  15. 他の類似エンジンとの比較
  16. まとめと応用アイデア



1. Pyxelとは何か?

Pyxelは、Pythonでレトロゲームを開発するためのオープンソースのゲームエンジンです。
作者はkitao氏で、古き良きコンピュータゲームの雰囲気(低解像度や少ない色数などのハードウェア制限)を再現した作品を気軽に作れるよう設計されています。

  • MITライセンスで公開されており、無料で誰でも利用可能
  • 内蔵エディタを使えば、ドット絵・サウンド・マップをGUIで作成できる
  • Pythonの文法がわかれば、初心者でもゲームを作り始めやすい

2. Pyxelの特徴・メリット

  1. シンプルなAPI
    ゲームループ(update, draw)や入力・グラフィックス関連のAPIがシンプルで覚えやすいです。
    わずか数行のコードで「ウィンドウ生成」「画面クリア」「テキスト描画」が可能。
  2. レトロテイストの表現
    • 解像度は最大256×256のピクセル(初期設定の例として160×120などをよく使う)
    • カラーパレットはデフォルト16色(カスタマイズも可能)
    • あえて制限を設けることで、ファミコンやゲームボーイのような雰囲気を再現
  3. マルチプラットフォーム対応
    Windows、macOS、Linux上で動作。Pythonさえ動く環境なら簡単に実行できる
  4. 内蔵エディタによる一貫開発
    コマンドラインからpyxeleditorを起動すると、画像・タイルマップ・サウンド・音楽を一元的に作成・管理できる。
    ピクセル単位で絵を描けるドット絵エディタや波形単位で音を編集できるツールが同梱
  5. コミュニティとサンプル
    GitHubに多数のサンプルが公開されている。
    Pyxelを使ったゲームやツールの事例も豊富にあるため、学習コストが低い



3. インストール方法

PyxelはPythonパッケージとして公開されており、以下のコマンドで導入できます。

pip install pyxel

もし仮想環境(venvやcondaなど)を使っている場合は、その環境下で実行してください。
インストール後にバージョンを確認するには:

python -c "import pyxel; print(pyxel.__version__)"

バージョンが正しく表示されればインストール成功です。

4. 最小構成のプログラム例

まずは“画面を立ち上げて文字を表示する”という、最小限のサンプルを見てみましょう。

import pyxel

def update():
    # ゲームの状態を更新する関数(毎フレーム呼ばれる)
    pass

def draw():
    # 画面描画を行う関数(毎フレーム呼ばれる)
    pyxel.cls(0)  # 画面クリア(カラーID=0)
    pyxel.text(50, 40, "Hello, Pyxel!", 7)  # (x, y, テキスト, カラーID)

pyxel.init(160, 120, caption="Hello Pyxel")  # ウィンドウサイズ(幅, 高さ), タイトル
pyxel.run(update, draw)

pyxel.initでゲーム画面(ウィンドウ)を生成し、サイズやタイトルなどを指定
pyxel.run(update, draw)を呼ぶと、内部でメインループが始まり、毎フレームごとに updatedraw の順に関数が呼ばれる

上記のファイルを保存後、python ファイル名.pyで起動すると、レトロ感のあるウィンドウに「Hello, Pyxel!」と表示されます。



5. 画面の基本(解像度・カラーパレット)

5.1 解像度

Pyxelでは画面サイズを任意に指定できますが、レトロ感を出すために160×120の低解像度がよく使われます。最大解像度は256×256です。
画面サイズを大きくするとレトロ感は薄れますが、表現の幅は広がります。

5.2 カラーパレット

Pyxelデフォルトの16色は下図のようなIDとカラーコードが対応しています(公式ドキュメントより一部抜粋)。

Color IDHex説明
0000000黒(背景など)
11D2B53濃い青
27E2553
3008751濃い緑
4ABBE4D黄系の明るい緑
55F574Fグレーがかった茶色
7FFFFFF白(テキストなど)
8~15他の色

pyxel.cls(0)で画面をクリアしたとき、引数0はカラーID0を意味します。
文字の色7は白を表します。

6. ゲームループ(update関数とdraw関数)

Pyxelプログラムでは、メインループが動いている間、1フレームごとに以下の関数を呼び出します。

  1. update()
    入力取得、キャラクターやオブジェクトの状態変化など「ゲームロジック」の更新を行う関数。
  2. draw()
    画面をクリアし、新しいシーン(グラフィックス)を描画する関数。

いわゆるモダンなゲームループ構造ですが、Pyxelはこの2つの関数を用意してpyxel.run()に渡すだけでOKというシンプル設計です。



7. 入力処理(キーボード・マウス・ゲームパッド)

レトロゲームにおいても、キーボード操作は基本です。Pyxelでは以下のように入力状態を取得できます。

if pyxel.btn(pyxel.KEY_LEFT):
    # 左キーが押されていればTrue
    player_x -= 1

if pyxel.btnp(pyxel.KEY_SPACE):
    # スペースキーが「押された瞬間」だけTrue(押しっぱなしでは再度発火しない)
    jump()

pyxel.btn(keycode)
→ そのキーが押されているかどうかをフレームごとにチェック
pyxel.btnp(keycode)
→ そのキーが「押された瞬間」だけTrue(押しっぱなしなら最初の1回だけ)

キーボード以外にも、マウスやジョイスティックに対応しています。

mx = pyxel.mouse_x
my = pyxel.mouse_y
if pyxel.btn(pyxel.MOUSE_LEFT_BUTTON):
    # 左クリックが押されている
    do_something()

8. 画像・スプライトの扱い

8.1 画像メモリの概要

Pyxel内部には、ゲーム中で使うグラフィックスを保持するイメージバンクがあります。
デフォルトでは、pyxel.image(0)のようにインデックス0~3の4つのイメージバンクが用意され、各バンクは256×256サイズのピクセルデータを保持できます。

8.2 スプライト描画

画像バンクに登録したグラフィックを画面に描画する場合、pyxel.bltを使います。

pyxel.blt(x, y, img_bank_no, u, v, w, h, colkey)

x, y: 描画先の画面座標
img_bank_no: 参照するイメージバンクの番号(0~3)
u, v: 画像バンク上の描画元の左上座標
w, h: 画像の幅と高さ
colkey: 透過色として使うカラーID(不要なら-1

例:

pyxel.blt(10, 20, 0, 0, 0, 16, 16, 0)

これは、イメージバンク0の(0,0)~(16,16)領域を、画面の(10,20)へ透過色0を用いて描画します。

9. サウンド・音楽の扱い

Pyxelにはサウンド再生機能も備わっており、正弦波や矩形波など簡易的な音源でレトロな効果音やBGMを作れます。
サウンドデータも「サウンドバンク(0~63の64個)」に格納し、pyxel.sound(番号)でアクセスします。

# サウンドの再生
pyxel.play(channel, snd)

channel: 0~3の4チャンネルがあり、同時再生が可能
snd: 再生するサウンド番号(sound bankのインデックス)

サウンドや音楽は、Pyxel Editor上で簡単に作成できます(後述)。



10. Pyxel Editor(内蔵エディタ)の使い方

Pyxelには、ドット絵・タイルマップ・サウンド・音楽を一括で編集できるエディタ「Pyxel Editor」が同梱されています。
インストール後、ターミナルやコマンドプロンプトで以下を実行するとエディタが起動します。

pyxeleditor

エディタの画面は大きく以下の4つのタブに分かれています。

  1. Image
    – スプライトやドット絵を描く領域。image bank 0~3を編集できる
    – ツールバーからペン、消しゴム、塗りつぶしなどが利用可能
  2. Tilemap
    tilemap bank 0~7を使ってマップを配置する領域
    – マップチップを並べてステージや背景を作成
  3. Sound
    – 効果音など短いサウンドデータを作成
    – 波形や音程、ボリュームなどを編集
  4. Music
    – 上記Soundを並べてBGMを構成
    – ループポイントや音量バランスを調整

エディタで作成したアセットは、.pyxresという形式のリソースファイルに保存されます。
ゲーム実行時にpyxel.load("assets.pyxres")のように読み込むことで、編集したデータを使えます。

11. タイルマップを使ったステージ作成

大きなステージやマップを作る場合、タイルマップ機能を活用すると便利です。
1つのマップセルが「画像バンク内のどこを参照しているか」を指定する形で、大きなマップを構築できます。

pyxel.tilemap(tm_bank_no).pset(x, y, tile_id)
→ タイルマップにタイルIDを書き込む(プログラムからの操作)
pyxel.bltm(x, y, tm_bank_no, u, v, w, h)
→ タイルマップを画面にまとめて描画

Pyxel EditorのTilemapタブを使うと、GUI上で直感的にタイルを置けるため、ステージ制作が捗ります。

12. 衝突判定(簡易的なコリジョン処理)

Pyxel自体に衝突判定のためのAPIは用意されていません。しかし、レトロゲーム程度であれば、矩形の重なりチェック円同士の距離チェックで十分です。
例えば、プレイヤーと敵が矩形で衝突しているかを調べるには、以下のように書きます。

def check_collision(x1, y1, w1, h1, x2, y2, w2, h2):
    return not (x1 + w1 < x2 or x2 + w2 < x1 or y1 + h1 < y2 or y2 + h2 < y1)

# プレイヤー(px, py, pw, ph)、敵(ex, ey, ew, eh)
if check_collision(px, py, pw, ph, ex, ey, ew, eh):
    # 衝突時の処理
    player_hp -= 1

ゲームの規模が大きくなると、スプライト毎にクラスを作って座標・速度・当たり判定などをまとめて管理すると整理しやすいです。

13. 実践的なサンプルコード

ここでは、キーボードでプレイヤーを動かし、敵キャラを避ける簡易ゲームのサンプルを示します。

import pyxel
import random

class App:
    def __init__(self):
        pyxel.init(160, 120, caption="Simple Avoid Game")
        pyxel.cls(0)
        self.reset()
        pyxel.run(self.update, self.draw)

    def reset(self):
        self.player_x = 80
        self.player_y = 100
        self.enemy_list = []
        self.score = 0
        self.game_over = False

    def update(self):
        if not self.game_over:
            # プレイヤー操作
            if pyxel.btn(pyxel.KEY_LEFT):
                self.player_x -= 2
            if pyxel.btn(pyxel.KEY_RIGHT):
                self.player_x += 2

            # 画面範囲を超えないよう制限
            self.player_x = max(0, min(self.player_x, pyxel.width - 8))

            # 敵生成(一定確率)
            if random.random() < 0.02:
                ex = random.randint(0, pyxel.width - 8)
                self.enemy_list.append([ex, 0])

            # 敵移動
            for e in self.enemy_list:
                e[1] += 2

            # 敵削除(画面外のもの)
            self.enemy_list = [e for e in self.enemy_list if e[1] < pyxel.height]

            # 衝突判定(プレイヤーと敵)
            for e in self.enemy_list:
                if (abs(e[0] - self.player_x) < 8 and
                    abs(e[1] - self.player_y) < 8):
                    self.game_over = True
                    pyxel.play(0, 0)  # 衝突SE
                    break

            # スコア加算
            self.score += 1
        else:
            # ゲームオーバー時にリスタート
            if pyxel.btnp(pyxel.KEY_R):
                self.reset()

    def draw(self):
        pyxel.cls(0)
        if not self.game_over:
            pyxel.text(5, 5, f"SCORE: {self.score}", 7)
            # プレイヤー描画
            pyxel.rect(self.player_x, self.player_y, 8, 8, 8)
            # 敵描画
            for e in self.enemy_list:
                pyxel.rect(e[0], e[1], 8, 8, 2)
        else:
            pyxel.text(60, 50, "GAME OVER", 8)
            pyxel.text(40, 60, f"YOUR SCORE: {self.score}", 7)
            pyxel.text(45, 80, "PRESS R TO RESTART", 7)

App()

– 左右キーで自機を動かし、上から降ってくる敵を避け続けるだけのシンプルなゲーム
– 衝突判定は座標差を判定して簡易的に実装
pyxel.rectで四角を描画しているだけなので、ドット絵を使ったグラフィックスに差し替えるのも簡単です

14. デバッグ・テストのコツ

  1. ログ出力を活用
    – Pythonのprintやロガーを使って、フレームごとの変数を確認
    – デバッグ時のみ描画する座標情報や当たり判定領域を表示してもよい
  2. 小さなモジュールに分割
    – キャラクター、敵、弾、ステージなどをクラスやモジュール単位で分割し、テストしやすくする
    – メインのupdate()draw()はシンプルに保つ
  3. Pause機能やスロー機能
    – ゲーム速度を一時的に落とす(フレームスキップ/ウェイト調整)ことで、挙動を追いやすくする
    – Pyxel標準では提供していないので、自前で制御してみるのも手
  4. Pyxel Editorでのリソース管理
    – 大規模なゲームでは手作業のアセット管理が煩雑
    – エディタでタイルやサウンドを一元管理するとバグが減る



15. 他の類似エンジンとの比較

Pyxel以外にも、Pythonでレトロ風ゲームを作れるツールはいくつか存在します。代表的なものを表にまとめてみました。

ライブラリ/エンジン特徴向いている用途
Pyxel16色パレット、最大256×256画面、内蔵エディタ完備。シンプルなAPIレトロゲーム開発全般。小~中規模プロジェクト
PygamePythonゲームライブラリの定番。自由度が高いが、レトロ制限は自前実装幅広いジャンルのゲーム
PICO-8Luaベースの仮想コンソール。固定の128×128解像度、16色パレットPyxel同様、制限付きレトロゲーム
love2dLuaベース。制限は少なめ2Dゲーム全般、プロトタイピング

Pyxelは「Pythonベース」「内蔵エディタあり」「レトロ制限の再現」に強みがあるため、PICO-8ライクな環境でPythonを使いたい人におすすめです。



16. まとめと応用アイデア

Pyxelは、レトロ感を味わいながらゲームを作りたいPythonユーザーに最適なエンジン
– シンプルなAPIで、update/drawを用意しpyxel.run()するだけでゲームループが成立
– Pyxel Editorを使えば、ドット絵・タイルマップ・サウンドを一元管理できる
– 衝突判定や物理演算などは手動実装が必要だが、その分ゲームプログラミングの基礎を学べる

応用アイデア

  1. アクションゲーム
    タイルマップでステージを作り、当たり判定を仕組む。
    敵AIを実装し、パワーアップやボス戦などを導入
  2. 弾幕シューティング
    スプライトを多用し、敵弾を大量に生成・管理する。
    パフォーマンスが限界を超えないよう最適化を考える
  3. パズルゲーム
    マウスやキーボード操作でブロックを移動・回転させ、テトリスや落ち物ゲームを実装
  4. RPG
    Tilemapでマップを作り、NPCやメッセージウィンドウ、イベントを作り込む。
    長編になる場合はセーブデータの仕組みを工夫
  5. オンライン連携
    WebソケットやAPIを用いて通信対戦・スコアランキングを実装(Pythonのネットワーク機能を利用)

これらのアイデアはあくまで一例です。
「こんなの作れるかな?」と試行錯誤しながら、プログラムとデザインの両面でレトロゲーム開発を楽しんでみてください。

総括

Pyxelは、
– Pythonで簡単にレトロ感のあるゲームを作れる
– 内蔵エディタによりアートやサウンドを直感的に編集可能
– update/drawの二関数によるシンプルなゲームループを採用
– 十分な制限(低解像度や16色パレット)が、逆にクリエイティビティを刺激する
という魅力的なゲームエンジンです。大規模なゲームにも対応できるものの、初心者でも取り組みやすいので、学習用や個人の趣味プロジェクトとしてぜひ試してみてください。
レトロなドット絵やサウンドをこだわって作るほど、自分だけのオリジナルゲームに仕上がります。
ぜひこの記事を参考に、Pyxelでのゲーム開発を始めてみましょう!

 

特集記事

コメント

この記事へのコメントはありません。

TOP