第一次按键后,我的游戏控制冻结,持续时间为int 16h/ah = 1 [英] The controls of my game freeze after the first keypress with int 16h / ah=1

查看:140
本文介绍了第一次按键后,我的游戏控制冻结,持续时间为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码和扫描码.
重要的是,报告的可用键保留在键盘缓冲区中.在ALAH中获得的信息只是预览,而不是实际的键(在某种意义上).这解释了您的观察:

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来确定ALAH中的信息是否有效.
  • 数字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 and AH 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 from AH.

这篇关于第一次按键后,我的游戏控制冻结,持续时间为int 16h/ah = 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆