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

📄 snake.asm

📁 汇编语言课程设计,贪吃蛇,使用DOS环境,用MASM2.0编译.此为贪吃蛇源代码.
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;****************************************************************
;		设计进程					;
;2006-01-02:实现了基本的图像框架,蛇的初始化			;
;2006-01-04:增加了蛇的移动,食物的随机出现,取得系统日期、时间。;
;2006-01-04:增加了计分,显示速度,显示系统日期、时间,游戏进行时;
;	    间和相关版本信息					;
;2006-01-05:增加了菜单功能					;
;2006-01-06:增加了文件系统和显示排名				;
;2006-01-07:增加了鼠标功能,鼠标改变方向在设计中		;
;2006-01-08:增加了鼠标改变方向的功能				;
;	    修改了蛇身抖动问题					;
;	    增加了自动导航功能					;
;	    所有程序注释使用中文				;
;	    程序部分总行数2600行				;
;								;
;       开放源码,共同学习,共同进步!				;
;     在别处引用\发表请注明出处,谢谢!				;
;								;
;								;
;				         2006-01-08		;
;                                           悠落		;
;****************************************************************
title	Snake Game
;贪吃蛇游戏
;***********************************
data	segment
;游戏分数
	even
	Gscore	dw	0
;===================================
;记录蛇身体坐标的数组
	even
	snake_B dw	1000 dup(4)

;记录数组snake_B的偏移地址
	even
	temp	dw	snake_B

;记录组成蛇身体的方格数
	even
	count	dw	24

;记录蛇头坐标
	even
	snake_H	dw	?,?
;===================================
;方向控制变量
;****Directive =01h,to left
;****          =02h,to right
;****          =03h,to top
;****          =04h,to bottom
;默认值是03h,向上
	Directive	db	03h
;单击鼠标的位置相对蛇头的方位控制
	DirectiveM	dw	?
;判断蛇头是不是和蛇身体相遇
;****Comparison=00h,没有相遇
;****          =11h,相遇
	Comparison	db	00h
;===================================
;食物的坐标
	even
	Food	dw	18,16
;生成食物横坐标的随机种子,有百分之一秒数生成
	Foodt	db	?
;===================================
;前进速度
	even
	Speed	dw	?
;===================================
;半个方格的宽度
	even
	HalfPoint	dw	2
;用于在游戏中改变方格的大小
	TempHalf	dw	2
;用于记录当前坐标-HalfPoint之后的值
;在绘制方格的时候用到
	TempPoint	dw	?
;方格的颜色
	PointColor	db	10
;===================================
;系统时间
	even
	SysYear		dw	?
	SysData		db	?,?
	SysTime		db	?,?,?,?
;游戏时间
;开始时间,用dl确定Foodt的初值
	StartTime	db	?,?,?,?
	GameTime	dw	0
;===================================
;二进制到十进制转换并输出函数的参数
	even
;记下要转换并输出的数据
	BTD	dw	0
;用于控制转换的上限
;Ctr_Jmp=0时转换输出5位的十进制数
;        1时转化输出2位的十进制数
	Ctr_Jmp	db	0
;控制输出的位置
	H_value	db	0
	L_value	db	0
;===================================
;记录系统间的秒数,用于和当前系统时间的秒数相比较
;如果相同,则游戏时间不增加,否则游戏时间增加一秒并显示
	Time_temp	db	?
;===================================
;菜单控制变量,默认只显示主菜单
;控制进入主菜单的4号功能下一层
	Direct_set1	db	0
;控制进入主菜单的4号功能下一层的下一层
	Direct_set2	db	0
;控制进入排名察看菜单
	Direct_set3	db	0
;控制在4号功能菜单中,是设置count还是color
	Ctrl_set	db	0
;===================================
;File_Name_ASC文件名
;File_Area向文件存取的空间大小
;Rank_ABC存放历史最高三位分数
;File_Handle文件句柄
	File_Name_ASC	db	7 dup(0)
	File_Area	dw	9 dup(?)
	Rank_ABC	dw	3 dup(0)
	File_Handle	dw	?
;===================================
;当前鼠标坐标(X,Y)
;Mouse_Point的大小是HalfPoint两倍,在鼠标控制的
;CX_DX函数中用到
;鼠标左键按下时的(X,Y)
;蛇移动时的指定位置的坐标
	Mouse_X		dw	?
	Mouse_Y		dw	?
	Mouse_Point	dw	?
	Mouse_Down_X	dw	?
	Mouse_Down_Y	dw	?
;判断鼠标左键按下的坐标是否和蛇头的坐标不远
	Mouse_Snake_Meet	db	?
;===================================
;鼠标键盘控制判断变量
;****Control_Kind=0,键盘
;****Control_Kind=1,鼠标
	Control_Kind	db	0
data	ends	
;***********************************
code 	segment
	assume cs:code,ds:data,es:data
main	proc	far
;set the DS And ES
	mov	ax,data
	mov	ds,ax
	mov	es,ax
start:
	call	draw_the_game_area
	call	Show_Menu

;取得游戏环境初始化信息
	call	Get_some_information
	call	Get_time
	call	draw_the_snake
	call	Creat_a_random_mark
	call	draw_the_food
;显示相关信息
	call	Print_score
	call	Print_speed
	call	Print_data
	call	Print_time
	call	Print_SysTime
	call	Print_GameTime
	call	Print_Copyright
;游戏开始,蛇在游戏区域移动
	call	move_the_snake	
exit:
	mov	ax,4c00h
	int	21h
main	endp
;***********************************
;信息取得和游戏环境初始化
Get_some_information	proc	near
;获取游戏开始时间,初始化Foodt和Time_temp
;为产生一随机坐标的横坐标和记录有戏时间做准备
	mov	ah,2ch
	int	21h
	mov	StartTime,ch
	mov	StartTime+1,cl
	mov	StartTime+2,dh
	mov	StartTime+3,dl
	mov	Time_temp,dh
	mov	Foodt,dl
;取得系统年月日信息
	mov	ah,2ah
	int	21h
	mov	SysYear,cx
	mov	SysData,dh
	mov	SysData+1,dl	
;取得当前游戏速度,并显示在界面上
	mov	bx,Speed
	mov	ax,0ffffh
	sub	ax,bx
	mov	BTD,ax
	mov	H_value,9
	mov	L_value,66
	mov	Ctr_Jmp,0
	call	Bin_to_Dec
;在每局游戏开始的时候设置方格的大小
;由上一局中按M和N键控制
	mov	ax,TempHalf
	mov	HalfPoint,ax
;设置控制的方式,默认为键盘
	mov	Control_Kind,0
;在界面上显示游戏分数
	mov	ax,Gscore
	mov	BTD,ax
	mov	H_value,3
	mov	L_value,66
	mov	Ctr_Jmp,0
	call	Bin_to_Dec
	ret
Get_some_information	endp
;***********************************
;绘制游戏界面
draw_the_game_area	proc	near
;设置显示方式,640*480,16色
	mov	ah,0
	mov	al,12h
	int	10h
;画游戏界面的框架,范围(10,10)-(630,470)
;边框颜色使用10 ,翠绿色
	mov	ah,0ch
	mov	al,10
	mov	bh,0
;顶部横线
	mov	cx,10
	mov	dx,8
top1:	int	10h
	inc	cx
	cmp	cx,630
	jnz	top1

;底部横线
	mov	cx,10
	mov	dx,470
buttom2:	
	int	10h
	inc	cx
	cmp	cx,630
	jnz	buttom2

;左边竖线
	mov	cx,10
	mov	dx,8
left3:	int	10h
	inc	dx
	cmp	dx,470
	jnz	left3

;右边竖线
	mov	cx,630
	mov	dx,8
right4:	int	10h
	inc	dx
	cmp	dx,470
	jnz	right4

;中间分割线,左边游戏区域,右边信息区域
;游戏区域(10,10)-(470,470)
	mov	cx,470
	mov	dx,8
mid5:	int	10h
	inc	dx
	cmp	dx,470
	jnz	mid5
;信息区域分割线
	mov	cx,470
	mov	dx,102
line1:
	int	10h
	inc	cx
	cmp	cx,630
	jnz	line1

	mov	cx,470
	mov	dx,194
line2:
	int	10h
	inc	cx
	cmp	cx,630
	jnz	line2

	mov	cx,470
	mov	dx,286
line3:
	int	10h
	inc	cx
	cmp	cx,630
	jnz	line3

	mov	cx,470
	mov	dx,378
line4:
	int	10h
	inc	cx
	cmp	cx,630
	jnz	line4
	ret
draw_the_game_area	endp
;*******************************************
;初始化蛇在游戏中出现的位置
draw_the_snake	proc	near
	mov	ah,0ch
	mov	al,10
	mov	bh,0
	mov	di,offset snake_B
;每次蛇头在游戏区域中出现的位置(210.280)	
	mov	cx,210
	mov	dx,280
	mov	snake_H,cx
	mov	snake_H+2,dx
;蛇头坐标就是蛇身体的第一个方块的坐标
	mov	[di],cx
	add	di,2
	mov	[di],dx
	add	di,2
	call	draw_one_point
	ret
draw_the_snake	endp
;***********************************
;绘制食物
draw_the_food	proc	near
	mov	ah,0ch
	mov	al,12
	mov	bh,0
	mov	cx,Food
	mov	dx,Food+2
	call	draw_one_point
	ret
draw_the_food	endp
;************************************
;蛇的移动
move_the_snake	proc	near
move_to_next:
;将原来的蛇像擦除
	mov	di,offset snake_B
	add	di,count
re_move:
	call	Remove_the_old_body	
	sub	di,4	
	cmp	di,temp
	jg	re_move
;设定蛇身体的坐标
	mov	di,offset snake_B
	add	di,count
go_forward_one_point:
	mov	si,[di-4]
	mov	[di],si
	mov	si,[di-2]
	mov	[di+2],si
	sub	di,4
	cmp	di,temp
	jg	go_forward_one_point
;在新的位置绘制蛇像
	mov	di,offset snake_B
	add	di,count
re_draw:
	call	Redraw_the_new_body
	sub	di,4	
	cmp	di,temp
	jg	re_draw
;扫描键盘按键,检测鼠标信息
	call	KeyBoard_Control
	call	Scan_Mouse
;输出当前速度
	mov	bx,Speed
	mov	ax,0ffffh
	sub	ax,bx
	mov	BTD,ax
	mov	H_value,9
	mov	L_value,66
	mov	Ctr_Jmp,0
	call	Bin_to_Dec
	
;输出时间
	call	Get_time
	call	Print_SysTime
;判断蛇是否吃到食物
	call	Judeg_meet
;一段时间延迟
	push	cx
	mov	cx,Speed 
	call	Draw_Mouse
	call	Waitf
	call	Clear_Mouse
	pop	cx
	call	draw_the_food
;CX增减表示蛇在水平方向有移动
;DX增减表示蛇在垂直方向有移动
;CX增加----向右    CX减小----向左
;DX增加----向下    DX减小----向上
;判断当前是由键盘控制还是由鼠标控制
;Control_Kind=0,键盘控制
;Control_Kind=1,鼠标控制
	cmp	Control_Kind,0
	jnz	Together_CX_DX
	call	Set_the_CX_and_DX
	jmp	fffff
Together_CX_DX:
	call	Set_the_CX_and_DX_Together
fffff:
;判断蛇是否死亡
	call	Judge_dead
	ret
move_the_snake	endp
;***********************************
;设置键盘控制方向的时候,CX,DX的增减情况
Set_the_CX_and_DX	proc	near
	mov	cx,snake_H
	mov	dx,snake_H+2
	cmp	Directive,01h
	jz	left1
	cmp	Directive,02h
	jz	right2
	cmp	Directive,03h
	jz	up3
	cmp	Directive,04h
	jz	down4
	jmp	exit_set
;这里减两次HalfPoint才是一个方块的单位
left1:	sub	cx,HalfPoint	
	sub	cx,HalfPoint
	jmp	exit_set
right2:	add	cx,HalfPoint
	add	cx,HalfPoint
	jmp	exit_set
up3:	sub	dx,HalfPoint
	sub	dx,HalfPoint
	jmp	exit_set
down4:	add	dx,HalfPoint
	add	dx,HalfPoint
exit_set:
;设置此时的蛇头坐标
	mov	snake_H,cx
	mov	snake_H+2,dx
	mov	snake_B,cx
	mov	snake_B+2,dx
	ret
Set_the_CX_and_DX	endp
;***********************************
;蛇像擦除函数
Remove_the_old_body	proc	near
	mov	ah,0ch
	mov	al,00h	
	mov	bh,0
	mov	cx,[di]
	mov	dx,[di+2]
	call	draw_one_point
	ret
Remove_the_old_body	endp
;***********************************
;蛇像绘制函数
Redraw_the_new_body	proc	near
	mov	ah,0ch
	mov	al,PointColor
	mov	bh,0
	mov	cx,[di]
	mov	dx,[di+2]
	call	draw_one_point
	ret
Redraw_the_new_body	endp
;************************************
;80x86 PC的时间延迟函数
;参见清华大学<<IBM-PC汇编语言程序设计>>第二版
;第390页
Waitf	proc	near
	push	ax
waitf1:
	in	al,61h
	and	al,10h
	cmp	al,ah
	je	waitf1
	mov	ah,al
	loop	waitf1
	pop	ax
	ret
Waitf	endp

;************************************
;键盘扫描函数
KeyBoard_Control	proc	near
	push	ax
	mov	dl,0ffh
	mov	ah,06h
	int	21h
;扫描键盘
	cmp	al,'a'
	jz	left
	cmp	al,'d'
	jz	right
	cmp	al,'w'
	jz	up
	cmp	al,'s'
	jz	down
	jmp	next_cmp1
;判断方向键
;按下方向键的时候,设置控制标志变量Control_Kind
;为0,关闭鼠标右键功能
;设置方向控制变量Directive的时候,首先判断当向蛇
;的运动方向时候和现在要设置的方向相反.
;避免失误按下反方向键造成死亡
left:	mov	Control_Kind,0
	cmp	Directive,02h
	jz	exit_control0
	mov	Directive,01h
	jmp	exit_control0
right:	mov	Control_Kind,0
	cmp	Directive,01h
	jz	exit_control0
	mov	Directive,02h
	jmp	exit_control0
up:	mov	Control_Kind,0
	cmp	Directive,04h
	jz	exit_control0
	mov	Directive,03h
	jmp	exit_control0
down:	mov	Control_Kind,0
	cmp	Directive,03h
	jz	exit_control0
	mov	Directive,04h
	jmp	exit_control0
exit_control0:
	jmp	exit_control
;继续判断其他控制键
next_cmp1:
	cmp	al,'+'
	jz	faster
	cmp	al,'-'
	jz	slower
	cmp	al,'p'
	jz	Pause
	cmp	al,'m'
	jz	Max_er
	cmp	al,'n'
	jz	Min_er
;Q为保存当前游戏环境设置并退出游戏到菜单界面
	cmp	al,'q'
	jz	exit_main
	jmp	exit_control0
exit_main:
	call	Quit_Msg
	call	Save_File
;保存设置后初始化新游戏的数据
	mov	Speed,16572
	mov	GameTime,0
	mov	Gscore,0
	mov	count,24
	jmp	far ptr	start
;"+"增加前进速度
faster:	mov	ax,Speed
	sub	ax,1000
	mov	Speed,ax
	jmp	exit_control
;"-"减小前进速度
slower:	mov	ax,Speed
	add	ax,1000
	mov	Speed,ax
	jmp	exit_control
;"p"暂停游戏,直到再次按下"p"
Pause:	mov	ah,08h
	int	21h
	cmp	al,'p'
	jnz	Pause
	jmp	exit_control
;"m","n",设计下一局游戏中方块的大小
;由大\中\小三种设置
Max_er:	mov	ax,HalfPoint
	cmp	ax,1
	jz	To_2
	cmp	ax,2
	jz	To_4
	jmp	exit_control
Min_er:	mov	ax,HalfPoint
	cmp	ax,4
	jz	To_2
	cmp	ax,2
	jz	To_1
	jmp	exit_control
To_1:	mov	TempHalf,1
	jmp	exit_control
To_2:	mov	TempHalf,2
	jmp	exit_control
To_4:	mov	TempHalf,4
	jmp	exit_control
exit_control:
	pop	ax
	ret
KeyBoard_Control	endp
;************************************	
;判断蛇时候死亡的函数
Judge_dead	proc	near
;判断蛇头的坐标是否超出了游戏区域(10,10)-(470,470)
	mov	cx,snake_H
	mov	dx,snake_H+2
	cmp	cx,470
	jae	exit_move
	cmp	cx,10
	jbe	exit_move
	cmp	dx,10
	jbe	exit_move
	cmp	dx,470
	jae	exit_move
	mov	di,offset snake_B
	add	di,count
;判断当前游戏由鼠标还是键盘控制方向
;为了降低鼠标控制方向时的难度
;设置 鼠标控制 的时候,蛇遇到自己身体时候不死亡
	cmp	Control_Kind,0
	jz	cmp_body
	jmp	move_to_next
;键盘控制的时候,蛇遇到自己的身体时死亡
cmp_body:
;逐个比较蛇头坐标和身体坐标
Compar:	cmp	cx,[di]
	jnz	Reset
;当横坐标相同的时候Comparison和10H相或,继续比较纵坐标
;不同的时候,和下一组坐标比较
	or	Comparison,10h
	cmp	dx,[di+2]
	jnz	Reset
;当纵坐标相同的时候Comparison和01H相或
;不同的时候,和下一组坐标比较
	or	Comparison,01h
;判断Comparison的值
;若为11H,表示蛇头坐标和身体的某个坐标相同
;则推出游戏到菜单界面
;否则设置Comparison为0,继续比较下一组坐标
;直到和蛇身坐标比较完毕
;比较从蛇尾向蛇头进行
	cmp	Comparison,11h	
	jz	exit_move
Reset:	and	Comparison,00h		
	sub	di,4
	cmp	di,temp
	jg	Compar
	jmp	move_to_next
exit_move:
;退出游戏到菜单界面的时候显示结束信息
;发出结束警报声音
;当前的游戏分数和历史游戏分数比较,排名
;初始化下一次游戏数据
	call	Soundf
	call	Dead_Msg
	call	Set_Rank
	mov	Speed,16572
	mov	GameTime,0
	mov	Gscore,0
	mov	count,24
	call	Save_File
	jmp	far	ptr	start
	ret
Judge_dead	endp
;************************************	

⌨️ 快捷键说明

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