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

📄 td.asm

📁 用汇编语言实现的类似DOS下打字的游戏
💻 ASM
字号:
;处理开始界面和主界面间的延时的宏
DELAY1 MACRO
      PUSH CX
      PUSH DX
      MOV  DX,9000
DL11:
      MOV CX,0FFFFH
DL12:
      LOOP DL12
      DEC  DX
      JNZ  DL11
      POP  DX
      POP  CX
ENDM

;处理下降延时时的宏
DELAY2 MACRO
      LOCAL DL21
      LOCAL DL22	
      PUSH CX
      PUSH DX
      MOV  DX,2000
DL21:
      MOV CX,0FFFFH
DL22:
      LOOP DL22
      DEC  DX
      JNZ  DL21
      POP  DX
      POP  CX
ENDM

;处理打出字幕延时的宏
DELAY3 MACRO
      PUSH CX
      PUSH DX
      MOV  DX,200
DL31:
      MOV CX,0FFFFH
DL32:
      LOOP DL32
      DEC  DX
      JNZ  DL31
      POP  DX
      POP  CX
ENDM

date segment
      	table db 'qpalzmxnskwieudjcnvbfhrytqscgyjmkopzoxicvubhnymtgrfjrekqdfghyuiopmbeswzaqwqpbncxmalalpnqcxzqetnclgfpoxzewe' 
	hour   db 0	;要初始化
	minute db 0
	second db 0 

	right  db 0
	total  dw 0
date ends
stack segment stack
	db 800 dup(0)
stack ends
code segment
	assume ds:date,ss:stack,cs:code
start:  mov ax,date
	mov ds,ax
	
	lea si,table
	call mpc
	call music
	call topword
	call enter
	call down

	mov  ax,total
;	call far ptr num_char
exit:	mov ah,4ch
	int 21h

;显示游戏开始界面的子程序
;入口参数---------------------空
;出口参数---------------------产生游戏开始界面
mpc proc 
	mov ah,0
	mov al,3
	int 10h

	mov ah,15
	int 10h

	mov dx,0000h
	mov ah,2
	int 10h
	mov al,08h

	mov bh,0
	mov cx,80	;显示上眉
	mov ah,0ah
	int 10h

	mov cx,1
	mov dx,0100h	;显示左披
left:	mov ah,2
	int 10h
	mov al,08h
	mov ah,0ah
	int 10h
	inc dh
	cmp dh,24	 	 	  
	jb  left 
	
	mov dl,79	;显示右披
rightb:	mov ah,2
	int 10h
	mov al,08h
	mov ah,0ah
	int 10h
	dec dh
	ja rightb

	mov dx,1701h
	mov ah,2
	int 10h
	mov al,01h	 		 
	mov cx,78
	mov ah,0ah
	int 10h

	mov dx,1800h
	mov ah,2
	int 10h

	mov al,08h
	mov cx,80	;显示下眉
	mov ah,0ah
	int 10h

	ret	
mpc	endp
;游戏开始时的音乐程序
music proc 
	push ax
	push bx
	push cx
	push ds

	mov ax,0	
	mov ds,ax	;段地址为000h

	mov cx,3	;计数值为3

	in  al,61h	;打开定时器和扬声器
	or  al,3	;置pb0和pb1
	out 61h,al

main1:  mov bx,1800	;选用1800HZ音调
	call far ptr beep
	mov bx,2000	;选用2000HZ音调
	call far ptr beep
 	mov bx,1000	;选用1000HZ音调
	call far ptr beep
	mov bx,1600
	call far ptr beep
	mov bx,1200	;选用1200HZ音调
	call far ptr beep
	mov bx,1400	;选用1400HZ音调
	call far ptr beep
	loop main1	;重复3次

	in  al,61h	;关闭扬声器
	xor al,3	;清除pb0和pb1
	out 61h,al
	
	pop ds
	pop cx
	pop bx
	pop ax
	ret
music endp	

;击中时的的音乐程序
right_mus proc far

	push ax
	push bx
	push ds

	mov ax,0	
	mov ds,ax	;段地址为000h

	in  al,61h	;打开定时器和扬声器
	or  al,3	;置pb0和pb1
	out 61h,al

 	mov bx,1000	;选用1000HZ音调
	call far ptr beep

	in  al,61h	;关闭扬声器
	xor al,3	;清除pb0和pb1
	out 61h,al

	pop ds
	pop bx
	pop ax
	ret 
right_mus endp	

;没有击中时的的音乐程序
wrong_mus proc far 


	push ax
	push bx
	push ds

	mov ax,0	
	mov ds,ax	;段地址为000h

	in  al,61h	;打开定时器和扬声器
	or  al,3	;置pb0和pb1
	out 61h,al

 	mov bx,2000	;选用2000HZ音调
	call far ptr beep

	in  al,61h	;关闭扬声器
	xor al,3	;清除pb0和pb1
	out 61h,al

	pop ds
	pop bx
	pop ax
	ret 
wrong_mus endp	

beep  proc far
	mov ax,34dch	;ax=1,193,180
	mov dx,12h
	div bx		;计算出相应音调的计数值
	out 42h,al	
	mov al,ah	;对定时器2用计数值编程
	out 42h,al
	DELAY2	;延时
	ret
beep	endp

; 显示游戏界面上方字母的子程序
;入口参数-----------------si
;出口参数-----------------显示游戏界面上方字母
topword proc 
	
	mov cx,1
	mov dx,0101h	;预制光标位置

con:	
	delay3
	mov ah,2
	int 10h

	mov ah,0ah
	mov al,table[si]
	int 10h
	
	
	inc si
	inc dl
	cmp dl,79
	jb con		;显示的字母不足78个转

	ret
topword endp
;游戏界面子程序和游戏子程序间的等待ENTER输入的子程序
enter proc
	push ax
	push cx
	push dx
	mov al,0

again:	mov ah,8
	int 21h
	cmp al,0ah		;有输入时比较输入是否为enter键
	je  out2
	cmp al,0dh
	jne again

out2:	mov ah,2ch	;为enter键则读取游戏开始时刻
	int 21h
	mov hour,ch	
	mov second,cl
	mov minute,dh

	pop dx
	pop cx
	pop ax
	ret
enter 	endp
;建立一个随机数发生程序,用于控制字母下降的位置的随机变化
;出口参数------------bl,存放一个小于79大于0的随机数
random proc far
	push ax
	push cx
	push dx

	mov ah,2ch
	int 21h
	cmp dl,78
	ja  above
	cmp dl,0
	ja  zero1
	inc dl
zero1:	mov bl,dl
	jmp ok
above:	cmp dh,0
	ja  nzero
	inc dh
nzero:	mov bl,dh
ok:	pop dx
	pop cx
	pop ax
	ret
random endp
;游戏界面上方字母随机下落的子程序
;入口参数--------------主程序中的字母表table
;出口参数--------------键盘的输入值ax
down proc 

	PUSH CX
	PUSH DX
	PUSH AX

ANOTHER:MOV CX,1
	MOV BH,0
	MOV DH,1
	CALL RANDOM
        MOV DL,BL	;bl为random产生的随机数
	INC TOTAL	;下降的字符个数的计数器增一

REPTD0:	MOV AH,2
        INT 10H            ; set cursor position

	MOV SI,BX 
        MOV AL,TABLE[SI]
        MOV AH,10
        INT 10H            ; display spade
        DELAY2
        MOV AL,0
        MOV AH,10
        INT 10H
	
	push dx
	MOV DL,0FFH
	MOV AH,6	;判断控制台(键盘)是否有输入
	INT 21H
	pop dx
	JZ  CONDN 	;无输入时转字符继续下落
	CALL FAR PTR SPEKEY	;有输入时转特殊键处理
	
CONDN:  INC DH

	INC DH
        CMP DH,23
        JNE REPTD0
	JE  RECOVER

RECOVER:MOV DH,1
        MOV DL,BL
        MOV AH,2
        INT 10H            ;recover the top character
        MOV SI,BX
        MOV AL,TABLE[SI]
        MOV AH,10
        INT 10H   
	JMP ANOTHER       

	POP AX
	POP DX
	POP CX
	
	RET
DOWN ENDP
     
;判断输入是否ESC、ENTER、TAB等特殊键,若是则进行处理否则转comkey子程序进行处理
;入口参数------------键盘输入的值ax
;出口参数------------对特殊键处理完毕,非特殊键给后面的comkey子程序处理
spekey proc far

	cmp al,'Q'
	jne notq 
	jmp exit	;为'Q'键则结束游戏
notq:	cmp al,1bh
	jnz concmp
;	call far ptr time
	JMP  START	;为ESC键跳转到主程序头,调出主界面
concmp: cmp al,20h
	jz  istap
	call far ptr comkey	;非特殊键转一般键处理
	jmp gback 
istap:  ; call far ptr time	;为TAB键则暂停计时
	call far ptr  tapkey
gback:	ret
spekey endp	

;判断键盘是否有输入,记下输入,并与当前正在下落的字母比较
;人口:-------------------当前下落的字母序号放在bl中
;入口:-------------------键盘输入的字母放在ax中

comkey proc far 
	
	mov bh,0
	mov si,bx
	cmp al,table[si]	;有输入时比较输入是否和当前下落字母一致
	jne back
	inc right
	call far ptr redown 	;击中则调用另一字母下落子程序	
back:	call far ptr wrong_mus	;没有击中后发出刺耳的音乐
	ret
comkey 	endp

;击中后,修复顶部字母下落后的空缺,然后让另一字母开始下落
;人口:-------------------当前下落的字母序号放在bl中
;出口:-------------------另一字母开始下落
redown proc far 
	
	MOV DH,1
        MOV DL,BL
        MOV AH,2
        INT 10H            ;recover the top character

        MOV AL,TABLE[SI]
        MOV AH,10
        INT 10H          
	CALL FAR PTR RIGHT_MUS	;击中后发出和悦的音乐
	CALL DOWN
	ret
redown  endp

;实现按下tab键游戏暂停,并统计前段所用时间,再按下tab键游戏继续的子程序
;入口参数:-------------输入的tab键
tapkey proc far 

	push ax
	push cx
	push dx
	

	MOV SI,BX 
        MOV AL,TABLE[SI]
        MOV AH,10
        INT 10H            ; display spade

waittap:mov ah,8
	int 21h
 	cmp al,20h	;有输入时比较输入是否为空格
	jne waittap

	MOV SI,BX 	;为空格则清除当前光标所在字符
        MOV AL,0
        MOV AH,10
        INT 10H       

	mov ah,2ch	;为空格则读取当前时刻
	int 21h
	mov hour,ch	;重置当前时刻
	mov second,cl
	mov minute,dh

	pop dx
	pop cx
	pop ax
	
	ret
tapkey  endp
code ends
	end start


;函数功能:将某一数按十进制输出
;入口参数: ax---存贮一字
;出口参数: 转换后的数字在显示器上输出
;所用寄存器:bx----地址逆计数器
data2 segment
	numchar db 6 dup(0)
	cout equ $-numchar
	pot2 db ?
data2 ends
stack2 segment stack
	db 100 dup(0)
stack2 ends
pro2 segment
	assume cs:pro2,ds:data2,ss:stack2
num_char proc	far
	push si	
	push di
	push ds
	push cx
	push dx		
	mov cx,	data2	;将numchar与数据段联系起来
	mov ds,cx
	mov bx,cout	;地址逆计数器
	dec bx	
	lea si,numchar
	mov ch,'$'
	mov [bx+si],ch
	mov pot2,0h	;预置pot2=0代表ax为正
	mov cx,10	
	mov dx,0	;ax扩展待用
	cmp ax,0	;判断待输出的数字正负性		
	jns pov		;ax为正转
	mov pot2,'-'	
	neg ax		;将负数转换成对应相反数
pov:	idiv cx
	add dl,30h
	dec bx
	mov [bx+si],dl
	cmp ax,0
	jne not_end		
	jmp exit2
not_end:mov dx,0
	jmp pov
exit2:	dec bx
	mov al,pot2
	mov [bx+si],al	
	mov dx,bx
	mov ah,9
	int 21h	
	pop dx
	pop cx
	pop ds
	pop di
	pop si
	ret
pro2    ends	
num_char endp

;统计游戏有效时间的子程序
;入口参数:主程序记录上一当前时刻的hour,minute,second
;出口参数:子程序统计实际所用时间的zhour,zminute,zsecond
;注意每次重新启动计时功能前需将hour,minute,second即时化
tdata segment
	zhour db 0
	zminte db 0
	zsecond db 0
tdata ends
tstack segment stack
	db 100 dup(0)
tstack ends
tcode segment
	assume ds:tdata,ss:tstack,cs:tcode
time proc far

	push ax
	push bx
	push cx
	push dx

	mov ah,2ch	;读取当前时刻
	int 21h
	
	mov ah,ch	;存储当前时刻
	mov al,cl
	mov bh,dh

	cmp dh,second
	jns setsec	
	dec cl
	add dh,60
setsec:	sub dh,second	;设置秒数
	add zsecond,dh
	cmp zsecond,60
	jb dealmin
	sub zsecond,60
	inc zminute
dealmin:cmp cl,minute
	jns setmin
	del ch
	add cl,60
setmiu: sub cl,minute	;设置分钟数
	add zminute,cl
	cmp zminute,60
	jb dealhou
	sub zminute,60
	inc zhour
dealhou:cmp ch,hour
	jnb sethou
	add ch,24
sethou: sub ch,hour	;设置小时数
	add zhour,ch

	mov hour, ah
	mov minute,al
	mov second,dh

	pop dx
	pop cx
	pop bx
	pop ax
	ret
time endp
tcode ends
	

⌨️ 快捷键说明

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