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

📄 snake.asm

📁 汇编语言课程设计,贪吃蛇,使用DOS环境,用MASM2.0编译.此为贪吃蛇源代码.
💻 ASM
📖 第 1 页 / 共 4 页
字号:

	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
Load_File	endp
;*************************************
;将本局游戏的分数和历史分数进行排名
Set_Rank	proc	near
	push	ax
	push	bx
	push	cx

	lea	bx,Rank_ABC
Cmp_A:	mov	ax,[bx]
	cmp	ax,Gscore
;若本局分数和历史最高相等,则保持原顺序
;退出比较	
	jz	exit_cmp
;若本局分数比历史最高低,则和历史第二高比较
	ja	Cmp_B
;程序运行到此处,本局分数为历史最高,放在第一位
	mov	cx,[bx+2]
	mov	[bx+4],cx
	mov	cx,[bx]
	mov	[bx+2],cx
	mov	cx,Gscore
	mov	[bx],cx
	jmp	exit_cmp
Cmp_B:
	mov	ax,[bx+2]
	cmp	ax,Gscore
;若本局分数和历史第二高相等,则保持原顺序
;退出比较
	jz	exit_cmp
;若本局分数比历史第二高低,则和历史第三高比较
	ja	Cmp_C
;程序运行到此处,本局分数为历史第二高,放在第二位
	mov	cx,[bx+2]
	mov	[bx+4],cx
	mov	cx,Gscore
	mov	[bx+2],cx
	jmp	exit_cmp
Cmp_C:	
	mov	ax,[bx+4]
	cmp	ax,Gscore
;若本局分数比历史第三高低,则保持原顺序
;退出比较
	jae	exit_cmp
;程序运行到此处,本局分数为历史第三高,放在第三位
	mov	cx,Gscore
	mov	[bx+4],cx
exit_cmp:
	pop	cx
	pop	bx
	pop	ax
	ret
Set_Rank	endp
;**********************************
;查看游戏分数排名情况
View_Rank	proc	near
	push	ax
	push	bx
	push	dx
	push	cx
;关闭所有进入子菜单的'开关'
	mov	Direct_set3,0
	mov	Direct_set1,0
	mov	Direct_set2,0
;绘制第三项子菜单的窗口框架
;范围(200,200)-(330,265)
	mov	cx,200
	mov	al,0
INC_Cr:
	inc	cx
	mov	dx,200
INC_Dr:	inc	dx
	int	10h
	cmp	dx,264
	jnz	INC_Dr
	cmp	cx,329
	jnz	INC_Cr

	mov	al,10
	mov	cx,200
	mov	dx,200
line15r:
	int	10h
	inc	cx
	cmp	cx,330
	jnz	line15r
	mov	cx,200
	mov	dx,265
line16r:
	int	10h
	inc	cx
	cmp	cx,330
	jnz	line16r
	mov	dx,200
	mov	cx,200
line17r:
	int	10h
	inc	dx
	cmp	dx,265
	jnz	line17r
	mov	dx,200
	mov	cx,330
line18r:
	int	10h
	inc	dx
	cmp	dx,266
	jnz	line18r
;第三项子菜单的选项
;第一项'1-'
	mov	dh,13
	mov	dl,29
	mov	al,'1'
	call	View_Video
	inc	dl
	mov	al,'-'
	call	View_Video
	inc	dl
;第二项'2-'
	mov	dh,14
	mov	dl,29
	mov	al,'2'
	call	View_Video
	inc	dl
	mov	al,'-'
	call	View_Video
	inc	dl
;第三项'3-'
	mov	dh,15
	mov	dl,29
	mov	al,'3'
	call	View_Video
	inc	dl
	mov	al,'-'
	call	View_Video
	inc	dl
;显示游戏分数排名情况
;从文件中载入游戏信息,保存到内存缓冲区
	call	Load_File
	mov	bx,offset File_Area
	add	bx,12
;取出数据,并显示
;显示第一名
	mov	cx,[bx]
	mov	BTD,cx
	mov	Ctr_Jmp,0
	mov	H_Value,13
	mov	L_Value,31
	call	Bin_to_Dec
	add	bx,2
;显示第二名
	mov	cx,[bx]
	mov	BTD,cx
	mov	Ctr_Jmp,0
	mov	H_Value,14
	mov	L_Value,31
	call	Bin_to_Dec
	add	bx,2
;显示第三名
	mov	cx,[bx]
	mov	BTD,cx
	mov	Ctr_Jmp,0
	mov	H_Value,15
	mov	L_Value,31
	call	Bin_to_Dec
;等待用户的键盘信息,避免窗口一闪而过
	mov	ah,01h
	int	21h
	pop	cx
	pop	dx
	pop	bx
	pop	ax
	jmp	far	ptr	start
	ret
View_Rank	endp
;**********************************
;同用发声程序
;参见清华大学<<IBM-PC汇编语言程序设计>>第二版
;第286页
Soundf	proc	near
	push	ax
	push	bx
	push	cx
	push	dx
	push	di
	
	mov	dx,2000
	in	al,61h
	and	al,11111100b
Trig:	xor	al,2
	out	61h,al
	mov	cx,10000
Delay:	loop	Delay
	dec	dx
	jne	Trig
	
	pop	di
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
Soundf	endp
;**********************************
;绘制鼠标图案
Draw_Mouse	proc	near
	push	ax
	push	bx
	push	cx
	push	dx
	
	mov	ah,0ch
	mov	al,10
	mov	bh,0
	mov	cx,Mouse_X
	mov	dx,Mouse_Y
	call	draw_one_point

	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret	
Draw_Mouse	endp
;**********************************
;清除鼠标图案
Clear_Mouse	proc	near
	push	ax
	push	bx
	push	cx
	push	dx

	mov	ah,0ch
	mov	al,00
	mov	bh,0
	mov	cx,Mouse_X
	mov	dx,Mouse_Y
	call	draw_one_point
	
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret	
Clear_Mouse	endp
;**********************************
;检测鼠标状态
Scan_Mouse	proc	near
	push	ax
	push	bx
	push	cx
	push	dx
;限制鼠标水平活动范围
	mov	ax,7
	mov	cx,18
	mov	dx,466
	int	33h
;限制鼠标垂直活动范围
	mov	ax,8
	mov	cx,18
	mov	dx,466
	int	33h
;检测鼠标当前状态
	mov	bx,0
	mov     ax,3
        int     33h
;对鼠标的现实位置进行校准
	call	Balance_Shake
;保存扫描到的鼠标坐标
	mov	Mouse_X,cx
	mov	Mouse_Y,dx

;判断是否按下了鼠标的左键
cmp_bx_left:
	push	bx
	and	bx,1
	cmp	bx,1
	pop	bx
	jnz	cmp_bx_right
;当按下鼠标左键时设置Control_Kind=1
;表明当前由鼠标控制蛇的运动方向
;记录鼠标左键按下时鼠标的坐标,作为蛇移动的指定位置
	mov	Control_Kind,1
	mov	Mouse_Down_X,cx
	mov	Mouse_Down_Y,dx
;判断是否按下了鼠标的右键
;鼠标右键功能为'自动导航'
;即自动寻找食物
cmp_bx_right:	
	push	bx
	and	bx,2
	cmp	bx,2
	pop	bx
	jnz	exit_Scan_Mouse
;当鼠标右键功能时设置Control_Kind=1
;表明当前由鼠标控制蛇的运动方向
;记录食物的坐标,作为蛇移动的指定位置
        mov	Control_Kind,1
	mov	ax,Food
	mov	Mouse_Down_X,ax
	mov	ax,Food+2
	mov	Mouse_Down_Y,ax

exit_Scan_Mouse:
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret	
Scan_Mouse	endp
;**********************************
;在鼠标控制蛇运动方向的时候,设置
;坐标(CX,DX)的值
Set_the_CX_and_DX_Together	proc	near
	push	ax
	push	bx
	push	cx
	push	dx
	push	si
	push	di
;清空键盘控制的方向标志变量
	mov	Directive,0
	mov	ax,0
	add	ax,HalfPoint
	add	ax,HalfPoint
	mov	Mouse_Point,ax
;清空鼠标控制的方向标志变量
;以便进行下面的设置
	and	DirectiveM,0000h
;得到鼠标按下左键时候的坐标
	mov	ax,Mouse_Down_X
	mov	bx,Mouse_Down_Y
;得到蛇头的坐标
	mov	cx,snake_H
	mov	dx,snake_H+2
;在鼠标控制下,存放蛇头的坐标是否已经到达
;鼠标指定坐标附近的信息
	mov	Mouse_Snake_Meet,0
;开始判断蛇头是否在指定坐标附近
;附近的定义为:以指定坐标为中心,
;             上下左右12个像素单位的范围
	mov	si,ax
	mov	di,bx

	sub	si,cx
	jae	Test_di
	neg	si
Test_di:
	sub	di,dx
	jae	do_other
	neg	di
do_other:
;得到蛇头横纵坐标和指定位置的横纵座标的差的绝对值
;比较它们的值是否同时满足'附近'的定义
;如果满足,则设置Mouse_Snake_Meet为1
	cmp	si,12
	jae	Go_on_Judge
	cmp	di,12
	jae	Go_on_Judge
	mov	Mouse_Snake_Meet,1
;=============================================================
;DirectiveM 控制 CX 和 DX 的增减情况
;	0000	保持CX	保持Dx ,即指定的位置与蛇头的位置相同。
;	0001	保持CX	增加DX ,即指定的位置在蛇头的垂直下方。
;	0010	保持CX	减小DX ,即指定的位置在蛇头的垂直上方。
;
;	0100	增加CX	保持DX ,即指定的位置在蛇头的水平右方。
;	0101	增加CX	增加DX ,即指定的位置在蛇头的右下方。
;	0110	增加CX	减小DX ,即指定的位置在蛇头的右上方。
;
;	1000	减小CX	保持DX ,即指定的位置在蛇头的水平左方。
;	1001	减小CX	增加DX ,即指定的位置在蛇头的左下方。
;	1010	减小CX	减小DX ,即指定的位置在蛇头的左上方。
;=============================================================
Go_on_Judge:
;****judge
	cmp	ax,snake_H
	jb	DEC_CX
	cmp	ax,snake_H
	ja	INC_CX
	cmp	ax,snake_H
	je	NON_CX

DEC_CX:	or	DirectiveM,1000h
	jmp	CMP_DX	
INC_CX:	or	DirectiveM,0100h
	jmp	CMP_DX
NON_CX:	or	DirectiveM,0000h
	jmp	CMP_DX

CMP_DX:
	cmp	bx,snake_H+2
	jb	DEC_DX
	cmp	bx,snake_H+2
	ja	INC_DX
	cmp	bx,snake_H+2
	je	NON_DX

DEC_DX:	or	DirectiveM,0010h
	jmp	CX_DX
INC_DX:	or	DirectiveM,0001h
	jmp	CX_DX
NON_DX:	or	DirectiveM,0000h
	jmp	CX_DX

CX_DX:
	mov	ax,Mouse_Point
;****NON_DX
	cmp	DirectiveM,0000h
	jz	NON_CX_NON_DX
	cmp	DirectiveM,0100h
	jz	INC_CX_NON_DX
	cmp	DirectiveM,1000h
	jz	DEC_CX_NON_DX

	jmp	INCDX
NON_CX_NON_DX:	
		jmp	exit_Set_Together

INC_CX_NON_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing1
		add	Mouse_Down_X,ax
Nothing1:	add	cx,ax
		jmp	exit_Set_Together
DEC_CX_NON_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing2
		sub	Mouse_Down_X,ax
Nothing2:	sub	cx,ax
		jmp	exit_Set_Together

INCDX:
;****INC_DX
	cmp	DirectiveM,0001h
	jz	NON_CX_INC_DX	
	cmp	DirectiveM,0101h
	jz	INC_CX_INC_DX
	cmp	DirectiveM,1001h
	jz	DEC_CX_INC_DX

	jmp	DECDX

NON_CX_INC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing3
		add	Mouse_Down_Y,ax
Nothing3:	add	dx,ax
		jmp	exit_Set_Together
		
INC_CX_INC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing4
		add	Mouse_Down_X,ax
		add	Mouse_Down_Y,ax
Nothing4:	add	cx,ax
		add	dx,ax
		jmp	exit_Set_Together

DEC_CX_INC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing5
		sub	Mouse_Down_X,ax
		add	Mouse_Down_Y,ax
Nothing5:	sub	cx,ax
		add	dx,ax
		jmp	exit_Set_Together

DECDX:
;****DEC_DX
	cmp	DirectiveM,0010h
	jz	NON_CX_DEC_DX
	cmp	DirectiveM,0110h
	jz	INC_CX_DEC_DX
	cmp	DirectiveM,1010h
	jz	DEC_CX_DEC_DX

NON_CX_DEC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing6
		sub	Mouse_Down_Y,ax
Nothing6:	sub	dx,ax
		jmp	exit_Set_Together

INC_CX_DEC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing7
		add	Mouse_Down_X,ax
		sub	Mouse_Down_Y,ax
Nothing7:	add	cx,ax
		sub	dx,ax
		jmp	exit_Set_Together

DEC_CX_DEC_DX:	cmp	Mouse_Snake_Meet,0
		jz	Nothing8
		sub	Mouse_Down_X,ax
		sub	Mouse_Down_Y,ax
Nothing8:	sub	cx,ax
		sub	dx,ax
		jmp	exit_Set_Together
;============================================
;    鼠标指定位置的座标和蛇头坐标的关系说明
;    当蛇头没有在指定范围内出现的时候,CX和DX的
;增减情况由DirectiveM数据表给出
;    当蛇头在指定范围内出现的时候,CX和DX的增减
;情况依然由DirectiveM数据表给出,同时指定坐标的
;横纵坐标值的增减情况也和CX与DX的增减情况相同
;    这样做是为了解决蛇移动到指定目标之后就立刻
;死亡的情况.
;============================================
exit_Set_Together:
;设定蛇头坐标
	mov	snake_H,cx
	mov	snake_H+2,dx
	mov	snake_B,cx
	mov	snake_B+2,dx
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
Set_the_CX_and_DX_Together	endp
;**********************************
;鼠标位置校准函数
;游戏中出现的方块的中心必须遵守这样的
;规则:
;横坐标减去2之后可以被8整除
;中坐标可以直接被8整除
Balance_Shake	proc	near
	push	ax
	push	bx
	
;校准横坐标
	mov	ax,cx
	sub	ax,2
	and	ax,0007h
	sub	cx,ax
;校准纵坐标
	mov	ax,dx
	and	ax,0007h
	sub	dx,ax

	pop	bx
	pop	ax
	ret
Balance_Shake	endp
;**********************************.
;游戏结束时显示的信息'Game Over'
Dead_Msg	proc	near
	push	ax
	push	dx
	mov	dh,14
	mov	dl,26
	mov	al,'G'
	call	View_Video
	inc	dl
	mov	al,'a'
	call	View_Video
	inc	dl
	mov	al,'m'
	call	View_Video
	inc	dl
	mov	al,'e'
	call	View_Video
	inc	dl
	mov	al,' '
	call	View_Video
	inc	dl
	mov	al,' '
	call	View_Video
	mov	al,'O'
	call	View_Video
	inc	dl
	mov	al,'v'
	call	View_Video
	inc	dl
	mov	al,'e'
	call	View_Video
	inc	dl
	mov	al,'r'
	call	View_Video

	call	Waitf
	call	Waitf
	call	Waitf
	call	Waitf
	call	Waitf
	call	Waitf

	pop	dx
	pop	ax
	ret
Dead_Msg	endp
;*************************************
;按下'q'键时显示的信息'Save Information'
Quit_Msg	proc	near
	push	ax
	push	dx
	mov	dh,14
	mov	dl,26
	mov	al,'S'
	call	View_Video
	inc	dl
	mov	al,'a'
	call	View_Video
	inc	dl
	mov	al,'v'
	call	View_Video
	inc	dl
	mov	al,'e'
	call	View_Video
	inc	dl
	mov	al,' '
	call	View_Video
	inc	dl
	mov	al,' '
	call	View_Video
	mov	al,'I'
	call	View_Video
	inc	dl
	mov	al,'n'
	call	View_Video
	inc	dl
	mov	al,'f'
	call	View_Video
	inc	dl
	mov	al,'o'
	call	View_Video
	inc	dl
	mov	al,'r'
	call	View_Video
	inc	dl
	mov	al,'m'
	call	View_Video
	mov	al,'a'
	call	View_Video
	inc	dl
	mov	al,'t'
	call	View_Video
	inc	dl
	mov	al,'i'
	call	View_Video
	inc	dl
	mov	al,'n'
	call	View_Video
	
	call	Waitf
	call	Waitf
	call	Waitf
	call	Waitf
	call	Waitf
	pop	dx
	pop	ax
	ret
Quit_Msg	endp
code	ends
	end
 

⌨️ 快捷键说明

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