我正在用程序集8086编写游戏。我修复了游戏无法打开时的问题,但无法修复控件。
ESC 键起作用。当我按下它时,它会进入 _QUIT 功能,但是如果在此之前按下任何其他键,控件将冻结并且不会对任何键做出反应。
我的功能有问题吗?
我试图将AL
寄存器更改为AH
,但是没有用。
_KEYCHECK:
mov ah,01h
int 16h
cmp al,1Bh ;ESC
je _QUIT
cmp al,48h ;UP
je _PLAYER.UP
cmp al,50h ;DOWN
je _PLAYER.DOWN
cmp al,4Bh ;LEFT
je _PLAYER.LEFT
cmp al,4Dh ;RIGHT
je _PLAYER.RIGHT
ret
答案 0 :(得分:3)
您的 _KEYCHECK 功能正在使用BIOS.ReadKeyboard 状态功能。
如果没有可用的按键,它会通过设置ZeroFlag(ZF)来通知您有关键盘按键的可用性,或者如果有一个按键在等待中,则会通过清除ZeroFlag来通知您。在后一种情况下,您还将收到密钥的ASCII码和扫描码。
重要的是,报告的可用键保留在键盘缓冲区中。在某种意义上,您在AL
和AH
中获得的信息只是预览而不是实际的密钥。这解释了您的观察:
...但是如果在此之前按下了其他任何键,则控件将释放...
解决方案是从键盘缓冲区中删除键。这就是BIOS.ReadKeyboard 字符的功能。如果某个键在等待,它将很快从缓冲区中删除该键而返回。如果没有可用的密钥,它将等到一个可用的密钥之后再返回,并从缓冲区中删除该密钥。
_KEYCHECK:
mov ah, 01h ; BIOS.ReadKeyboardStatus
int 16h ; -> AX ZF
jz NoKeyAvailable
mov ah, 00h ; BIOS.ReadKeyboardCharacter
int 16h ; -> AX
cmp al, 1Bh ;ESC
je _QUIT
cmp ah, 48h ;UP
je _PLAYER.UP
cmp ah, 50h ;DOWN
je _PLAYER.DOWN
cmp ah, 4Bh ;LEFT
je _PLAYER.LEFT
cmp ah, 4Dh ;RIGHT
je _PLAYER.RIGHT
NoKeyAvailable:
ret
请注意:
AL
和AH
中的信息是否有效。AL
中进行检查,但是所有其他代码48h(UP),50h(DOWN),4Bh(LEFT)和4Dh(RIGHT)都是扫描码,因此必须从AH
中进行检查。答案 1 :(得分:1)
您正在使用int 16h,1。 如您所见here,特殊键(如箭头)的值称为扫描代码,并且扫描代码以ah返回。试试
mov ah,01h
int 16h
cmp al,1Bh ;ESC
je _QUIT
cmp ah,48h ;UP
je _PLAYER.UP
cmp ah,50h ;DOWN
je _PLAYER.DOWN
cmp ah,4Bh ;LEFT
je _PLAYER.LEFT
cmp ah,4Dh ;RIGHT
je _PLAYER.RIGHT
如果那不起作用,建议您调试并检查问题是否在其他地方(例如,尝试在_PLAYER.UP下打印内容)