メインコンテンツへスキップ
見出し画像

続々: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の方に置いてあります。

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

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

     
     
    出版社のしがない社内SE。 ここでは主に趣味のプログラミングやゲーム制作について書いています。作ったゲームは https://koidemizu.github.io/ で公開しているのでよかったら遊んでください。 ゲーム大好きインドア派。

    あなたへのおすすめ