固定小数点で動かす

座標と速度に小数部を持たせて、1ピクセル未満の細かさでキャラクターを動かします。

なぜ小数部が必要か

座標を整数のピクセル単位だけで持つと、速度は「1フレームに1ピクセル」「2ピクセル」のように飛び飛びになります。ゆっくり加速する、重力で少しずつ落ちる、といった動きを作るには、1ピクセルより細かい単位(サブピクセル)が必要です。

ここでは、1ピクセルを256分割した単位を使います。

変数大きさ内容
$101バイトX座標の小数部(1/256ピクセル単位)
$11・$122バイトX座標の整数部(ピクセル)
$14・$152バイトX方向の速度(符号付き、1/256ピクセル単位)

$10~$12 を、1/256ピクセル単位の24ビットの値として扱います。

速度を座標に加える

速度は符号付きの16ビットなので、24ビットの座標に加えるときは、上位バイトを符号で埋めて(符号拡張して)加えます。

; X座標に速度を加える
    REP #$20
    CLC
    LDA $10
    ADC $14         ; 座標の下位16ビット + 速度
    STA $10
    SEP #$20
    LDA.b #$00
    BIT $15         ; 速度の符号(ビット7)を調べる
    BPL .plus
    DEC A           ; 負の速度なら上位バイトは$FF
.plus
    ADC $12         ; 繰り上がりと符号拡張した上位バイトを加える
    STA $12

LDA命令・BIT命令・DEC命令はキャリーフラグを変えないので、最初のADC命令の繰り上がりがそのまま最後のADC命令に渡ります。

加速と重力

速度にも小さな値を毎フレーム加えることで、加速や重力を表現します。

; Y方向の速度($18・$19)に重力を加え、最大の落下速度で止める
    REP #$20
    LDA $18
    CLC
    ADC.w #$0040    ; 1フレームに 0.25 ピクセル/フレーム ずつ加速
    BMI .store      ; 上昇中(負の速度)ならそのまま
    CMP.w #$0400    ; 最大の落下速度 4ピクセル/フレーム
    BCC .store
    LDA.w #$0400
.store
    STA $18

画面に表示する

スプライトのOAMに書くのは、整数部だけです。

    SEP #$20
    LDA $11
    SEC
    SBC $40         ; カメラのX座標を引いて、画面上の座標にする
    STA $0200       ; OAMの写しのX座標

参照

多倍長の加減算と比較
符号付きの値の扱い
スプライトを表示する