注意
バージョンや環境によってはうまく動かない可能性があります
投稿時の各バージョンは以下です
- pyxel:2.2.7
- pygame-ce:2.5.2
- plumOS-RN:v2.0
はじめに
Pyxelは1.0がリリースされた時にちょっと触ったぐらいの経験だったのですが、、、
以下の2つの投稿を見て、久々に Pyxel 熱が再燃してきました🏃
最近は、以下のようなテキストアドベンチャーエンジンもどきを、少しずつ作っています👀
Pyxelの思想を考えると、少々邪道な作りですが、、、
※イメージバンク乱用していたり、BGMはpygame使ってフリー素材のOggファイルに頼り切りだったり
PCで動かせるのはもちろん、Webで実行出来たり、中華ゲーム機(plumOS利用)で実行出来たり、色々なプラットフォームで動かせるのは楽しいです👾
ただ、上述の通り、BGM再生をOggに頼り切ってしまうと、
WebやplumOSで実行する際に一手間が必要になってきます。
この投稿では、WebやplumOS-RNでOggを再生する方法の一例を記載しています。
この投稿のソースコードは以下にコミットしています。
1.ローカルPC
まずは、ローカルPCでのOggファイル再生です。
ソースコードは以下です。
pygame-ceを使用しているだけなので、あまり特別なことはしていませんね。
import pyxel
import pygame
class Sample:
def __init__(self):
self.play_flag = False
# Oggファイルパス
self.ogg_path = "maou_bgm_acoustic22.ogg"
# pygame初期化
pygame.mixer.init()
# Pyxel初期化
pyxel.init(256, 256)
pyxel.run(self.update, self.draw)
def update(self):
if not self.play_flag:
# Oggファイル読み込み
pygame.mixer.music.load(self.ogg_path)
# Oggファイル再生
pygame.mixer.music.play(-1) # -1はループ再生
self.play_flag = True
def draw(self):
pyxel.cls(7)
# 再生表示
if self.play_flag:
pyxel.text(2, 2, "Now Playing...", 1)
pyxel.text(2, 10, self.ogg_path, 1)
Sample()
実行する時は以下の通り。
cd 01.Local-PC
python sample.py
2.Web
次にWeb実行です。
せっかくのWeb実行なので、GitHub Pagesに公開しています。
Web実行用のソースコードは以下です。
Pythonコード自体はローカルPCと同じソースコードですね。
import pyxel
import pygame
class Sample:
def __init__(self):
self.play_flag = False
# Oggファイルパス
self.ogg_path = "maou_bgm_acoustic22.ogg"
# pygame初期化
pygame.mixer.init()
# Pyxel初期化
pyxel.init(256, 256)
pyxel.run(self.update, self.draw)
def update(self):
if not self.play_flag:
# Oggファイル読み込み
pygame.mixer.music.load(self.ogg_path)
# Oggファイル再生
pygame.mixer.music.play(-1) # -1はループ再生
self.play_flag = True
def draw(self):
pyxel.cls(7)
# 再生表示
if self.play_flag:
pyxel.text(2, 2, "Now Playing...", 1)
pyxel.text(2, 10, self.ogg_path, 1)
Sample()
htmlファイルには少し対応が必要です。
PyxelのWeb実行では、追加で利用できるパッケージが限られています(PyxelはPyodideを利用しているため、Pyxelの制約と言うよりはPyodideの制約)
利用できるパッケージは、Pyodide 対応パッケージに記載されている通りです。今回は pygame-ce を利用しています。
追加パッケージを利用する場合には、<pyxel-play>タグの packages にパッケージ名を追加します。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/kitao/pyxel/wasm/pyxel.js"></script>
</head>
<body>
<pyxel-play root="." name="02.Web.pyxapp" packages="pygame-ce"></pyxel-play>
</body>
</html>
実行する時は以下の通り。
cd 02.Web
pyxel package ./ sample.py
python -m http.server 8000 # http://localhost:8000
3.plumOS-RN
最後にplumOS-RNでの実行です。
少々、録画の音量が小さいですが、以下のように動作しています。
ローカルPCやWebでは、pygame-ce が利用できたので、pygame-ce のBGM再生機能をそのまま使用しました。
plumOS-RNでは、任意のパッケージは(現時点では)追加できないので、もう少し別の対応をしています。
【2024年12月14日追記】
ゲームで見るITの世界さんから情報いただきました。
portsやSSH接続でpipインストール出来るとのこと(試していませんがPythonスクリプトからのsubprocessでもいける?)
これで、sample.pyはどのプラットフォームでも共通で行けますね。ありがとうございます。
以下は、訂正前の情報です。作業ログとして残しておきます👀
pygame-ce は内部では、SDL2と言うマルチメディアライブラリを利用して、マルチメディアを扱っています。
plumOS-RNにも、SDL2自体はインストールされているため、
Pythonから直接SDL2を使用します(/usr/lib/の下にsoファイルがいます)
import ctypes
from ctypes import c_int, c_char_p
import pyxel
class Sample:
def __init__(self):
self.play_flag = False
# Oggファイルパス
self.ogg_path = "maou_bgm_acoustic22.ogg"
# Pyxel初期化
pyxel.init(256, 256)
pyxel.run(self.update, self.draw)
def update(self):
if not self.play_flag:
# SDL2およびSDL2_mixerの共有ライブラリをロード
sdl2 = ctypes.CDLL("/usr/lib/libSDL2.so")
sdl2_mixer = ctypes.CDLL("/usr/lib/libSDL2_mixer.so")
# SDL2およびSDL2_mixerの関数を定義
sdl2.SDL_Init.argtypes = [c_int]
sdl2.SDL_Init.restype = c_int
sdl2_mixer.Mix_Init.argtypes = [c_int]
sdl2_mixer.Mix_Init.restype = c_int
sdl2_mixer.Mix_OpenAudio.argtypes = [c_int, c_int, c_int, c_int]
sdl2_mixer.Mix_OpenAudio.restype = c_int
sdl2_mixer.Mix_LoadMUS.argtypes = [c_char_p]
sdl2_mixer.Mix_LoadMUS.restype = ctypes.c_void_p
sdl2_mixer.Mix_PlayMusic.argtypes = [ctypes.c_void_p, c_int]
sdl2_mixer.Mix_PlayMusic.restype = c_int
# SDL2を初期化
sdl2.SDL_Init(0x00000010) # オーディオサブシステムを有効化
# SDL_mixerのOGGサポートを有効化
sdl2_mixer.Mix_Init(0x00000002) # Oggの初期化フラグ
# オーディオデバイスを初期化
# 周波数: 44100Hz, フォーマット: 16ビット, チャンネル: ステレオ, チャンクサイズ: 1024
sdl2_mixer.Mix_OpenAudio(44100, 0x8010, 2, 1024)
# Oggファイル読み込み
music = sdl2_mixer.Mix_LoadMUS(self.ogg_path.encode("utf-8"))
# Oggファイル再生
sdl2_mixer.Mix_PlayMusic(music, -1) # -1はループ再生
self.play_flag = True
# AボタンかBボタンで終了
if pyxel.btnp(pyxel.GAMEPAD1_BUTTON_A) or pyxel.btnp(pyxel.GAMEPAD1_BUTTON_B):
pyxel.quit()
def draw(self):
pyxel.cls(7)
# 再生表示
if self.play_flag:
pyxel.text(2, 2, "Now Playing...", 1)
pyxel.text(2, 10, self.ogg_path, 1)
Sample()
実行する時は以下の通り。
出来上がった「03.plumOS-RN.pyxapp」をWinSCPなどで、plumOS-RNを導入した中華ゲーム機へコピーしてください。
cd 03.plumOS-RN
pyxel package ./ sample.py
使用BGMについて
BGMは、魔王魂 様の アコースティック22 を使用しております。
魔王塊様はゲーム制作の強い味方です。ありがとうございます🙇
以上、Oggファイルを再生したお話でした。