📄 snake.asm
字号:
;************************************************************************************************
; SNAKE 1.0 by Hotou 2005 CopyRight (C) Detective *
; Compile by Tasm v3.0 *
; *
; This is a snake game.Play it with the cross key on the keyboard. *
; I whrite this for the work of ASM course in Tianjin University. *
; This version is commpleted on 30-08-2005 at home. *
; *
; Blog: http://hotou.blogchina.com/ *
; Web: http://hotou.vicp.net/ *
; E-mail: http://ehotou@hotmail.com/ *
;************************************************************************************************
; 所有子程序列表
; show_start_msg 显示开始提示信息
; Cutsnake 显示蛇一段
; Cutfood 显示食物
; Clearcut 清除格
; Hetfood 产生新食物
; Check_key 处理键盘响应
; Check_die 处理死亡的响应
; Check_eat 处理吃到食物的响应
; Show_point 打印分数(进制转换)
; Run_snake 蛇运动
; Init_snake 蛇初始化
; Clear_area 清空游戏区域
; Show_title 打印游戏标题
; HLine 画横线函数
; VLine 画竖线函数
; Rec 画无填充矩形
; SetGb 设置光标位置
; Msg 显示字符串
; Rand 产生随机数
;******************************************************************************************
.model small
;******************************************************************************************
.stack 200
;******************************************************************************************
.data
;蛇的参数以及游戏参数
Len db 5 ;蛇的长度
Life db 1 ;蛇的生命
Body dw 200 dup(0) ;蛇的身体位置
Direction dw 256 ;(0,1)(O,-1)(1,0)(-1,0)
Score db 'Score00000' ;得分
snake_color db 09 ;蛇颜色
speed db 0 ;速度
gameover db 0 ;游戏结束标记
Point db 0 ;得分数
food_color db 04 ;食物色
foodX dw ? ;食物坐标
foodY dw ?
seed dw 200 ;随即数种子
num1 dw 4
num3 dw 3
;******************************************************************************************
;显示方面的参数
topline dw 20 ;上边界
leftline dw 60 ;左边界
cut_x dw 4 ;每格宽
cut_y dw 3 ;每格长
max_x dw 49 ;最大格数(横)
max_y dw 49 ;最大格数(纵)
msg1 db 'Hotou snakes'
msg2 db 'SNAKE With TASM3.0 by Hotou 2005 CopyRight (C) Detective'
msg3 db 'Game is over!'
msg4 db 'Press any key! Esc for exit'
msg5 db 'ESC for back, Space for retry'
flash db 8eh ;字体颜色(黄)
green db 02h ;字体颜色(绿)
white db 0fh ;字体颜色(白)
;******************************************************************************************
;键盘扫描码
LEFT EQU 4Bh
RIGHT EQU 4Dh
UP EQU 48h
DOWN EQU 50h
QUIT EQU 01h
SPACE EQU 39h
;******************************************************************************************
;LOGO by bsascii
tit1 db ' JNNN. NN (N .NN JNNN. N) JNN'
tit2 db ' (NNNNN NN. (N (NN. (NNNNN. N) (NN`'
tit3 db ' NNNNNN) NN) (N (NN) NNNNNN) N) JN) '
tit4 db ' NN` 4N) NNL (N JNN) (NN` 4NL N) (NN` '
tit5 db ' N) (NN NNN. (N NFNL (N) NN N) NN) '
tit6 db ' NN. "" NNN) (N (N)NN NN `` N)(NN` '
tit7 db ' NNNL. NNNN (N (N)(N. NN N)NN) '
tit8 db ' (NNNNL N)NN)(N NN (N) NN NNNNN '
tit9 db ' 4NNNN) N)(N)(N NN (N) NN NNNNN) '
tit10 db ' `4NNN N)`NN(N .N) NN NN NNF(N) '
tit11 db ' _. `NN N) NNNN (NNNNNN NN JL NN `NN '
tit12 db '(N) (N N) (NNN NNNNNNN) NN. NN N) 4N) '
tit13 db '(NL NN N) `NNN NNNNNNN) (NL (NF N) (NL '
tit14 db ' NNL_JNN N) 4NN NF `NN NNNNNN) N) NN '
tit15 db ' NNNNNNF N) (NN (N) NN (NNNNN N) (N)'
tit16 db ' (NNNNN` N) `NN (N` 4N NNNN) N) (NN'
tit17 db ' `4NF` "` "" "" `"` `"` "` ""'
;******************************************************************************************
.code
main proc far
mov ax , @data
mov ds , ax
start:
mov ah , 00
mov al , 12h
int 10h ;设置图形模式640*480
call show_title ;显示LOGO
call show_start_msg ;显示开始提示信息
mov ah , 00h
int 16h ;等待按键
cmp ah , QUIT
jz dos ;ESC则退出,否则进入游戏
game_start:
mov ah , 00 ;设置图形模式320*200,游戏在此模式下运行
mov al , 13h
int 10h
mov cl , 10 ;边框颜色
mov si , 63
mov bx , 22
mov di , 256
mov dx , 167
call rec ;打印边框
;call clear_area ;游戏区域清空(效果)
call Init_snake ;初始化蛇
call getfood ;得到第一个食物
call run_snake ;开始运动蛇
exit:
mov dx , 1010h ;设置光标
call SetGb
mov bl , white ;显示死亡信息
lea bp , msg3
mov cx , 13
call Msg
mov dx , 1605h
mov bl , white ;显示提示信息
lea bp , msg5
mov cx , 29
call Msg
exit_loop:
mov ah , 00h
int 16h ;等待按键
cmp ah , QUIT
jz start
cmp ah , SPACE
jz game_start
jmp exit_loop ;返回开始
dos:
mov ah , 00
mov al , 03
int 10h ;设置文本模式
mov ah , 4ch
int 21h ;退出到DOS
main endp
;******************************************************************************************
;函数名: show_start_msg
;功能: 显示开始提示信息
;传递参数:
;函数返回: 空
;******************************************************************************************
show_start_msg proc near
push ax
push bx
push cx
push dx
push si
push di
mov dx , 190bh
call SetGb ;设置光标
mov bl , white
lea bp , msg2 ;显示作者信息
mov cx , 56
call Msg ;显示字符串
mov dx , 1619h ;设置光标
call SetGb
mov bl , 0a8h
lea bp , msg4 ;显示提示信息
mov cx , 27
call Msg ;显示字符串
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
show_start_msg endp
;******************************************************************************************
;函数名: cutsnake
;功能: 显示蛇一段
;传递参数:
; si/di 游戏空间行/游戏空间列(50*50)
;函数返回: 空
;******************************************************************************************
cutsnake proc near
push ax
push bx
push cx
push dx
push si
push di
mov cl , snake_color ;置颜色
mov ax,di ;取坐标值
mul cut_y ;乘象素值
add ax,topline ;加上边界
mov bx , ax
add ax , 2
mov dx , ax
push bx
push dx
mov ax,si ;取坐标值
mul cut_x ;乘象素值
add ax,leftline ;加上边界
mov si , ax
add ax , 3
mov di , ax
pop dx
pop bx
mov cx,si
mov dx,bx
mov al,snake_color
call qiu
;call Rec ;Rec的参数是cl颜色 si左边 bx上边 di右边 dx下边
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
cutsnake endp
;******************************************************************************************
;函数名: cutfood
;功能: 显示食物
;传递参数:
; si/di 游戏空间行/游戏空间列(50*50)
;函数返回: 空
;******************************************************************************************
cutfood proc near
push ax
push bx
push cx
push dx
push si
push di
mov cl , food_color ;置颜色
mov ax,di ;取坐标值
mul cut_y ;乘象素值
add ax,topline ;加上边界
mov bx , ax
add ax , 2
mov dx , ax
push bx
push dx
mov ax,si ;取坐标值
mul cut_x ;乘象素值
add ax,leftline ;加上边界
mov si , ax
add ax , 3
mov di , ax
pop dx
pop bx
mov cx,si
mov dx,bx
mov al,food_color
;call Rec ;Rec的参数是cl颜色 si左边 bx上边 di右边 dx下边
call qiu
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
cutfood endp
;******************************************************************************************
;函数名: clearcut
;功能: 清除格
;传递参数:
; si/di 游戏空间行/游戏空间列(50*50)
;函数返回: 空
;******************************************************************************************
clearcut proc near
push ax
push bx
push cx
push dx
push si
push di
mov cl , 0 ;置颜色(黑)
mov ax,di ;取坐标值
mul cut_y ;乘象素值
add ax,topline ;加上边界
mov bx , ax
add ax , 2
mov dx , ax
push bx
push dx
mov ax,si ;取坐标值
mul cut_x ;乘象素值
add ax,leftline ;加上边界
mov si , ax
add ax , 3
mov di , ax
pop dx
pop bx
mov al,0
mov cx,si
mov dx,bx
;call Rec ;Rec的参数是cl颜色 si左边 bx上边 di右边 dx下边
call qiu
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
clearcut endp
;******************************************************************************************
;函数名: Rand
;功能: 产生指定范围大小的随机数
;传递参数:
; si 数字的范围最大值+1
;函数返回: ax 返回随机数的值
;******************************************************************************************
Rand proc
push bx
push cx
push dx
push si
push di
sti
mov ah,0 ;读时钟计数器值
int 1ah
mov ax , seed
add ax , dx
and ax , 8fffh
mov seed , ax ;产生新种子
mov dx , 0
mov bx , si ;指定随机数的范围
div bx
mov ax , dx
pop di
pop si
pop dx
pop cx
pop bx
ret
Rand endp
;******************************************************************************************
;函数名: getfood
;功能: 产生新食物,即随机产生一组49*49的坐标
;传递参数:
;
;函数返回: foodx与foody的值
;******************************************************************************************
getfood proc
push ax
push bx
push cx
push dx
push si
push di
mov si,49 ;置随机数范围(最大值+1)
call Rand ;产生随机数
mov foodx,ax ;赋予食物坐标x
mov si,49 ;置随机数范围(最大值+1)
call Rand ;产生随机数
mov foody,ax ;赋予食物坐标x
mov si,foodx
mov di,foody
call cutfood ;画食物
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
getfood endp
;******************************************************************************************
;函数名: Delay
;功能: 延时
;传递参数:
;
;函数返回:
;******************************************************************************************
Delay proc
push ax
push cx
mov ax , 0ah
sub ax , cx
mov cx , ax
M3_1: push cx ;外层循环来控制延时速度
mov cx , 8000 ;标准半秒应该是33144大小
M3_2: in al , 61h
and al , 10h
cmp al , ah
je M3_1
mov ah , al
loop M3_2
pop cx
loop M3_1
pop cx
pop ax
ret
Delay endp
;******************************************************************************************
;函数名: Check_key
;功能: 处理键盘响应
;传递参数: 无
;
;函数返回: Direction的值,gameover的值(按ESC时)
;******************************************************************************************
Check_key proc
push ax
push bx
push cx
push dx
push si
push di
mov ah , 01h
int 16h
jz check_nokey;如果没有按键就继续
;mov ah , 0eh
;mov al , 7
;int 10h
mov ah , 00h ;取得扫描码
int 16h
cmp ah , LEFT ;往左移动
jz check_LEFT
cmp ah , RIGHT ;往右边移动
jz check_RIGHT
cmp ah , UP ;往上移动
jz check_UP
cmp ah , DOWN ;往下移动
jz check_DOWN
cmp ah , QUIT ;结束游戏
jz check_QUIT
jmp check_nokey
check_LEFT:
mov ah , -1 ;(-1,0)
mov al , 0
mov bx , ax ;检查是否反向
add bx , Direction
jz check_nokey
mov Direction , ax
jmp check_nokey
check_RIGHT:
mov ah , 1 ;(1,0)
mov al , 0
mov bx , ax ;检查是否反向
add bx , Direction
jz check_nokey
mov Direction , ax
jmp check_nokey
check_UP:
mov ah , 0 ;(0,-1)
mov al , -1
mov bx , Direction ;检查是否反向
sub bl , 1
jz check_nokey
mov Direction , ax
jmp check_nokey
check_DOWN:
mov ah , 0 ;(0,1)
mov al , 1
mov bx , Direction ;检查是否反向
add bl , 1
jz check_nokey
mov Direction , ax
jmp check_nokey
check_QUIT:
jmp check_exit
check_exit:
mov al,1 ;按下ESC键的情况
mov gameover,al
check_nokey:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
Check_key endp
;******************************************************************************************
;函数名: Check_die
;功能: 处理死亡的响应
;传递参数: SI,DI为当前蛇头部的坐标
;
;函数返回: 蛇参数的值
;******************************************************************************************
Check_die proc
push ax
push bx
push cx
push dx
push si
push di
mov bx , offset Body
cmp si , 49 ;检查是否到达边界
jz dead1
cmp si , 0
jz dead2
cmp di , 49
jz dead3
cmp di , 0
jz dead4
mov ax,si ;检查是否接触蛇身
mov dh,al ;DX中获得当前坐标
mov ax,di
mov dl,al
xor cx , cx
mov cl , Len
sub cl , 1
check_die_loop:
mov ax , [bx+2]
cmp ax , dx ;取出蛇身信息进行比较
jz dead ;触及蛇身即死亡
dec cl
jz next
add bx , 2
jmp check_die_loop
dead:
mov al,1 ;死亡即赋gameover值1
mov gameover,al
jmp next
dead1: mov ax,[bx]
mov ah,1
mov [bx],ax
jmp next
dead2: ;mov ax,[bx]
mov ah,48
mov [bx],ax
jmp next
dead3: mov ax,[bx]
mov al,1
mov [bx],ax
jmp next
dead4: mov ax,[bx]
mov al,48
mov [bx],ax
jmp next
next:
pop di
pop si
pop dx
pop cx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -