見出し画像

MSX マシン語でスプライトを動かす 序章

前回記事ではMSXでの入力について学習しました。今回記事ではスプライトを実際に動かしてみます。
今回から条件分岐がバシバシ出てきます。
・・といいつつ、今回記事では伝えることが山ほどあるので当記事ではGitHubのサンプルだけ紹介します。

https://github.com/sailorman-msx/games/tree/main/src/sample007


予習:ここを読んでおくといいですよ

次回記事ではもっと詳しく説明しますが、事前の予習としてはこのへんを読んでおくといいです。という箇所だけ紹介します。
まずはinitialize.asm

; スプライト座標格納用
WK_PLAYERPOSX:equ $D003     ; 1バイト(0-31)
WK_PLAYERPOSY:equ $D004     ; 1バイト(0-23)
WK_PLAYERPOSXOLD:equ $D005  ; 1バイト(0-31)
WK_PLAYERPOSYOLD:equ $D006  ; 1バイト(0-23)

WK_PLAYERDIST:equ $D007     ; 1バイト(プレイヤーの向き:1=上,5=下,7=左,3=右)

; ワーク用スプライトアトリビュートテーブル
; スプライトを表示させるために、いったんこのワークテーブルを
; 作成してからLDIRVMでVRAMに一括転送する
WK_PLAYERSPRATTR:equ $D008   ; 8バイト(スプライト2枚分)
WK_PLAYERSPRCLR1:equ $D010 ; 1バイト(スプライト1枚目)
WK_PLAYERSPRCLR2:equ $D011 ; 1バイト(スプライト2枚目)

変数がたくさん増えました。動かすにあたって重要なのが上半分。
下半分はスプライトを表示させるための変数になっています。

data_sprite.asm
今回は4方向(上下左右)のキャラクタパターンを作りました。
SPRDISTPTN_TBLがミソです。

sprite.asm
いくつかのサブルーチンを追加しています。

;------------------------------------------------
; SUB-ROUTINE: MovePlayer
; Aレジスタに格納されている情報から
; 方向を特定してプレイヤーのスプライトを移動させる
;------------------------------------------------
MovePlayer:
;--------------------------------------------
; SUB-ROUTINE: UndoMove
; 移動範囲外に移動した場合は表示位置を元に戻す
;--------------------------------------------
UndoMove:
;--------------------------------------------
; SUB-ROUTINE: CreateWorkSpriteAttr
; ワーク用スプライトアトリビュートテーブルを
; 作成する
;
; IXレジスタ:SPRDISTPTN_TBLのポインタ
; をセットしてから呼び出すこと
;
; CreateWorkSpriteAttr
;   |
;   v
; PutSprite
;
; の順で処理を行うこと
;--------------------------------------------
CreateWorkSpriteAttr:

PutSpriteサブルーチンは前回とかなり変更しています。
最後にsample007.asm。

MainLoop:

    call DelayLoop

    ;--------------------------------------------
    ; 入力を受け付ける
    ;--------------------------------------------
    ; キーボードバッファをクリアする
    ; これを呼び出さないとカーソルキーを正常に判定できない
    call KILBUF

    ; JOY STICK(またはカーソルキー)の方向を取得
    ; Aレジスタに方向がセットされる
    ld a, 0
    call GTSTCK

    ;--------------------------------------------
    ; ジョイスティックが押されたら移動処理を呼ぶ
    ;--------------------------------------------
    ; Aレジスタに0OR演算する
    ; ジョイスティックが押されるとAレジスタの
    ; 値には0より大きい値が入るためOR演算の結果はゼロにならない
    or 0
    jr z, MainEnd

    ;--------------------------------------------
    ; プレイヤーの移動
    ; 移動は8ドット単位で移動する
    ; X座標は1-29まで
    ; Y座標は1-21まで
    ; の範囲だけ移動可能とする
    ;--------------------------------------------
    call MovePlayer

    call DebugPrint

MainEnd:

    jr MainLoop

今回のサンプルではジョイスティック(というかカーソルキー)だけを対応にしています。

下に動いたり
左に動いたり
上に動いたりするよ!

次回から「プログラムらしいプログラム」の解説になります。

では、また!

セーラー服が似合うおじさんです。猫好き、酒好き、ガジェット好き、楽しいことならなんでも好き。そんな「好き」をつらつらと書き留めていきます。