📄 sn.asm
字号:
DATA SEGMENT GAMERULES1 DB 0DH,0AH,0DH,0AH," Game rules:","$" GAMERULES2 DB 0DH,0AH," Press ",1AH,2CH,1BH,2CH,18H,2CH,19H," to control the snake","$" GAMERULES3 DB 0DH,0AH,"Press ESC to Exit, or Press any key to Continue.",0DH,0AH,"$" MSGERR DB 0DH,0AH," GAME OVER, Press ESC to EXIT, or Press any key to Restart",0DH,0AH,"$" PX DW 100 DUP(?) ;记录蛇的各个部位的位置 PY DW 100 DUP(?) ;蛇的最大长度为100 LAST DW ? ;用于记录上一次移动方向的反方向,即禁止180调转 GOON DW ? ;保存上一次前进的方向 QX DW 8 DUP(?) ;保存苹果的位置 QY DW 8 DUP(?) DELAYTIME DD ? ;通过设置延迟调节蛇的移动速度 LENGTH DW ? ;蛇的长度DATA ENDS STACK SEGMENT STACK DW 64 DUP(?)STACK ENDSCODE SEGMENT ASSUME CS:CODE,SS:STACK,DS:DATASTART: MOV AX,DATA MOV DS,AX ; 一些初始设置 MOV LENGTH,10 ; 设置蛇的初始长度 MOV DELAYTIME,10000 ; 设置蛇的移动速度 MOV AH,0 MOV AL,3 INT 10H MOV AL, 0 ;清屏功能 MOV BH, 16H ;蓝底黄字 MOV CH, 0 ;左上角行号 MOV CL, 0 ;左上角列号 MOV DH, 24 ;右下角行号 MOV DL, 79 ;右下角列号 MOV AH, 6 ;功能号 INT 10H ;中断调用 MOV AH,1 ;;隐藏光标 MOV CX,1000H INT 10H MOV DX,OFFSET GAMERULES1 MOV AH,9 INT 21H MOV DX,OFFSET GAMERULES2 MOV AH,9 INT 21H MOV DX,OFFSET GAMERULES3 MOV AH,9 INT 21H MOV AH,0 INT 16H CMP AL,27 JE THE_END MOV AL, 0 ;清屏功能 MOV BH, 16H ;蓝底黄字 MOV CH, 0 ;左上角行号 MOV CL, 0 ;左上角列号 MOV DH, 24 ;右下角行号 MOV DL, 79 ;右下角列号 MOV AH, 6 ;功能号 INT 10H ;中断调用 MOV LAST,75 MOV GOON,77 MOV AH,0FH INT 10H MOV CX,1 MOV QX[0],23H ;设置苹果位置 MOV QY[0],12H ;一共设置6个苹果 MOV QX[1],06H ;他们将循环依次显示 MOV QY[1],08H MOV QX[2],22H MOV QY[2],09H MOV QX[3],23H MOV QY[3],12H MOV QX[4],13H MOV QY[4],06H MOV QX[5],23H MOV QY[5],06H MOV DI,0 ;初始化第一只苹果DISP: MOV AH,1 ;隐藏光标 MOV CX,1000H INT 10H MOV CX,1 MOV DL,03H ;;开始显示蛇尾 MOV DH,10H MOV AH,2 INT 10H MOV AL,2DH ;- ;使用-代替蛇尾 MOV AH,0AH INT 10H MOV PX[0],DL MOV PY[0],DH MOV SI,1BODY: ;显示蛇的身体 INC DL MOV AH,2 INT 10H MOV AL,3DH ;= ;使用=表示蛇的身体 MOV AH,0AH INT 10H MOV PX[SI],DL MOV PY[SI],DH INC SI CMP SI,LENGTH JNE BODY INC DL ;显示蛇头 MOV AH,2 INT 10H MOV AL,23H ;# ;使用#表示蛇的头部 MOV AH,0AH INT 10H MOV SI,LENGTH MOV PX[SI],DL MOV PY[SI],DH MOV DL,QX[DI] ;显示第一只苹果 MOV DH,QY[DI] MOV AH,2 INT 10H MOV AL,01H ;APPLE ;使用笑脸代替苹果 MOV AH,0AH INT 10H GO_TO_NEXT: MOV SI,LENGTH ;首先得到蛇的头部将要到达的位置 MOV DL,PX[SI] MOV DH,PY[SI] YOURSELF: ;判断蛇是否咬到自己 DEC SI CMP DL,PX[SI] JNE NEXTYOURSELF CMP DH,PY[SI] JNE NEXTYOURSELF JMP GAME_OVERNEXTYOURSELF: CMP SI,0 JNE YOURSELF MOV CX,1 ;将蛇的头部显示 MOV AH,2 INT 10H MOV AL,23H ;# MOV AH,0AH INT 10H CMP DL,QX[DI] ;判断蛇是否吃到苹果 JNE NOTEAT CMP DH,QY[DI] JNE NOTEAT JMP EAT NOTEAT: ;如果没有吃到,继续身体和尾巴的移动 MOV SI,LENGTH DEC SI MOV DL,PX[SI] ;在蛇的头部原来的位置绘制'='表示身体 MOV DH,PY[SI] MOV AH,2 INT 10H MOV AL,3DH ;= MOV AH,0AH INT 10H MOV BL,DL ;判断尾巴将要到达的地方是否有苹果 MOV DL,PX[1] ;如果有,将不绘制尾巴 MOV DH,PY[1] CMP DL,QX[DI] JNE TAILA CMP DH,QY[DI] JNE TAILA JMP NOTAIL TAILA: ;在尾巴的前一个位置绘制'-'表示尾巴 MOV AH,2 INT 10H MOV AL,2DH ;- MOV AH,0AH INT 10H MOV DL,BL NOTAIL: CALL CLEAR ;CLEAR ;擦除上一个尾巴的痕迹 MOV SI,0 ;更新身体的各个部位的位置坐标NEXT: MOV AL,PX[SI+1] MOV AH,PY[SI+1] MOV PX[SI],AL MOV PY[SI],AH INC SI CMP SI,LENGTH JNE NEXT WAITING: CALL DELAY ;停留一会儿 MOV AH,1 MOV CX,1000H INT 10H MOV CX,1 MOV AH,1 ;等待按键输入 INT 16H JNZ COMP ;若有输入,进行方向判断 MOV AH,GOON ;若没有输入,保持上一次的移动方向 JMP KEY COMP: ;通过比较判断蛇的前进方向 MOV AH,0 INT 16H CMP AL,27 ;如果输入的是 ESC键,退出程序 JE THE_END MOV DH,LAST CMP AH,DH ;调转180度不被允许 JE WAITING KEY: ;判断前进方向 CMP AH,75 JB IS_UP JE GO_LEFT CMP AH,77 JE GO_RIGHT CMP AH,80 JE GO_DOWN JMP WAITINGIS_UP: CMP AH,72 JE GO_UP JMP WAITING GO_UP: MOV SI,LENGTH ;向上 MOV LAST,80 MOV GOON,72 MOV DH,PY[SI-1] DEC DH MOV PY[SI],DH MOV DL,PX[SI-1] MOV PX[SI],DL JMP GO_TO_NEXT GO_LEFT: ;向左 MOV SI,LENGTH MOV LAST,77 MOV GOON,75 MOV DL,PX[SI-1] DEC DL MOV PX[SI],DL MOV DH,PY[SI-1] MOV PY[SI],DH JMP GO_TO_NEXT GO_RIGHT: ;向右 MOV SI,LENGTH MOV LAST,75 MOV GOON,77 MOV DL,PX[SI-1] INC DL MOV PX[SI],DL MOV DH,PY[SI-1] MOV PY[SI],DH JMP GO_TO_NEXT GO_DOWN: ;向下 MOV SI,LENGTH MOV LAST,72 MOV GOON,80 MOV DH,PY[SI-1] INC DH MOV PY[SI],DH MOV DL,PX[SI-1] MOV PX[SI],DL JMP GO_TO_NEXT EAT: ;如果吃到了苹果将直接跳转到这儿 INC DI CMP DI,6 ;如果第6个苹果已经显示 JNE NEXTAPPLE ;将从第一个苹果重新显示 MOV DI,0NEXTAPPLE: INC LENGTH ;吃到苹果,蛇的长度增加1 MOV SI,LENGTH MOV DL,QX[DI] ;显示下一个苹果 MOV DH,QY[DI] MOV AH,2 INT 10H MOV AL,01H ;APPLE MOV AH,0AH INT 10H SUB SI,2 MOV DL,PX[SI] ;在蛇头部的前一个位置显示身体 MOV DH,PY[SI] ;其他部位保持不变 MOV AH,2 INT 10H MOV AL,3DH ;= MOV AH,0AH INT 10H JMP WAITING ;等待下一个方向 GAME_OVER: ;如果咬到自己,将会跳转到这儿 MOV DH, 12H ; 置光标位置 MOV DL, 5 MOV BH, 0 MOV AH, 2 INT 10H MOV DX,OFFSET MSGERR MOV AH,9 INT 21HANYKEY: ;等待按键输入 MOV AH,1 ;隐藏光标 MOV CX,1000H INT 10H MOV CX,1 MOV AH,0 INT 16H CMP AL,1BH ;如果输入的是ESC键,将退出程序 JE THE_END MOV AH,6 MOV AL,0 INT 10H ;其他按键,清屏并且重新开始新游戏 JMP START THE_END: ;退出程序 MOV AH,4CH INT 21H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CLEAR PROC NEAR ;清除尾巴痕迹的子程序 MOV AL,00H ;使用00H号字符清除尾巴痕迹 MOV BL,DL MOV DL,PX[0] MOV DH,PY[0] CMP DL,QX[DI] ;判断要清除的位置是否有苹果 JNE TA1 CMP DH,QY[DI] JNE TA1 MOV AL,01H ;如果有,则使用苹果覆盖(即保持苹果不消失)TA1: MOV AH,2 INT 10H MOV AH,0AH INT 10H MOV DL,BL RET CLEAR ENDPDELAY PROC NEAR ;延迟子程序 PUSH CX ;通过设置循环的次数 PUSH DX ;延迟的长短和机器的性能有关 MOV DX,14000 ;内层循环OUTDELAY: MOV CX,DELAYTIME ;外层循环INDELAY: LOOP INDELAY DEC DX JNZ OUTDELAY POP DX POP CX RETDELAY ENDP CODE ENDS END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -