前言:
随便说说:最近闲得蛋疼,然后之前《汇编语言》看了一遍,没怎样具体写过东西,就想着来用汇编写个贪食蛇吧(话说大一就想写过,想不到是到了大二才完成,还是用汇编写的。。。)
代码可以点这里下载
P.S.由于CPU差异,初始速度可能有差异,可以通过调节速度(开始页面按a)
程序:贪食蛇
环境:masm+dosbox+windows(有doxbox基本win的系统都一样)
功能:(或者说要实现的东西)
1.控制蛇方向
2.蛇撞墙或者撞到自己身体会死
3.蛇吃到食物会长一个身体
4.食物随机出现,但不能出现在蛇的身体中或者墙里面
5.开始游戏前可以调节速度
6.游戏结束时提示分数以及速度
P.S.最后成品有个bug,就是食物随机出现那里(下面说)
下面来根据上面6点逐个解释:
分析:
1.控制蛇方向
先把其分割成几个步骤:
1.检测用户是否按键:有->3 没有->2
2.保持原方向
3.获取盖按键,并判断该按键是否合法(合法按键:w/s/a/d)合法->5 不合法->4
4.保持原方向
5.修改方向(注意:只是修改方向,蛇身体还没动)
检测用户是否按键:采用中断
mov ax,0b00h
int 21h
这个中断只能用来检测是否有输入而并不能获取输入的按键
因此还需要另一个中断来获取按键:
mov ah,07h
int 21h
注意上面描述中,是等待输入,因此不判断是否有输入而是直接采用这个中断就会造成整个程序停在那里等待输入,因为是个单线程程序
下面是我贪食蛇中代码:
;if input the key,then return the key value
;al: the key value
;ah: ff:true 0:false
check_get_input proc
mov ax,0b00h
int 21h
mov ah,0h
cmp al,0ffh
jne finish_cgi
mov ah,07h
int 21h
mov ah,0ffh
finish_cgi:
ret
check_get_input endp
还有个关键就是方向的修改,这个算整个程序核心。。。
2、3
把这2个放在一起讲,是因为它们的关键都一样(就是修改方向的那个)
首先,控制蛇方向、蛇撞墙、蛇长身体这些的前提,必须是分清除哪些是蛇身体,哪些是墙,哪些是空白地方,给用户分辨就是很简单的颜色不同来区分,但程序如何区分?
由于我这是通过显示缓冲区来显示,而且修改后不能从内存缓冲区获取原来的信息,因此必须用另外的方法来记录,我一开始想到的是用链表来记录,不过用汇编来实现一个链表好像也挺大过程的,那就算了,就用最普通的建一个图(map)来记录各种信息:
map db 2000 dup('0')
因为是25*80所以就是2000
P.S.这个空间可以缩小,因为一共就3种情况(食物我没有记录)所以用2bit就可以,但是这个后面的比较又比较麻烦所以算了。。。
.1地址转换
采用map的话,还需要一个实际图和map之间的转化(由于实际图,也就是显示缓冲区中,是用2byte来表示一格,而map使用1byte来表示),又由于8086的地址格式是:
segment:[offset]
最后地址=segment*16+offset
因此要先把地址组合起来,再减去0b800h(显示缓冲区起始地址),获得偏移值再除以2,获得最终的偏移值,最后加上map的起始地址就完成了地址的转换
;convert the true