目的
以下の3枚のドット絵を交互に描画して歩いているように見せます。
本来のゲームはスプライトとして描画しないといけませんが、一旦背景として描画しています。
用意したドット絵
tile.asm
tile.asm
hero:
; 主人公正面右足前進
hero_down_right_foot:
db %00000000, %00000000
db %00000111, %00000111
db %00001111, %00001000
db %00011111, %00010000
db %00011111, %00010000
db %00111100, %00111000
db %00111111, %00111111
db %01010000, %01010000
db %00000000, %00000000
db %11100000, %11100000
db %11110000, %00010000
db %11111000, %00001000
db %11111000, %00001000
db %00111100, %00011100
db %11111100, %11111100
db %00001010, %00001010
db %01000010, %01000010
db %01110010, %01110010
db %01011001, %01011000
db %00111111, %00111111
db %00011111, %00011011
db %00011111, %00011110
db %00001111, %00001001
db %00000111, %00000111
db %01000010, %01000010
db %01001100, %01001100
db %10011100, %00010100
db %11110100, %11110100
db %11001100, %11001100
db %11001100, %01001100
db %10111000, %10111000
db %00000000, %00000000
; 主人公正面静止
hero_down_idle:
db %00000111, %00000111
db %00001111, %00001000
db %00011111, %00010000
db %00011111, %00010000
db %00111000, %00111000
db %00110111, %00110111
db %01010000, %01010000
db %01000010, %01000010
db %11100000, %11100000
db %11110000, %00010000
db %11111000, %00001000
db %11111000, %00001000
db %00111100, %00011100
db %11101100, %11101100
db %00001010, %00001010
db %01000010, %01000010
db %00110010, %00110010
db %00111001, %00111000
db %01001111, %01001111
db %01001111, %01001111
db %00111111, %00111001
db %00011110, %00010110
db %00011111, %00010001
db %00001110, %00001110
db %01001100, %01001100
db %10011100, %00011100
db %11110010, %11110010
db %11110010, %11110010
db %11111100, %10011100
db %01111000, %01101000
db %11111000, %10001000
db %01110000, %01110000
; 主人公正面左足前進
hero_down_left_foot:
db %00000000, %00000000
db %00000111, %00000111
db %00001111, %00001000
db %00011111, %00010000
db %00011111, %00010000
db %00111100, %00111000
db %00111111, %00111111
db %01010000, %01010000
db %00000000, %00000000
db %11100000, %11100000
db %11110000, %00010000
db %11111000, %00001000
db %11111000, %00001000
db %00111100, %00011100
db %11111100, %11111100
db %00001010, %00001010
db %01000010, %01000010
db %00110010, %00110010
db %00111001, %00101000
db %00101111, %00101111
db %00110011, %00110011
db %00110011, %00110010
db %00011101, %00011101
db %00000000, %00000000
db %01000010, %01000010
db %01001110, %01001110
db %10011010, %00011010
db %11111100, %11111100
db %11111000, %11011000
db %11111000, %01111000
db %11110000, %10010000
db %11100000, %11100000
ソース
main.asm
SECTION "Entry", ROM0[$0100]
jp start
SECTION "Main", ROM0[$0150]
INCLUDE "tile.asm"
start:
di ; 割り込み禁止
ld sp, $FFFE ; スタック設定
call display_off
; 画面クリア
call bj_clear
; パレット
ld a, %11100100 ; 4色(11 10 01 00)を設定
ld [$FF47], a
; 主人公タイル右足+静止+左足 16×16×3個読み込む
ld hl, hero
ld de, $8000
ld bc, 16*12
call memcpy
main_loop:
; 主人公正面右足前進
ld hl, $9800
ld a, 0
call set_tile1616
call display_on
call delay
call display_off
; 主人公正面静止
ld hl, $9800
ld a, 4
call set_tile1616
call display_on
call delay
call display_off
; 主人公正面左足前進
ld hl, $9800
ld a, 8
call set_tile1616
call display_on
call delay
call display_off
; 主人公正面静止
ld hl, $9800
ld a, 4
call set_tile1616
call display_on
call delay
call display_off
jr main_loop
hang:
jr hang
; 画面描画停止
display_off:
xor a
ldh[$FF40], a
ret
; 画面描画再開: BG有効
display_on:
ld a, %10010001
ldh [$FF40], a
ret
; メモリ複製関数
; HL=元, DE=先, BC=長さ
memcpy:
ld a, [hl]
ld [de], a
inc hl
inc de
dec bc
ld a, b ; B==CならBC==0 (B==$FF,C==$FFの時は失敗する)
or c
jr nz,memcpy ; BC!=0なら繰り返す
ret
; 16*16のタイル(4つ分)を表示する
; HL VRAM
; A 開始タイル番号(連続して配置する前提)
set_tile1616:
; 左上
ld [hl], a
; 右上
inc hl
inc a
ld [hl], a
; 左下
ld bc, 31
inc a
add hl, bc
ld [hl], a
; 右下
inc hl
inc a
ld [hl], a
ret
; 画面全体にタイル255(真っ白)を登録する
; メモリは初めから0で初期化されているのでタイル255を故意に書き換え無ければ全て0
bj_clear:
ld bc, 32*32
ld hl, $9800
loop1:
ld [hl],255
inc hl
dec bc
ld a, b
or c
jr nz, loop1
ret
; 遅延
delay:
ld bc, $AFFE
loop2:
dec bc
ld a, b
or c
jr nz, loop2
ret