LoginSignup
4
2

More than 1 year has passed since last update.

Z80アセンブラで書いたインベーダー

Last updated at Posted at 2023-02-03

CHATGPTでインベーダーゲームを書かせてみた。
イメージ的には、インベーダーが体当たりで降りてくるイメージだが、ソース的には十分な内容だった。
玉を発射したりするルーチンは無いけど、たぶんココからちょっと指示しただけで、追加してくれると思う。
なんか妙に懐かしく、PC8001のゲームが作りたくなってきた。

; インベーダーゲーム
; Z80アセンブラで書いたサンプルプログラム

org	100h

; スタートアップルーチン
startup:
	ld	a,#0
	ld	(score),a	; スコアをゼロに設定
	ld	(lives),a	; 残機をゼロに設定
	call	init		; 初期化
	call	play		; ゲーム開始
	jp	finish		; 終了

; 初期化ルーチン
init:
	ld	a,#20		; 画面の幅を20文字に設定
	ld	(width),a
	ld	a,#16		; 画面の高さを16行に設定
	ld	(height),a
	call	clear_screen	; 画面を消去
	call	create_ship	; 自機を作成
	call	create_invader	; インベーダーを作成
	jp	startup		; スタートアップに戻る

; 画面を消去するルーチン
clear_screen:
	ld	hl,#0000h	; 画面の先頭アドレスを設定
	ld	bc,#4000h	; 画面サイズを設定
	ld	a,#20h		; 画面を消去するためのデータ
	ldir			; 全てを20hで埋め尽くす
	jp	startup		; スタートアップに戻る

; 自機を作成するルーチン
create_ship:
	ld	hl,#4000h	; 画面の底端をHLに設定
	ld	(ship_pos),hl	; 自機の座標を記憶
	ld	a,#0fh		; 自機を作成するためのデータ
	ld	(hl),a		; 自機を画面に描画
	jp	startup		; スタートアップに戻る

; インベーダーを作成するルーチン
create_invader:
	ld	hl,#0000h	; 画面の先頭アドレスをHLに設定
	ld	a,#0eh		; インベーダーを作成するためのデータ
	ld	(hl),a		; インベーダーを画面に描画
	jp	startup		; スタートアップに戻る

; ゲームを開始するルーチン
play:
	call	draw_screen	; 画面を描画
	call	control		; 操作を受け付ける
	call	move_ship	; 自機を動かす
	call	move_invader	; インベーダーを動かす
	call	check_collision	; 衝突をチェックする
	call	check_end	; ゲーム終了をチェックする
	jp	play		; 繰り返す

; 画面を描画するルーチン
draw_screen:
	ld	hl,#0000h	; 画面の先頭アドレスをHLに設定
	ld	bc,#4000h	; 画面サイズを設定
	ldir			; 画面を描画
	jp	startup		; スタートアップに戻る

; 操作を受け付けるルーチン
control:
	in	a,(#00h)	; キー入力を受け取る
	cp	#01h		; 左キーが押されたかチェック
	jp	z,move_left	; 押されていたら左に移動
	cp	#02h		; 右キーが押されたかチェック
	jp	z,move_right	; 押されていたら右に移動
	jp	startup		; スタートアップに戻る

; 左に移動するルーチン
move_left:
	ld	a,#0fh		; 自機を消去するためのデータ
	ld	(ship_pos),a	; 自機を消去
	dec	hl		; 左に1文字移動
	ld	(ship_pos),hl	; 自機の座標を記憶
	ld	a,#0fh		; 自機を作成するためのデータ
	ld	(hl),a		; 自機を描画
	jp	startup		; スタートアップに戻る

; 右に移動するルーチン
move_right:
	ld	a,#0fh		; 自機を消去するためのデータ
	ld	(ship_pos),a	; 自機を消去
	inc	hl		; 右に1文字移動
	ld	(ship_pos),hl	; 自機の座標を記憶
	ld	a,#0fh		; 自機を作成するためのデータ
	ld	(hl),a		; 自機を描画
	jp	startup		; スタートアップに戻る

; インベーダーを動かすルーチン
move_invader:
	ld	a,(inv_pos)	; インベーダーの座標を取得
	ld	hl,a		; HLに設定
	ld	a,#0eh		; インベーダーを消去するためのデータ
	ld	(hl),a		; インベーダーを消去
	inc	hl		; インベーダーを1文字右へ移動
	ld	(inv_pos),hl	; インベーダーの座標を記憶
	ld	a,#0eh		; インベーダーを作成するためのデータ
	ld	(hl),a		; インベーダーを描画
	jp	startup		; スタートアップに戻る

; 衝突をチェックするルーチン
check_collision:
	ld	a,(ship_pos)	; 自機の座標を取得
	cp	(inv_pos)	; インベーダーの座標をチェック
	jp	z,game_over	; 衝突したらゲームオーバー
	jp	startup		; スタートアップに戻る

; ゲームオーバー時の処理
game_over:
	dec	(lives)		; 残機を減らす
	ld	a,(lives)	; 残機を取得
	or	a		; 残機がゼロかチェック
	jp	z,finish	; ゼロなら終了
	call	create_invader	; インベーダーを再作成
	jp	startup		; スタートアップに戻る

; ゲーム終了をチェックするルーチン
check_end:
	ld	hl,#4000h	; 画面の底端をHLに設定
	ld	a,(inv_pos)	; インベーダーの座標を取得
	cp	hl		; 画面の底端と比較
	jp	nc,startup	; 画面の底端以外ならスタートアップに戻る
	inc	(score)		; スコアを1増やす
	call	create_invader	; インベーダーを再作成
	jp	startup		; スタートアップに戻る

; 終了ルーチン
finish:
	halt			; プログラムを終了

; 変数定義
score	defb	00h	; スコア
lives	defb	00h	; 残機
width	defb	20h	; 画面の幅
height	defb	16h	; 画面の高さ
ship_pos	defw	0000h	; 自機の座標
inv_pos	defw	0000h	; インベーダーの座標

end
4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2