📄 snake.asm
字号:
;*****************************snake************************************
TRUE = 1
COLOR = 66 ;snake的颜色(0-255)
;**********************************************************************
;退出并还原用户的显示方式
exit macro
push ax
mov ah, 0h ;bios功能调用
mov al, vdMode
int 10h
mov ax, 4c00h
int 21h
pop ax
endm
;*********************************************************************
.model small
;*********************************************************************
.data
top db 42 dup(-1)
table db 25 DUP(-1, 40 DUP(0), -1)
bottom db 42 dup(-1)
row dw 0
column dw 0
head dw 675 ;指向snake头部
tail dw 673 ;指向snake尾部
vdMode db 0 ;保存用户的显示方式
bWait db 20 ;时间延迟 = 0.05s的倍数
key db 4dh ;保存从键盘输入的字符的扫描码
stay db 0 ;暂停标记
bkColor db 0 ;保存背景颜色
prompt db 0ah, 0dh, "****************************************",
0ah, 0dh, "*** pause: space ***",
0ah, 0dh, "*** exit: q(Q)/ESC ***",
0ah, 0dh, "****************************************",
0ah, 0dh, "Please enter A(easy)or B(common)or C(crazy): $"
;*********************************************************************
.code
main proc far
mov ax, @data
mov ds, ax
slt:
mov ah, 09h
mov dx, offset prompt
int 21h
mov ah, 01h
int 21h
.if (al=='A')||(al=='a')
mov bWait, byte ptr 20 ;延迟1s
.elseif (al=='B')||(al=='b')
mov bWait, byte ptr 10 ;延迟0.5s
.elseif (al=='C')||(al=='c')
mov bWait, byte ptr 5 ;延迟0.25s
.else
jmp slt
.endif
call initial
.while TRUE
next:
mov ah, 0bh ;DOS功能调用,检查是否按下键盘
int 21h
.if al
call getKey
.endif
.break .if (key==10h)||(key==01h) ;退出
.if stay ;暂停
jmp next
.endif
call setSnk
call waitf ;延迟bWait×0.5s
.endw
exit
main endp
;*********************************************************************
;从键盘读取字符,并保存扫描码在key
getKey proc near uses ax bx
mov ah, 0h ;bios功能调用,读取键盘
int 16h
mov al, key
.if ah == 48h ;上方向键
.if al != 50h
mov key, ah
.endif
.elseif ah == 4bh ;左方向键
.if al !=4dh
mov key, ah
.endif
.elseif ah == 4dh ;右方向键
.if al != 4bh
mov key, ah
.endif
.elseif ah == 50h
.if al != 48h
mov key, ah
.endif
.elseif (ah==10h)||(ah==01h) ;q(Q)或ESC退出
mov key, ah
.elseif ah == 39h ;space暂停或终止暂停
.if stay == 1
mov stay, byte ptr 0
.else
mov stay, byte ptr 1
.endif
.endif
ret
getKey endp
;*********************************************************************
;产生时间延迟 bWait × 0.05s
waitf proc near uses cx ax bx
mov bl, bWait
wait1:
mov cx, 3314
wait2:
in al, 61h
and al, 10h
cmp al, ah
je wait2
mov ah, al
loop wait2
dec bl
cmp bl, 0
ja wait1
ret
waitf endp
;*********************************************************************
;在数组(row, column)映射到的在屏幕上的区域画宽为8个像素的方块,al=方块的颜色
box proc near c uses ax bx cx dx si di
mov dx, row
mov bx, column
mov cl, 3
shl dx, cl
shl bx, cl
mov cx, bx
mov column, cx
mov si, 8
mov ah, 0ch ;bios功能调用,写像素
mov bh, 0
box1:
mov di, 8
box2:
int 10h
inc cx
dec di
cmp di, 0
ja box2
inc dx
mov cx, column
dec si
cmp si,0
ja box1
ret
box endp
;*********************************************************************
;初始化屏幕
initial proc near c uses ax bx cx dx
mov ah, 0fh ;bios功能调用,取用户显示方式并保存
int 10h
mov vdMode, al
mov ah, 0 ;bios功能调用,设置显示方式
mov al, 13 ;320×200 256色图形
int 10h
mov ah, 6 ;bios功能调用,清除屏幕
mov al, 0
mov bh, 255
mov cx, 0
mov dx, 184fh
int 10h
mov ah, 0dh ;bios功能调用,读像素的颜色
mov bh, 0
mov dx, 10
mov cx, 10
int 10h
mov bkColor, al
mov al, COLOR
mov bx, 673 ;42×14 +1
mov table[bx],byte ptr 3
mov row, word ptr 16
mov column, word ptr 0
call box
inc bx ;42×14 +2
mov table[bx], byte ptr 2
mov column, word ptr 1
call box
inc bx ;42×14 +3
mov table[bx], byte ptr 1
mov column, word ptr 2
call box
call rand
ret
initial endp
;*********************************************************************
;随机地产生一个方块
rand proc near uses ax bx dx di si
start_Rand:
mov ah, 0h ;bios功能调用,读系统时钟
int 1ah ;随机产生行
xor ah, ah
mov al, dl
mov dl, 25
div dl
mov al, ah
xor ah, ah
mov di, ax ;0~24
mov ah, 0h ;随机产生列
int 1ah
xor ah, ah
mov al, dl
mov dl, 40
div dl
mov al, ah
xor ah, ah
mov si, ax
mov ax, 42
mul di
mov bx, ax
add bx, si
inc bx
cmp table[bx], 0
jne start_Rand
mov table[bx], 200
mov row, di
mov column, si
mov al, COLOR
call box
ret
rand endp
;*********************************************************************
;当snake游动时,重新设置
setSnk proc near
mov bx, head
.if key == 48h ;上方向键
sub bx, 42
.elseif key == 4bh ;左方向键
sub bx, 1
.elseif key == 4dh ;右方向键
add bx, 1
.elseif key == 50h ;下方向键
add bx, 42
.endif
.if (table[bx]==-1)||((table[bx]>=2)&&(table[bx]<=150) )
mov key, 01h ;退出
ret
.elseif table[bx] == 0
call setBody
.elseif table[bx] == 200 ;吞食方块
call setEat
call rand
.endif
ret
setSnk endp
;*********************************************************************
;snake游动(不吞食方块)
setBody proc near uses ax bx cx dx
.if key == 48h
sub head, 42
.elseif key == 4bh ;左方向键
sub head, 1
.elseif key == 4dh ;右方向键
add head, 1
.elseif key == 50h ;下方向键
add head, 42
.endif
mov bx, head
mov table[bx], byte ptr 1
mov ax, bx
mov bl, 42
div bl
xor bh, bh
mov bl, al
mov row, bx
dec ah
mov bl, ah
mov column, bx
mov al, COLOR
call box
mov bx, tail
mov cl, table[bx] ;保存tail指向的值
mov table[bx], byte ptr 0
mov ax, bx
mov bl, 42
div bl
xor bh, bh
mov bl, al
mov row, bx
dec ah
mov bl, ah
mov column, bx
mov al, bkColor
call box
dec cl
mov bx, tail
sub bx, 42
.if cl == table[bx]
inc table[bx]
mov tail, bx
jmp endTail
.endif
mov bx, tail
dec bx
.if cl == table[bx]
inc table[bx]
mov tail, bx
jmp endTail
.endif
mov bx, tail
inc bx
.if cl == table[bx]
inc table[bx]
mov tail, bx
jmp endTail
.endif
mov bx, tail
add bx, 42
.if cl == table[bx]
inc table[bx]
mov tail, bx
.endif
endTail:
xor ch, ch
dec cl
mov dx, tail
nextSet:
mov bx, dx
sub bx, 42
.if cl == table[bx]
inc table[bx]
mov dx, bx
jmp set1
.endif
mov bx, dx
dec bx
.if cl == table[bx]
inc table[bx]
mov dx, bx
jmp set1
.endif
mov bx, dx
inc bx
.if cl == table[bx]
inc table[bx]
mov dx, bx
jmp set1
.endif
mov bx, dx
add bx, 42
.if cl == table[bx]
inc table[bx]
mov dx, bx
jmp set1
.endif
set1:
loop nextSet
ret
setBody endp
;*********************************************************************
setEat proc near uses ax bx cx dx
mov bx, tail
xor ch, ch
mov cl, table[bx]
mov bx, head
eatNext:
inc table[bx]
mov ah, table[bx]
mov dx, bx
sub bx, 42
.if ah == table[bx]
mov dx, bx
jmp eat
.endif
mov bx, dx
sub bx, 1
.if ah == table[bx]
mov dx, bx
jmp eat
.endif
mov bx, dx
add bx, 1
.if ah == table[bx]
mov dx, bx
jmp eat
.endif
mov bx, dx
add bx, 42
.if ah == table[bx]
mov dx, bx
jmp eat
.endif
eat:
loop eatNext
.if key == 48h
sub head, 42
.elseif key == 4bh
dec head
.elseif key == 4dh
inc head
.elseif key == 50h
add head, 42
.endif
mov bx, head
mov table[bx], 1
ret
setEat endp
;*********************************************************************
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -