Assembly 在汇编中进行乒乓球游戏时,如何一次获得多个按键的输入?

Assembly 在汇编中进行乒乓球游戏时,如何一次获得多个按键的输入?,assembly,keyboard,emu8086,pong,Assembly,Keyboard,Emu8086,Pong,我是初学者,所以这段代码可能不太好,我用了int16h来做这段代码,但我对这段int不太了解。我刚发现你不可能一次击多个键;有什么帮助吗? 这个代码的问题是一次只能移动一块板,我需要两块板。如何检查多个输入 以下是所有想要它的人的代码: 这个代码的问题是一次只能移动一块板,我需要两块板 同时性的感觉来自于快速,真正的快速。计算机中的大多数东西都是连续工作的,但我们认为许多事情是并行发生的 你的支票代码很好。一块板使用q键和s键,另一块板使用向上键和向下键。 一旦有键可用,键盘BIOS功能00h将

我是初学者,所以这段代码可能不太好,我用了
int16h
来做这段代码,但我对这段
int
不太了解。我刚发现你不可能一次击多个键;有什么帮助吗?
这个代码的问题是一次只能移动一块板,我需要两块板。如何检查多个输入

以下是所有想要它的人的代码:

这个代码的问题是一次只能移动一块板,我需要两块板

同时性的感觉来自于快速,真正的快速。计算机中的大多数东西都是连续工作的,但我们认为许多事情是并行发生的

你的支票代码很好。一块板使用q键和s键,另一块板使用向上键和向下键。
一旦有键可用,键盘BIOS功能00h将立即检索该键,您的程序将相应地更新图形。但是如果你的图形输出程序花费的时间太长,那么玩家就会开始认为键盘太慢了

查看您的图形例程,我看到您使用视频BIOS功能0Ch在屏幕上放置像素。这是缓慢的,尤其是痛苦的,因为你在最简单的图形屏幕上播放,你只需
MOV
一个字节就可以画出一个像素

在需要快速图形的程序中,将
ES
段寄存器点永久地放在视频缓冲区是非常有利的

  mov  ax, 0A000h
  mov  es, ax
  cld             ; Because of the use of STOSB
这就是清除屏幕所需的全部内容:

ClearScreen:
  xor  di, di
  mov  cx, 64000
  mov  al, 0
  rep stosb
  ret
这是绘制水平线(160100)-(200100)的方式:


另一个答案是关于一个多人游戏,其中没有一个玩家一直按专用键,从而占据键盘。尽管这种情况非常合理,但您可能希望允许玩家长时间按住钥匙。为此,我们可以用自己的处理程序替代BIOS/DOS提供的键盘处理程序

键盘上的每个键都与一个唯一的8位数字相关联,我们称之为扫描码。
只要按下一个键,键盘就会在端口60h处提供相关键的扫描码。键盘还生成一个中断09h。此中断的处理程序可以检查扫描代码并以任何方式处理它。下面的演示程序就是这样做的。
当按下某个键时,扫描码是一个最高位关闭的字节。释放钥匙时,扫描码是一个最高位为on的字节。对于按压和释放,其他7位保持不变

应该注意的是,尽管对于你的乒乓球游戏来说很好,但是包含的替换处理程序是一个极简的处理程序。复杂的处理程序还将考虑前缀为E0h或E1h代码的扩展扫描代码

该程序有附加注释,因此您可以轻松了解正在发生的事情。代码使用FASM语法。演示在真实DOS环境和DOSBox(0.74)中运行正常


程序的键列表记录键盘上所有键的当前状态。如果字节为0,则未按下该键。如果一个字节是1,则该键当前正在被按下。

这个问题应该被上千次投票,仅仅是为了在汇编中编写游戏的想法……学校项目:p无论如何,在汇编中打乒乓球真的是很有价值的回答你的问题吗?我想会的。也许老实说,我会试着学习港口主义!但问题是不能同时按下两个键来同时移动两块板,所以idk如果这样可以解决这个问题。谢谢,不过我会用你的代码让我的项目感觉好20倍。顺便问一下,我如何改变板的宽度?此外,我对es或rep stosb也不太了解,这会有问题吗?@orraz1如果您对
es
rep stosb
不太了解,请了解8086的完整指令集。它不太复杂;它包含大约50条指令,与当前x86的指令集相比,这算不了什么。我相信我的第二个答案会解决你同时按下按键的问题!这是胡说八道,谢谢,我会试着把这段代码翻译成tasm,并把它放在我的项目tysm.Sry中来回答问题,但是“DOS.GetInterruptVector”和“DOS.GetInterruptVector”到底是什么?还有,你在这段代码中到底在做什么?Nvm我现在明白了omfg这是Genius你有关于如何使用int 21h 25中断的文章吗?我知道它是如何工作的,只是不知道你如何使用它。顺便问一下,我应该把机具中断代码放在哪里?
ClearScreen:
  xor  di, di
  mov  cx, 64000
  mov  al, 0
  rep stosb
  ret
  mov  dl, 15    ; BrightWhite
  mov  cx, 51    ; 51 pixels from 160 to 200
  mov  bx, 160   ; X
  mov  ax, 100   ; Y
  call DrawLine

  ...

DrawLine:
  push dx
  mov  di, 320   ; BytesPerScanline
  mul  di
  add  ax, bx
  mov  di, ax    ; Address DI = (Y * BPS) + X
  pop  ax        ; Color AL
  rep stosb
  ret
; Multi-player Keyboard Input (c) 2021 Sep Roland

    ORG  256               ; Output will be a .COM program

    mov  ax, 3509h         ; DOS.GetInterruptVector
    int  21h               ; -> ES:BX
    push es bx             ; (1)

    mov  dx, Int09
    mov  ax, 2509h         ; DOS.SetInterruptVector
    int  21h

    mov  ax, 0013h         ; BIOS.SetVideoMode 320x200 (256 colors)
    int  10h
    mov  ax, 0A000h        ; Video buffer
    mov  es, ax
    cld                    ; So we can use the string primitive STOSB

Cont:
    mov  si, 160           ; Width
    mov  di, 100           ; Height

    mov  al, 0             ; Black
    cmp  [KeyList+48h], al ; Up
    je   .a
    mov  al, 2             ; Green
.a: mov  cx, 160           ; X
    mov  dx, 0             ; Y
    call Paint

    mov  al, 0             ; Black
    cmp  [KeyList+50h], al ; Down
    je   .b
    mov  al, 14            ; Yellow
.b: mov  cx, 160           ; X
    mov  dx, 100           ; Y
    call Paint

    mov  al, 0             ; Black
    cmp  [KeyList+11h], al ; aZerty / qWerty
    je   .c
    mov  al, 4             ; Red
.c: mov  cx, 0             ; X
    mov  dx, 0             ; Y
    call Paint

    mov  al, 0             ; Black
    cmp  [KeyList+1Fh], al ; S
    je   .d
    mov  al, 1             ; Blue
.d: mov  cx, 0             ; X
    mov  dx, 100           ; Y
    call Paint

    cmp  byte [KeyList+1], 0 ; ESC
    je   Cont

    pop  dx ds             ; (1)
    mov  ax, 2509h         ; DOS.SetInterruptVector
    int  21h

    mov  ax, 4C00h         ; DOS.Terminate
    int  21h
; --------------------------------------
Int09:
    push ax bx
    in   al, 60h
    mov  ah, 0
    mov  bx, ax
    and  bx, 127           ; 7-bit scancode goes to BX
    shl  ax, 1             ; 1-bit press/release goes to AH
    xor  ah, 1             ; -> AH=1 Press, AH=0 Release
    mov  [cs:KeyList+bx], ah
    mov  al, 20h           ; The non specific EOI (End Of Interrupt)
    out  20h, al
    pop  bx ax
    iret
; --------------------------------------
; IN (al,cx,dx,si,di)
Paint:
    push cx dx di          ; AL=Color CX=X DX=Y SI=Width DI=Height
    push ax                ; (1)
    mov  ax, 320           ; BytesPerScanline
    mul  dx
    add  ax, cx            ; (Y * BPS) + X
    mov  dx, di
    mov  di, ax
    pop  ax                ; (1)
.a: mov  cx, si
    rep  stosb
    sub  di, si
    add  di, 320
    dec  dx
    jnz  .a
    pop  di dx cx
    ret
; --------------------------------------
KeyList db 128 dup 0
KeyList db 128 dup 0