主にMSX関係のコンテンツが置いてあります。

1セクタゲーム作成に挑戦-7

取り敢えず、ゲームとして成り立つ部分まで組んでみました。

ただしこれでコードは647バイト。135バイトの超過です。

ソース(クリックで展開)
; 1secgame
;ワークエリア-------------------------------------------------------------------
exptbl: equ 0fcc1h ;main romのスロット
forclr: equ 0f3d9h ;前景色
bakclr: equ 0f3eah ;背景色
bdrclr: equ 0f3ebh ;周辺色
csry: equ 0f3dch ;カーソルy座標
csrx: equ 0f3ddh ;カーソルx座標
cliksw: equ 0f3dbh ;クリック音スイッチ
;bios---------------------------------------------------------------------------
calslt: equ 001ch ;スロットの指定アドレスをコール iy,ix
chgmod: equ 005fh ;スクリーンモード変更
;a=モード
;forclr=前景色
;bakclr=背景色
;bdrclr=周辺色
filvrm: equ 0056h ;vramを埋める hl=アドレスbc=長さa=データ
setwrt: equ 0053h ;vramアドレスセット hl=アドレス
wrtvrm: equ 004dh ;vram書き込み hl=アドレス a=データ
rdslt: equ 000ch ;スロットの指定アドレスを読む
;hl=アドレス a=読み込み値
enaslt: equ 0024h ;スロット切り替え
ldirvm: equ 005ch ;vramへブロック転送hl=メモリ,de=vram,bc=長さ
chput: equ 00a2h ;1文字表示,a=文字
gttrig: equ 00d8h ;トリガチェック
cls: equ 00c3h ;画面クリア
wrtvdp: equ 0047h ;vdp書き込み,c=レジスタ,b=データ
;-------------------------------------------------------------------------------
org 9000h

start: ;screen1:color15,1,12

ld a,15
ld (forclr),a
ld a,12
ld (bdrclr),a
xor a
ld (cliksw),a
inc a
ld (bakclr),a
call chgmod ;screen1:color15,1,12

;vramスプライト定義
ld hl,spplayer
ld de,3800h
ld bc,8*3
call ldirvm

;メインルーチン
mainst: call init

loop: call playersub
call obsocc
call obsomv
call putsprite
call scput
ld c,1
call scinc
in a,(099h)
and 00100000b
jr z,loop
jp gameover
;得点-----------------------------------------------------------
scput: ld hl,0101h
ld (csry),hl
ld hl,scstr
all print
ld b,4
ld hl,score
ld a,30h
scput0: rld
call chput
rld
call chput
rld
inc hl
djnz scput0
ret
;得点加算--------------------------------------------------------
scinc: ld b,4
ld hl,score+3
or a
scinc0: ld a,(hl)
adc a,c
daa
ld (hl),a
ld c,0
dec hl
djnz scinc0
ret
;障害物発生-----------------------------------------------------
obsocc: ld a,(obscnt)
dec a
jr z,obso0
ld (obscnt),a
ret
obso0: ;次の障害物発生までのカウント作成
rnd: ld a,0
ld b,a
add a,a
add a,a
add a,b
add a,b
add a,b
ld b,a
ld a,r
add a,b
ld (rnd+1),a
and 00001111b
add a,8
ld (obscnt),a ;次の発生のカウンタ
and 00000011b
ld b,a

;発生箇所算出
ld a,(ply + 1)
srl a
srl a
srl a

sub b
jr nc,obso1
xor a
obso1: ld (obso2+1),a
ld e,a
ld d,0
ld hl,sccnt
add hl,de ;hl=ラインカウンタ
ld a,(hl)
cp 3
ret nc
inc (hl)
;スプライト空き探す
ex de,hl ;de=ラインカウンタ
ld b,25
ld ix,obstw
obso3: ld a,(ix+1) ;yh
cp 209
jr z,obso2
push de
ld de,6
add ix,de
pop de
djnz obso3
ret
obso2: ld a,0
sla a
sla a
sla a
ld (ix+1),a ;yh
ld (ix+2),0 ;xl
ld (ix+3),255 ;xh
ld (ix+4),e ;addrl
ld (ix+5),d ;addrh
ret

;障害物移動-----------------------------------------------------
obsomv: ld b,25
ld ix,obstw
obsm0: ld a,(ix+1) ;yh
cp 209
jr nz,obsm1
obsm2: ld de,6
add ix,de
djnz obsm0
ret
obsm1: ld l,(ix+2) ;xl
ld h,(ix+3) ;xh
ld de,0280h
or a
sbc hl,de
ld (ix+2),l ;xl
ld (ix+3),h ;xh
jr nc,obsm2
;消去
ld (ix+1),209 ;yh
ld l,(ix+4) ;addrl
ld h,(ix+5) ;addrh
dec (hl)
jr obsm2
;プレイヤー処理-------------------------------------------------
playersub: xor a
call gttrig
ld b,a
ld a,(ploldt)
xor b
ld a,b
ld (ploldt),a
jr z,psub0
ld a,b
or a
jr z,psub0
;ジャンプ処理
ld a,(pljc)
cp 3
jr nc,psub0
inc a
ld (pljc),a
ld (plmd),a
;ジャンプ初期化
ld hl,(plxz)
ld bc,plxzval
add hl,bc
ld (plxz),hl
ld hl,plyzinival ;=-6.0
ld (plyz),hl

psub0: ;x座標処理
ld hl,(plx)
ld de,(plxz)
add hl,de
ld (plx),hl
;座標チェック
ld a,h
cp plxline
jr c,psub3
ld hl,plxline << 8
ld (plx),hl

;動作確認
psub3: ld a,(plmd)
or a
jr nz,jump
;走り
ld a,(plc)
dec a
ld (plc),a
ret nz
ld a,plcval
ld (plc),a

ld a,(plp)
xor 1
ld (plp),a
ret

jump: ;y座標処理
ld hl,(ply)
ld de,(plyz)
add hl,de
ld a,h
cp 210
jr c,psub1
ld hl,0 ;天井に付いた
psub1: ;座標チェック
ld a,h
cp plgline
jr c,psub2
;着地
xor a
ld (plmd),a ;動作=走り
ld (pljc),a ;ジャンプカウンタ0
ld hl,plxzinival ;x増分初期値
ld (plxz),hl
ld hl,plgline << 8
psub2: ld (ply),hl
;増分処理
ex de,hl
ld de,plyzval ;増分変化量
add hl,de
ld (plyz),hl
ret
;ゲームオーバー処理---------------------------------------------
gameover: ld a,10
ld (csry),a
ld a,12
ld (csrx),a
ld hl,gmovr
call print
ld b,10
call wait
govr0: xor a
call gttrig
or a
jr z,govr0
govr1: xor a
call gttrig
or a
jr nz,govr1
call 00c3h
jp mainst
;初期化--------------------------------------------------------
init: ;0埋め
ld hl,ply
ld (hl),0
ld de,ply+1
ld bc,workend - ply - 1
ldir
;座標初期化
ld b,30
ld hl,obstw
initl0: ld (hl),0 ;y座標下位
inc hl
ld (hl),209 ;y座標上位
inc hl
ld (hl),0 ;x座標下位
inc hl
ld (hl),0 ;x座標上位
inc hl ;sccnt
inc hl ;sccnt
inc hl
djnz initl0
;プレイヤー状態初期化
ld hl,0000h ;x=0
ld (plx),hl
ld hl,plgline << 8 ;y=120
ld (ply),hl
ld a,plcval
ld (plc),a

ld hl,plxzinival ;x増分初期値
ld (plxz),hl
ld hl,plyzinival ;y増分初期値
ld (plyz),hl
ret
;---------------------------------------------------------------
;キャラクタ全表示
putsprite: ld hl,1b00h
ld de,ply
ld c,11
ld a,(plp)
ld b,a
call putsp

ld b,30
putsplp: push bc
ld b,2
ld c,6
call putsp
inc de
inc de
pop bc
djnz putsplp
ret

;---------------------------------------------------------------
;スプライト表示
;hl=vramアドレス,de=ワーク座標y,c=カラー,b=パターン
;x座標がマイナスか256以上なら表示しない
putsp: inc de
ld a,(de) ;y上位
inc de
inc de
call wrtvrm ;y座標書き込み
inc hl
ld a,(de)
inc de
call wrtvrm ;x座標書き込み
inc hl
ld a,b
call wrtvrm ;パターン書き込み
inc hl
ld a,c
call wrtvrm ;色書き込み
inc hl
ret

;wait-----------------------------------------------------------
wait: ;b=ウエイト数 1/60単位
waitl0: halt
djnz waitl0
ret
;文字列表示-----------------------------------------------------
;hl=文字列アドレス
print: ld a,(hl)
inc hl
cp '$' ;終端文字
ret z
call chput
jr print

;文字列データ
gmovr: dm 'GAME OVER$'
scstr: dm 'SCORE $'

;障害物グラフィックパターン
spplayer: db 0fch,7eh,6ah,0e0h,0feh,7fh,7ch,82h
spplayer1: db 0fch,7eh,6ah,60h,0ffh,0feh,7ch,14h
spobst: db 3ch,42h,8dh,85h,0c1h,0b1h,42h,3ch
codeend:
codesize: equ codeend - start
;ゲーム用ワーク-----------------------------------------------------------------
ply: dw 0
plx: dw 0
obstw: ds 6*30 ;y=dw,x=dw,add=dw

plxz: dw 0 ;プレイヤーx座標増分
plxzinival: equ 0001h ;プレイヤーx座標増分初期値
plxzval: equ 0010h ;プレイヤーx座標増分変化量
plyz: dw 0 ;プレイヤーy座標増分
plyzinival: equ 0fa00h ;プレイヤーy座標増分初期値
plyzval: equ 0080h ;プレイヤーy座標増分変化量
plp: db 0 ;パターン
plmd: db 0 ;プレイヤー動作:0=走り,0以外=ジャンプ
pljc: db 0 ;プレイヤージャンプ回数
plc: db 0 ;アニメカウンタ
plcval: equ 4 ;アニメカウンタ設定値
ploldt: db 0 ;1つ前のトリガ状態,0=押されていない,255=押されている
plgline: equ 120 ;プレイヤー地面座標
plxline: equ 216 ;プレイヤー最右座標
obscnt: db 0 ;障害物カウンタ
sccnt: ds 24
score: ds 4
workend:

障害物をジャンプで避け、ゲームオーバーになるまでの得点を競う。そんなゲームになりました。

この状態から、コードの縮小とゲームとしての調整、それとバグ取りを行います。

果たして135バイト削り切れるのか。

あと、このコードにはバグがありまして、それは以下の動画の通りです。

これの原因究明と対策も考えなければいけません。