レトロゲームエンジン「Pyxel」で�ゲームプログラミングをはじめよう!
Let’s start game programming with the retro game engine “Pyxel”
北尾 崇 @kitao
Takashi Kitao
ピ ク セ ル
こんにちは、PyCon JP 2020!
Hello, PyCon JP 2020!
2
自己紹介 Self-introduction
3
本日得られること What you can get today
4
Pythonだけでこんなプログラムを簡単に作れるようになります�You can easily create such programs only with Python
155行 155 lines
14行 14 lines
本日の説明内容 Contents
5
Pyxelの概要と導入�Overview and installation of Pyxel
6
Pyxel(ピクセル)とは What is Pyxel?
7
「Fantasy Console」について About “Fantasy Console”
8
Fantasy Console俯瞰 Fantasy Console overview
9
有償 Paid
無料 Free
厳密な制約
Strict constraints
緩めの制約
Less constraints
Lua
Lua
Lua / MoonScript
Lua
Python
Pyxelの5つの特長 Five features of Pyxel
10
Pyxelの基本仕様
11
16色で表現できること What can be expressed in 16 colors
12
Illustration by Toshio Noguchi
作品例① Production examples #1
13
Both games are created by helpcomputer0
作品例② Production examples #2
14
レトロゲーム風セキュリティ・インシデント可視化ツール「8vana(ハチバーナ)」 by Isao Takaesu
Retro game style security incident visualization tool "8vana" by Isao Takaesu
Pyxelの導入方法 Installation of Pyxel
15
Windows (32bit / 64bit)
Python3インストール&PATH追加後に After installing Python3 and adding to PATH
pip install pyxel
Linux (Ubuntu)
sudo apt install python3 python3-pip libsdl2-dev libsdl2-image-dev gifsicle
sudo -H pip3 install -U pyxel
Mac (Catalina)
brew install python3 gcc sdl2 sdl2_image gifsicle
pip3 install -U pyxel
Homebrewインストール後に After installing Homebrew
WindowsでのPATH追加方法 How to add to PATH on Windows
16
サンプルの実行方法 How to execute the examples
サンプルを専用コマンド install_pyxel_examples でコピー�Copy the examples with the dedicated command install_pyxel_examples�����任意のファイルを選んで実行�Select and execute any file�� Windows:���� Mac or Linux:
17
install_pyxel_examples
cd pyxel_examples
python 01_hello_pyxel.py
python3 01_hello_pyxel.py
サンプル一覧 List of examples
18
Pyxelを使ったお絵描きプログラムの作成�Create a doodle program with Pyxel
19
Pyxelを使ったお絵描きの方法 How to doodle with Pyxel
20
import pyxel
pyxel.init(160, 120)
pyxel.rect(40, 40, 80, 40, 8)
pyxel.show()
実行結果 Execution result
21
実行結果 Execution result
22
rect(左座標, 上座標, 幅, 高さ, 色):指定した位置とサイズの矩形を描画する�rect(left, top, width, height, color) : Draw a rectangle at the specified position and size
pyxel.rect(40, 40, 80, 40, 8)
(0,0)
+x
+y
(40,40)
80
40
(159,119)
Pyxelの描画命令 Drawing commands of Pyxel
23
画面をクリアする�Clear screen
点を描画する�Draw a point
矩形を描画する�Draw a rectangle
円を描画する�Draw a circle
画像を描画する�Draw an image
文字を描画する�Draw text
直線を描画する�Draw a line
矩形の枠を描画する�Draw a rectangular frame
円の枠を描画する�Draw a circle frame
タイルマップを描画する�Draw a tilemap
色番号を置き換える�Replace color number
お絵描きの例 Doodle example
24
import pyxel
data = [40, 70, 50, 20, 100, 50, 40, 20]
pyxel.init(128, 128)
for i, d in enumerate(data):
pyxel.rect(i * 14 + 10, 120 - d, 10, d, 8 + i)
pyxel.line(0, 120, 127, 120, 7)
pyxel.show()
Pyxelによる絵の動かし方 How to animate doodles with Pyxel
25
import pyxel
x = 0
pyxel.init(160, 120)
while True:
x += 2
if x >= pyxel.width + 20:
x = -20
pyxel.cls(0)
pyxel.circ(x, 60, 20, 11)
pyxel.flip()
実行結果 Execution result
26
circ(中心X座標, 中心Y座標, 半径, 色):指定した位置と半径の円を描画する�circ(x, y, radius, color) : Draw a circle at the specified position and radius
pyxel.circ(x, 60, 20, 11)
つぶやきPyxelへの挑戦 Challenge to Pyxel tweet
27
つぶやきPyxelの例① Pyxel tweet example #1
28
from pyxel import *
from math import *
a=0
init(128,128)
while 1:
cls(1)
for x in range(0,128,4):
for y in range(0,128,4):
d=sqrt((x-64)**2+(y-64)**2)
b=sin(d*0.2+a)*4
c=(15-d*0.2)%16
circ(x+b,y+sin(b/4)*4,1,c)
a+=0.2
flip()
つぶやきPyxelの例② Pyxel tweet example #2
29
SNS投稿に便利な機能 Convenient functions for SNS posting
30
付属ツールを使った素材の作成�Create assets using the included tool
31
Pyxel Editorについて About Pyxel Editor
32
pyxeleditor
pyxeleditor your_resource_filename
または or
モード変更ボタン�Mode change buttons
ヘルプメッセージ�Help message
イメージバンクの仕組み Image Bank mechanism
33
Copy
blt(x, y, img, u, v, w, h, [colkey])
Image Bank with 256x256 pixels (0-2)
Screen with
256x256 pixels or less
w
h
Image Bank #img
(u,v)
(x,y)
イメージエディタ Image Editor
イメージバンクを編集するモード Mode for editing Image Banks
34
0-2の3イメージバンクが使用可能�3 Image Banks from 0 to 2 are available
PNG画像をドラッグ&ドロップすると選択中のイメージバンクにインポートできる
Drag and drop PNG images to import into the selected image bank
他の慣れたツールで画像を作成してインポートするのも一つのやり方�Creating and importing images with other familiar tools is another way
タイルマップの仕組み Tilemap mechanism
35
bltm(x, y, tm, u, v, w, h, [colkey])
Image Bank with 256x256 pixels (0-2)
Tilemap with 256x256 tiles (0-7)
Tilemap #tm
w
h
(u,v)
(x,y)
Screen with�256x256 pixels or less
00
01
02
...
03
32
33
34
...
35
64
65
66
...
67
Refer to tile image
Copy
00
01
02
...
03
32
33
34
...
35
64
65
66
...
67
タイルマップエディタ Tilemap Editor
タイルマップを編集するモード Mode for editing Tilemaps
36
0-7の8タイルマップが使用可能�8 Tilemaps from 0 to 7 are available
イメージバンクを選択する際にドラッグすると、複数のタイルを同時に選択できる
Multiple tiles can be selected simultaneously by dragging when selecting an image bank
そのタイルマップが何番のイメージバンクを�参照していたかも保存される�The number of the Image Bank that the Tilemap referred to is also saved
サウンドエディタ Sound Editor
サウンドを編集するモード Mode for editing Sounds
37
0-63の64サウンドが使用可能�64 Sounds from 0 to 63 are available
SPEEDの値が小さいほど速く再生される
The smaller the SPEED value, the faster the playback
再生速度によって効果音やメロディになる
Depending on the playback speed, it becomes a sound effect or melody
使用可能な音色(TON)やエフェクト(EFX)の種類は右上のヘルプメッセージに表示される
The types of tones (TON) and effects (EFX) that can be used are displayed in the help message in the upper right
ミュージックエディタ Music Editor
ミュージックを編集するモード Mode for editing Musics
38
0-7の8ミュージックが使用可能�8 Musics from 0 to 7 are available
最大4つのサウンドをミュージックとして同時に再生できる�Up to 4 sounds can be played as music simultaneously
ミュージックで使用するのは3音に留めて、�残りの1つは効果音の再生に使うのがおすすめ
It is recommended to use only three sounds for music, and use the other one for playing sound effects
本格的なゲームプログラミングの方法�Full-scale game programming method
39
ゲームの処理の流れ Game processing flow
40
入力情報の取得�Get input information
各要素の状態を更新�Update each element state
相互作用の処理�Process interactions
各要素を描画�Render each element
マウス、キーボード、ゲームパッド等�Mouse, keyboard, gamepad, etc.
プレイヤー、敵、弾、背景等�Player, enemies, bullets, background, etc.
衝突判定、ダメージ処理等�Collision detection, damage reaction, etc.
負荷が大きいとスキップする場合もある�It may be skipped if the load is large
Pyxelアプリケーションの雛形 Pyxel application template
41
import pyxel
class App:
def __init__(self):
pyxel.init(160, 120)
# 初期化処理 Initialization process
pyxel.run(self.update, self.draw)
def update(self):
# 更新処理 Update process
def draw(self):
# 描画処理 Render process
App()
init(画面幅, 画面高さ):指定した画面サイズでアプリを初期化する�init(width, height) : Initialize an application with the specified screen size
run(更新関数, 描画関数):アプリの実行を開始する�run(update, draw) : Start running the application
更新関数:run命令から一定時間(1/30秒)ごとに呼ばれる�update(self) : Called at regular intervals (1/30 sec) from the run command
描画関数:run命令から描画が必要な時に呼ばれる�draw(self) : Called when drawing is required from the run command
初期化処理の例 Initialization process example
42
class App:
def __init__(self):
pyxel.init(120, 160, caption="Pyxel Shooter")�
# 略 Ommited
self.scene = SCENE_TITLE
self.score = 0
self.background = Background()
self.player = Player(pyxel.width / 2, pyxel.height - 20)
pyxel.run(self.update, self.draw)
アプリケーション名をcaptionオプションで設定
Set application name with caption option
クラスのメンバ変数として必要な変数を初期化
Initialize necessary variables as class member
背景クラス、プレイヤークラスのインスタンスを生成・保持�Create and remember the Background class and the Player class instances
更新処理の例 Update process example
43
class Player:
def update(self):
if pyxel.btn(pyxel.KEY_LEFT):
self.x -= PLAYER_SPEED
if pyxel.btn(pyxel.KEY_RIGHT):
self.x += PLAYER_SPEED
# 略 Omitted
if pyxel.btnp(pyxel.KEY_SPACE):
Bullet(
self.x + (PLAYER_WIDTH - BULLET_WIDTH) / 2,
self.y - BULLET_HEIGHT / 2
)
pyxel.play(0, 0)
btn(key):keyが押されていたらTrue、押されていなければFalseを返す�btn(key) : Return True if key is pressed, otherwise return False
play(ch, snd, loop=False):チャンネルch(0-3) でサウンドsnd(0-63) を再生する
play(ch, snd, loop=False) : Play the sound snd(0-63) on channel ch(0-3)
btnp(key, [hold], [period]):そのフレームにkeyが押されたらTrue、押されなければFalseを返す�btnp(key, [hold], [period]) : Return True if key is pressed at that frame, otherwise return False
描画処理の例 Draw process example
44
class Player:
def draw(self):
pyxel.blt(self.x, self.y, 0, 0, 0, self.w, self.h, 0
class Blast:
def draw(self):
pyxel.circ(self.x, self.y, self.radius, BLAST_COLOR_IN)
pyxel.circb(self.x, self.y, self.radius, BLAST_COLOR_OUT)
class Bullet:
def draw(self):
pyxel.rect(self.x, self.y, self.w, self.h, BULLET_COLOR
自機はイメージバンクの画像をコピー�Copy a player image from the Image Bank
爆発は2つの円として描画
Draw two circles as a blast effect
弾は矩形として描画�Draw a rectangle as a bullet
ジャンルごとのポイント紹介 Key points for each genre
46
まとめ�Summary
47
Pyxelの今後 The future of Pyxel
48
本日のまとめ Today’s summary
49
ご清聴ありがとうございました!
Thank you for listening!
50