第一次按键后,我的游戏控制冻结,持续时间为int 16h/ah = 1 [英] The controls of my game freeze after the first keypress with int 16h / ah=1
问题描述
我正在用程序集8086编写游戏.我修复了游戏无法打开时的问题,但无法修复控件.
I am coding a game in assembly 8086. I fixed the issue when the game didn't open, but I can't fix the controls.
ESC 键起作用.当我按下它时,它会进入 _QUIT 功能,但是如果在此之前按下任何其他键,控件将冻结并且不会对任何键做出反应.
The ESC key works. When I press it, it goes to _QUIT function, but if any other key was pressed before that, the controls freeze and don't react on any key.
我的功能有问题吗?
我试图将AL
寄存器更改为AH
,但是没有用.
I tried to change the AL
register to AH
, but it didn't work.
_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
推荐答案
您的 _KEYCHECK 函数正在使用BIOS.ReadKeyboard状态函数.
Your _KEYCHECK function is using the BIOS.ReadKeyboardStatus function.
如果没有可用的按键,它会通过设置ZeroFlag(ZF)来通知您有关键盘按键的可用性,或者如果有一个按键在等待中,则会通过清除ZeroFlag来通知您.在后一种情况下,您还将收到密钥的ASCII码和扫描码.
重要的是,报告的可用键保留在键盘缓冲区中.在AL
和AH
中获得的信息只是预览,而不是实际的键(在某种意义上).这解释了您的观察:
It will inform you about the availability of a keyboard key by setting the ZeroFlag (ZF) if no key is available, or by clearing the ZeroFlag if a key is waiting. In the latter case you will also receive the key's ASCII code and scancode.
The important thing here is that a key that is reported available stays in the keyboard buffer. The info that you get in AL
and AH
is just a preview not the actual key (in a sense). This explains your observation:
...但是如果在此之前按下了其他任何键,则控件将释放...
... but if any other key was pressed before that the controls frees ...
解决方案是从键盘缓冲区中删除键.这就是BIOS.ReadKeyboard 字符的功能.如果某个键在等待,它将很快从缓冲区中删除该键的情况下返回.如果没有可用的密钥,它将等到一个可用的密钥之后再返回,并从缓冲区中删除该密钥.
The solution is to remove the key from the keyboard buffer. That's what BIOS.ReadKeyboardCharacter does. If a key is waiting it will return very quickly with the key removed from the buffer. If no key is available it will wait until one comes available and then return with that key removed from the buffer.
_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
请注意:
- 您实际上并没有检查ZeroFlag来确定
AL
和AH
中的信息是否有效. - 数字1Bh(ESC)是ASCII码,必须从
AL
中进行检查,但是其他所有代码48h(UP),50h(DOWN),4Bh(LEFT)和4Dh(RIGHT)都是扫描代码,因此必须从AH
检查.
- You didn't actually inspect the ZeroFlag to find out if the info in
AL
andAH
was valid. - The number 1Bh (ESC) is an ASCII code and has to be checked from
AL
but all the other codes 48h (UP), 50h (DOWN), 4Bh (LEFT), and 4Dh (RIGHT) are scancodes and thus have to be checked fromAH
.
这篇关于第一次按键后,我的游戏控制冻结,持续时间为int 16h/ah = 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!