我的游戏的控制冻结在第一个键击中INT 16h / ah = 1之后



我正在汇编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

您的 _KeyCheck 函数正在使用bios.readkeyboard status 函数。

如果没有可用键,它将通过设置Zeroflag(ZF(来通知您键盘键的可用性,或者如果键在等待时,请清除Zeroflag。在后一种情况下,您还将收到密钥的ASCII代码和scancode。
这里重要的是,可用的可用键保留在键盘缓冲区中。您在ALAH中获得的信息只是预览不是实际键(从某种意义上说(。这解释了您的观察:

...但是,如果在此之前按下任何其他键

解决方案是从键盘缓冲区中删除键。这就是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

请注意:

  • 您实际上并未检查Zeroflag以找出ALAH中的信息是否有效。
  • 数字1bh(esc(是ASCII代码,必须从AL检查,但所有其他代码48H(up(,50h(down(,4bh(左(和4DH(右(是scancodes,因此从AH进行检查。

您使用的是INT 16H,1。正如您在这里看到的那样,特殊键(如箭头(具有称为扫描代码的值,并且扫描代码在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下打印某些东西(

最新更新