作为学校项目的一部分,我正在尝试制作蛇游戏。到目前为止,我设法绘制了一个像素并使它使用a,w,s,d键作为箭头移动。我的问题是,我的蛇不等仅在按下某个键时移动并改变方向,而是等待按键(这意味着暂停整个程序),然后才继续移动。据我了解,我一直在使用错误的中断(int 16h \ 00),我想知道我可以使用哪些其他中断。
我已经尝试了int 16h \ 01,但它所做的只是一次改变了方向,然后继续朝该方向移动。
这是我代码中负责更改像素位置的部分:
proc check_press
; check for a key press
mov ah,0
int 16h
;check what key
check_key:
cmp al,119
je down
cmp al,97
je left
cmp al,100
je right
cmp al,115
je up
cmp al, 27
je escape
up:
inc [y]
jmp bye
left:
dec [x]
jmp bye
down:
dec [y]
jmp bye
right:
inc [x]
jmp bye
escape:
mov ah, 0
mov al, 2
int 10h
bye:
ret
endp check_press
我要感谢任何想法的人,或者即使有人曾经在汇编中编写过蛇游戏,也会有很大帮助
答案 0 :(得分:3)
我已经尝试了int 16h \ 01,但它所做的只是一次改变了方向,然后继续朝该方向移动。
Ralph Brown's interrupt list包含几乎所有MS-DOS和BIOS中断的描述。
本页上关于int 16h
,功能01
的描述是:
...
返回:
如果没有可用的击键,则设置ZF
ZF清除是否有按键操作
AH = BIOS扫描代码
AL = ASCII字符注意:如果存在击键,则不会从键盘缓冲区中将其移除
...
这意味着该函数将返回AX中的值,该值表示以后调用函数00
时将返回的值。
假设您按下“ A”,“ B”,“ C”和“ D”键,并且您没有调用任何int 16h
函数。稍后,您将函数00
调用四次。在这种情况下,您希望第一次返回“ A”,第二次返回“ B”,第三次返回“ C”,第四次返回“ D”。
如果在第一次调用函数01
之前调用函数00
,该函数将始终返回“ A”(尽管稍后您按了“ B”,“ C”和“ D”),因为函数00
在下次调用时将返回“ A”。
如果您不调用函数00
,则函数01
将永远返回“按键'A'被按下”。
如果函数int 16h
返回了00
,您必须调用01
,函数ZF=clear
:
mov ah, 1
int 16h
jz noKeyPressed
mov ah, 0
int 16h
; AX contains information about the key pressed
...
noKeyPressed:
...
答案 1 :(得分:2)
通常,您希望蛇自行移动,而不是在您按向左键时向左移动一个方块。因此,您应该设置方向变量,而不要修改x
或y
。您的整个设计都是基于这种“按动”行为构建的,因此您必须重写很多设计。
您可能想在蛇更新之前使用非阻塞键盘读取来检查键盘输入。或钩住键盘中断并从那里更新方向变量。
您可以使用hlt
睡觉直到下一个中断(例如计时器或键盘),然后醒来,看看是否该重绘蛇了。
另一种选择可能是从计时器中断中提取蛇,但是在中断处理程序中做很多工作是不好的。