Pyxel タイルより大きなキャラクターを動かす

プレイヤーキャラクターを大きなサイズにしたい

 以前の記事で,Python向けレトロゲームエンジン「Pyxel(ピクセル)」を使ってキャラクターがジャンプするゲームを作りました。
 kinutani.hateblo.jp

 タイルマップで作成したステージ上をプレイヤーキャラクターが移動する際,壁や床の判定としてキャラクターの四隅の座標を調べる方法を紹介しましたが,例ではプレイヤーキャラクターも8ドット×8ドットのサイズに収まる大きさでした。
 動かすキャラクターのドット絵のサイズを大きくしたい人もいるかと思いますが,単純に表示と壁判定の座標を変えただけだと,1マスの壁や床のタイルをすり抜ける問題が出てきますので,参考までに対応方法を紹介します。

 

描画するキャラクターのサイズを変える

 「Pyxel タイトル画面とゲーム画面を作る - 勉強ボックス管理者ブログ」からの変更例を示します。まずは,リソースファイルのドット絵を大きなものにしました。(例では幅12ドット,高さ16ドット。イメージバンク(0)の(0,32)が左上です)
 

 表示する部分の変更

pl_u = 0
pl_v = 32
pl_w = 12
pl_h = 16
・・・
def draw():
  ・・・
        # プレイヤーを表示
        pyxel.camera(scroll_x,scroll_y)
        # pyxel.blt( x, y, 0,  0, 8, pldir*8,8, 3)
        pyxel.blt( x, y, 0,  pl_u,pl_v, pldir*pl_w,pl_h, 3)    # 座標と幅と高さを変更

 

判定処理の失敗例

 chkwall()関数で判定する座標を,大きな絵の四隅の座標に変更してみます。

# chkpoint = [(2,0),(6,0),(1,7),(6,7)]
chkpoint = [(0,0),(11,0),(0,15),(11,15)]     # 四隅の座標を大きなものに変更 
def chkwall(cx,cy):

 実行結果
 
 キャラクターが壁タイルをすり抜けてしまいました。

 

改善案

 壁判定を行う座標のすき間が,タイルより大きなことが問題なので,座標の間を小さくします。

# chkpoint = [(2,0),(6,0),(1,7),(6,7)]
# chkpoint = [(0,0),(11,0),(0,15),(11,15)]     # 四隅の座標を大きなものに変更 
chkpoint = [(0,0),(5,0),(11,0),
            (0,7),(11,7),
            (0,15),(5,15),(11,15)]     # 中間点も判定する
def chkwall(cx,cy):

 実行結果
 
 すり抜けを防げるようになりました。
 ※わかりやすくするため一番外側の座標にしましたが,必要に応じて位置を調整してください。


 【補足】キャラクターの当たりの範囲を矩形(くけい 長方形のこと)で設定して,辺の上をタイルサイズごとにチェックしていく処理にすれば中間点のデータを準備する必要がなくなります。

 

ゴールタイル判定部分の変更

 キャラクターの中央の座標で判定していた,ゴールタイルとNGタイルもサイズ変更に対応させる必要があります。

    # タイルマップ判定
    for cpx,cpy in chkpoint:
        xi = (x + cpx)//8
        yi = (y + cpy)//8
        tile = pyxel.tilemap(stage_tm).pget(xi,yi)
        if (1,1) == tile :   # 得点アイテム
            score_tmp += 1
            pyxel.tilemap(stage_tm).pset(xi,yi,(0,0))
            item_list.append((xi,yi,tile)) # 消したアイテムを記録
        elif (2,1) == tile:   # ゴール
            ret = SNO_SFINISH
        elif (2,0) == tile or (3,0) == tile:    # NGタイル
            ret = SNO_GAMEOVER

元のコードでは,NGタイルとの判定を甘くしようという意図でキャラクターの中央の座標で判定させていました。判定個所を増やしても良かったのですが,コイン判定の chkpoint のループに入れる形での対応としました。

 

キャラクターの大きさを使用している処理の修正

 キャラクターの幅と高さが8ドットであることを前提に作成している処理は,新しいサイズに対応させる必要があります。
 こういった改造の際に,ソースコード上で直接 8 という数値で記述してあるよりも,変数名で player_width ,player_height などと記述してあるほうが修正箇所がわかりやすくなります。

・・・
# RIGHT_BORDER = pyxel.width - 48
RIGHT_BORDER = pyxel.width - 40 - pl_w
・・・
def chkwall(cx,cy):
    c = 0
    #  if cx < stage_x or stage_width -8 < cx:
    if cx < stage_x or stage_width -pl_w < cx:
        c = c + 1
    #  if stage_height -8 < cy: # 画面下に行かない設定
    if stage_height -pl_h < cy: # 画面下に行かない設定
・・・

 
 タイルより大きなキャラクターを動かすときの注意点と対応例の紹介は以上です。

 

関連記事

 kinutani.hateblo.jp