⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.asm

📁 一个用x86汇编语言编写的贪吃蛇小游戏。实现了基本的键盘操作控制和成绩显示
💻 ASM
字号:
.486
;-------------------------------------------------------------------------------
;(1) 清空键盘缓冲区
ckbuf macro
push ds
push ax
push bx
MOV   AL, 0BH
MOV   AH, 0CH
INT   21H
pop bx
pop ax
pop ds
endm
;-------------------------------------------------------------------------------
;(2) 产生0-n的随机数宏定义
;返回值存ah寄存器
rand macro n
      push  cx
      push  dx
      xor   ah,ah
      int   1ah
      mov  ax,dx
      and  ax,07fh
      mov  dl,n
      div  dl
      pop  dx
      pop  cx
endm
;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------
DATA SEGMENT   USE16
	BODY DB '-O#'         ;3个
           DB 50 DUP('a')
      ;设置蛇的每个字符的初始位置坐标 (行号,列号)
      COOR DB 13,23, 13,24, 13,25,  13,26
           DB 13,27, 13,28, 13,29,  13,30
           DB 13,31, 13,32, 13,33,  13,34
           DB 13,35, 13,36
      ;设置蛇最大可增加 50 个长度
      TAIL DB 100 DUP(?)
      ;设置蛇的当前长度,初始为3
      LENG        DB    3
      DIRECTION   DB    72
      FOOD        DB    10,10
      SCOINFO     DB    'SOORE:$'
      SCORE       DB    0H
      SCOCHAR     DB    4 DUP('0')
                  DB    '$'
      PAUSEINFO   DB    'PAUSE--Pagedown$'
      EXITINFO    DB    'EXIT --Esc$'
      CTRINFO     DB    'Change Direction$'
      CTRINFO2    DB    'with Dirction Key$'
      N     EQU 10000
      TEN2  DW   10
DATA ENDS

STACK SEGMENT STACK
	DB 100 DUP(?)
STACK  ENDS


CODE SEGMENT   USE16
	ASSUME CS:CODE,DS:DATA,SS:STACK
START:
      MOV   AX,DATA
	MOV   DS,AX

      CALL  CLEARS
      CALL  GENFOOD
      CALL  SHOWINFO

      ;设置CTRINFO光标位置
      PUSH  SI
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,  1
      MOV   DL,  60
      INT   10H
      ;显示CTRINFO
      MOV AH,9
	MOV DX,OFFSET CTRINFO
	INT 21H
 
      ;设置CTRINFO2光标位置
      PUSH  SI
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,  2
      MOV   DL,  60
      INT   10H
      ;显示CTRINFO2
      MOV AH,9
	MOV DX,OFFSET CTRINFO2
	INT 21H
 
      ;设置PAUSEINFO光标位置
      PUSH  SI
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,  5
      MOV   DL,  62
      INT   10H
      ;显示PAUINFO
      MOV AH,9
	MOV DX,OFFSET PAUSEINFO
	INT 21H

      ;设置EXITINFO光标位置
      PUSH  SI
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,  4
      MOV   DL,  62
      INT   10H
      ;显示EXITINFO
      MOV AH,9
	MOV DX,OFFSET EXITINFO
	INT 21H
      ;-------------------------------------------
      MOV   CX,3000
L1:   PUSH  CX

      CALL  DELAY

      CALL  MOVESTEP
      
      CALL  SHOWBODY
      
      
      POP   CX
      
      LOOP  L1
      

      
SCAN:
      MOV   AH,1
      INT   16H
      JZ    SCAN
SCAN2:
      MOV   AH,1
      INT   16H
      JZ    SCAN2

LAST:
     MOV AH, 4CH
     INT 21H
;-------------------------------------------------------------------------------
;(1)  设置彩色文本方式+清屏+清除光标的子程序
CLEARS    PROC
 ;设置屏幕显示方式为80×25的彩色文本方式
      MOV   AH,00H
      MOV   AL,3
      INT   10H
 ; 先用蓝色清屏
      MOV   AH,6
      MOV   AL,0
      MOV   BH,10H
      MOV   CX,0
      MOV   DL,59
      MOV   DH,24
      INT   10H
 ;清除光标
      MOV   AH,01H
      MOV   CH,20H
      INT   10H
      RET
ENDP
;-------------------------------------------------------------------------------
;(2)  从COORD为尾部的坐标开始,按照BODYY中的字符,
;     写内存LENGT中表示数字个字符到屏幕上的子程序
SHOWBODY    PROC
      MOV   SI,OFFSET LENG
      MOV   CL, [SI]
      MOV   CH, 0H
      MOV   SI,OFFSET COOR
      MOV   DI,OFFSET BODY
SL1:  ;设置光标位置
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,[SI]
      MOV   DL,[SI+1]
      INT   10H
      ;在当前光标位置处写字符
      MOV   AH,09H
      PUSH  CX    ;保存CX的值
      MOV   AL,[DI]
      MOV   BH,0
      MOV   BL,1FH
      MOV   CX,1
      INT   10H
      POP   CX

      ADD   SI,2
      ADD   DI,1
      LOOP  SL1
      RET
ENDP
;-------------------------------------------------------------------------------
;(3)延时子程序
DELAY PROC
      MOV   CX,N
DL2:
      PUSH  CX
      MOV   CX,N
DL1:
      LOOP   DL1
      POP   CX
      LOOP  DL2
      
      MOV   AH,1
      INT   16H
      MOV   DX,N
      JNZ   DL3
      
      JMP   DL4
DL3:   CALL GETCHAR
       CKBUF
DL4:
      RET
ENDP
;-------------------------------------------------------------------------------
;(4)按照参数方向移动一步,同时擦去尾巴   的子程序
;即直接改变COOR中的坐标 ,LENGT为蛇当前长度
MOVESTEP    PROC
      MOV   SI,OFFSET   COOR    ;先擦尾巴
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,[SI]
      MOV   DL,[SI+1]
      INT   10H
      ;在当前光标位置处写空白
      MOV   AH,09H
      MOV   AL,0H
      MOV   BH,0
      MOV   BL,1FH
      MOV   CX,1
      INT   10H

      ;先将除头部外的坐标 前一个 放到 后一个 从后向前
      MOV   SI,OFFSET LENG
      MOV   CL, [SI]
      MOV   CH, 0H
      DEC   CX
      MOV   SI,OFFSET  COOR
MLL:  MOV   AX, WORD PTR [SI+2]
      MOV   WORD PTR [SI],AX
      ADD   SI,2
      LOOP  MLL

      ;然后根据 DIRECTION 的不同值改变头部坐标
      ;  判断是否到达边界并修改坐标
      ;此时 SI 指的是头部坐标的内存位置
      MOV   DI,OFFSET DIRECTION
      MOV   DL,[DI]
      CMP   DL,77
      JE    ML0
      CMP   DL,72
      JE    ML1
      CMP   DL,75
      JE    ML2
      CMP   DL,80
      JE    ML3
ML0:  ;INC   BYTE  PTR [SI+1]
      MOV   AL,[SI+1]
      XOR   AH,AH
      INC   AX
      MOV   BL,60
      DIV   BL
      MOV   [SI+1],AH
      JMP   MLEND1
ML1:  ;DEC   BYTE  PTR [SI]
      MOV   AL,[SI]
      XOR   AH,AH
      DEC   AX
      ADD   AX,25
      MOV   BL,25
      DIV   BL
      MOV   [SI],AH
      JMP   MLEND1
ML2:  ;DEC   BYTE  PTR [SI+1]
      MOV   AL,[SI+1]
      XOR   AH,AH
      DEC   AX
      ADD   AX,60
      MOV   BL,60
      DIV   BL
      MOV   [SI+1],AH
      JMP   MLEND1
ML3:  ;INC   BYTE  PTR [SI]
      MOV   AL,[SI]
      XOR   AH,AH
      INC   AX
      MOV   BL,25
      DIV   BL
      MOV   [SI],AH
MLEND1:     ;判断是否碰到食物,若是,则根据当前方向增长头部
      MOV   AX,WORD PTR [SI]
      MOV   DI,OFFSET FOOD
      MOV   BX,[DI]
      CMP   AX,BX
      JNE   MLEND2
      

      MOV   DI,OFFSET LENG
      MOV   AL,[DI]
      XOR   AH,AH
      DEC   AX
      INC   BYTE PTR [DI]
      MOV   DI,OFFSET BODY
      ADD   DI,AX
      MOV   BYTE PTR [DI],       'O'
      MOV   BYTE PTR [DI+1],     '#'
      MOV   DI,OFFSET SCORE
      INC   BYTE PTR [DI]
      CALL  SHOWINFO

      
      ;根据方向修改增长后的头部坐标 ,此时 SI 指向原来的头部
      MOV   DI,OFFSET DIRECTION
      MOV   AL,[DI]
      CMP   AL,77
      JE    ML00
      CMP   AL,72
      JE    ML01
      CMP   AL,75
      JE    ML02
      CMP   AL,80
      JE    ML03
ML00: MOV   AL,[SI+1]
      XOR   AH,AH
      INC   AX
      MOV   BL,60
      DIV   BL
      MOV   [SI+3],AH
      MOV   BL,[SI]
      MOV   [SI+2],BL
      JMP   MFOOD
ML01: MOV   AL,[SI]
      XOR   AH,AH
      DEC   AX
      ADD   AX,25
      MOV   BL,25
      DIV   BL
      MOV   [SI+2],AH
      MOV   BL,[SI+1]
      MOV   [SI+3],BL
      JMP   MFOOD
ML02: MOV   AL,[SI+1]
      XOR   AH,AH
      DEC   AX
      ADD   AX,60
      MOV   BL,60
      DIV   BL
      MOV   [SI+3],AH
      MOV   BL,[SI]
      MOV   [SI+2],BL
      JMP   MFOOD
ML03: MOV   AL,[SI]
      XOR   AH,AH
      INC   AX
      MOV   BL,25
      DIV   BL
      MOV   [SI+2],AH
      MOV   BL,[SI+1]
      MOV   [SI+3],BL

MFOOD:
      CALL  GENFOOD
      
MLEND2:
;
      RET
ENDP
;-------------------------------------------------------------------------------
;(5)  读取键盘输入并根据输入和原来的方向改变DIRECTION 的子程序 ,
;     并判断是否暂停
GETCHAR     PROC  NEAR
      MOV   AH,0H
      INT   16H
      cmp   ah,01    ;为ESC键吗?
      JE    GEL2
      CMP   AH,81 ;先判断是否是Pagedown暂停
      JE    GEL1

      MOV   BL,AH
      XOR   BH,BH
      MOV   SI,OFFSET   DIRECTION
      MOV   AL,[SI]
      XOR   AH,AH
      ADD   AX,BX
      CMP   AX, 152
      JE    GEND
      MOV   [SI],BL
      JMP   GEND
GEL1: CKBUF
      MOV   AH,0H
      INT   16H
      CMP   AH,01
      JE    GEL2
      CMP   AH,81
      JNE    GEL1
      JMP    GEND

GEL2: MOV AH,4CH
      INT 21H
      

GEND:
      ;CKBUF
      RET
ENDP
;-------------------------------------------------------------------------------
;(6)  在 FOOD 内存 随机产生一个 坐标,并显示食物
GENFOOD     PROC NEAR
GENL1:
      RAND    24
      MOV   BL,AH
      RAND    59
      MOV   BH,AH
      MOV   SI,OFFSET LENG
      MOV   CX,[SI]
      MOV   SI,OFFSET COOR
GENL2:
      CMP   BX,WORD PTR [SI]
      JE    GENL1
      ADD   SI,2
      LOOP  GENL2
      
      MOV   SI,OFFSET  FOOD
      MOV   [SI],BX
      ;设置光标位置
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,[SI]
      MOV   DL,[SI+1]
      INT   10H
      ;在当前光标位置处写字符
      MOV   AH,09H
      MOV   AL,'@'
      MOV   BH,0
      MOV   BL,1FH
      MOV   CX,1
      INT   10H

      RET
ENDP
;-------------------------------------------------------------------------------
; (7) 显示信息子程序
SHOWINFO    PROC NEAR
 
      ;设置SCOINFO光标位置
      PUSH  SI
      MOV   AH,02H
      MOV   BH,0
      MOV   DH,  13
      MOV   DL,  67
      INT   10H
      ;显示INFO
      MOV AH,9
	MOV DX,OFFSET SCOINFO
	INT 21H
      ;转化SOCOE为SCORECHAR并显示
      MOV    SI,OFFSET SCOCHAR+3
      MOV    DI,OFFSET  SCORE
      MOV    AL,[DI]
      XOR    AH,AH
      MOV    DX, 0H
      MOV    CX,  4
 SLL1:DIV    TEN2
      MOV    DI,AX
      MOV    AL,DL
      ADD    AL,30H
      MOV    [SI],AL
      MOV    AX,DI
      DEC    SI
      MOV    DX,0H
      LOOP   SLL1
      
      MOV    AH,9
      MOV    DX,OFFSET  SCOCHAR
      INT    21H
 
      POP   SI
      RET
ENDP
CODE ENDS
      END START

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -