見出し画像

続々:pyxelでRPG風のものを作る(1)

久々にpyxelで以前作っていたRPGを引っ張り出してきて、いろいろといじってみました。前回からだいぶ時間が経ってしまったので、noteのタイトルも「続」から「続々」に変えて仕切り直しです。この間にpyxelの新バージョンが出たりしたので、そのあたりも絡めながら書いていきます。

前回までの進行具合は以下のnoteをご参照ください。

さて、前回一応ストーリーの区切りをつけたところで終わらせていましたが、その後pyxelの新バージョンが出ました。ところが、APIの使い方が変わっていたりで、ちょっとコードに互換性がなさそうだったのでこのRPGについては旧バージョンで作り続けることにして保留。
が、「やっぱり新しいバージョンで動かしたいなぁ」と思い、無理やり改造してしまいました。まずはそのお話からです。

さて、新旧のpyxelで一番違うのはタイルマップのデータの持たせ方。

▲この画像でカーソルを合わせてある2段目の石のタイル。これは以前のpyxelでは「32」という値で表されていました。

そのため、プレイヤーの移動時には下記のようなコードが出てきます。

if pyxel.tilemap(0).get(move_map_x, move_map_y-1) < 32:

▲移動先のタイルが32より小さかったら、というif文です。こういった形でタイルの種類を取得して、動作を分けていました。

新バージョンではタイルマップはタプルで持っています。

▲この石のタイルは(0, 1)のタプルです。(x, y)の順なので、1行目の0個目という意味ですね。順番が0から始まる点は注意です。

これによって、タイルの順番が劇的に追いやすくなりました。以前は0からの連番だったので、なかなか分かりにくかったのですが、とても便利なアップデートです。

ただし、コードとしては互換性がなくなってしまいました。

 def Tile_cnv(self, x, y):
     m1 = pyxel.tilemap(0).pget(x, y)
     m = m1[0] + (m1[1] * 32)         
     return m

▲というわけで無理やり変換用の関数を作りました。例えばさっきの石タイルはpyxel.tilemap(0).pgetで取得した際は(0, 1)という形になります。これを32に持っていくために、タプルの0個目はそのまま、1個目は×32して足すという力業で変換しています。(0, 1)は0+1×32=32ということでOK!

呼び出し部分も修正です。

if pyxel.tilemap(0).get(move_map_x, move_map_y-1) < 32:
↓
if self.Tile_cnv(move_map_x, move_map_y-1) < 32:

▲引数の形は合わせているので、pyxel.tilemap(0).getの部分を一括置換でできました。

これでタイルマップ取得部分は何とかなりました。
次はタイルマップを書き替えている部分です。

pyxel.tilemap(0).set(8+96, 8+96, ["005"]) 

▲元のコードはこんな感じです。タイルマップのsetは16進数でタイルを指定するのでこんな形でした。
新しいバージョンでも16進数であることは変わらないのですが、タプルのxy情報の形で指定しなければいけません。つまり、(1, 5)のタイルを指定したかったら、1を16進数にしたものと5を16進数にしたものをつなげて文字列化する、ということになります。この際最終的には4桁にしなければいけないので、xy部分は2桁になるように変換します。

なかなかややこしいですが完成した変換関数が以下のものです。

 def Tile_cnv_set(self, x, y, t):
     t0 = t[0]
     t1 = len(t0) + 1
     t2 = int(t1 / 3)
     
     for i in range(t2):
         s1 = i * 3
         s2 = s1 + 3
         tm = t0[s1:s2]    
         tm2 = int(tm, 16)
         tm3 = int(tm2 / 32)
         tm4 = int(tm2 % 32)
         tm5 = format(tm3, 'x')
         tm6 = format(tm4, 'x')
         tmy = str(tm5).zfill(2)
         tmx = str(tm6).zfill(2)
         print(tmx)
         print(tmy)
         pyxel.tilemap(0).set(x + i, y, [tmx + tmy])         

▲もともとのコードで16進数で指定していたのを生かそうとしたあまり、ごちゃごちゃになってしまいました。
流れとしては、

もともとの16進数でのタイルマップを引数として受け取る。

1つのタイルマップにつき3桁での指定だったので、3桁ごとに区切る。
以前は["005005006"]みたいな指定ができていました。これを005・005・006に分けます。

分けたタイル情報を10進数に変換。

32で割って何行目の何個目かを特定。

それぞれを16進数に変換し、2桁になるように0埋め。
文字列結合してタイルマップ書き換え。最終的には2桁+2桁で4桁になるように。

といった形です。だいぶややこしい。

pyxel.tilemap(0).set(8+96, 8+96, ["005"]) 
↓
self.Tile_cnv_set(8+96, 8+96, ["005"]) 

呼び出し部分も変えます。
書いてて思ったがほかにやり方なかったのか。

ただ、とにかくこれで新しいバージョンでも動くようなコードになりました。
この後pyxapp形式にしてスタンドアロン版で動かしたらセーブがうまく動かなくてまたごちゃごちゃやっていくわけですが、そのあたりは次回のnoteで書こうと思います。

コードやpyxresファイル、モジュールファイルはGitHubの方に置いてあります。

ここまで読んでいただきありがとうございました。

この記事が参加している募集

つくってみた

ここまで読んでいただきありがとうございます!