在组装中制作乒乓游戏时,如何一次输入多个按键? [英] Making a pong game in assembly, how do I get an input of multiple keystyokes at once?

查看:69
本文介绍了在组装中制作乒乓游戏时,如何一次输入多个按键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个初学者,所以这段代码可能没有什么用,我为此使用了 int 16h ,但对此 int 知之甚少.我刚刚发现您一次不能进行多次击键.有帮助吗?
这段代码的问题在于,一次只能移动一块板,而我俩都需要.如何检查多个输入?

I'm a beginner so this code probably isn't any good, I used int 16h for this but I don't know a lot about this int. I just found out you can't have multiple keystrokes at once; any help?
The problem with this code is that only one board can move at a time and I need both. How do I check for multiple inputs?

以下是任何人想要的代码:

Here's the code for anyone who wants it:

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
    line1X dw 80
  line1Y dw 120
  line1start dw 5
  line1end dw 10
  line2X dw 80
  line2Y dw 120
  line2start dw 310
  line2end dw 315
CODESEG
    proc startVideo ;creates video mode
      mov al,13h
      mov ah,0h
      int 10h
      ret
  endp startVideo
  proc clearScrean ;turns the screen black
      mov ah, 0ch
      xor al,al
      mov dx,200 
BlankLine:
      mov cx,320
BlankColumn:
        int 10h
        Loop BlankColumn
      dec dx
        cmp dx,0
        jne BlankLine     
      ret
  endp clearScrean
  
    proc drawboard ;creates the board
      push bp
      mov bp,sp
      mov al,0fh
      mov ah,0ch
      beginning equ [bp+10]
      fn equ [bp+8]
      X equ [bp+6] ;boards start
      Y equ [bp+4] ;boards end
      mov dx,Y
drawrow:
      mov cx,fn
drawcolumn:
        int 10h
      dec cx
        cmp cx,beginning
        jne drawcolumn
      dec dx
      cmp dx,X 
      jne drawrow
      pop bp
      ret 8
  endp drawboard
  proc drawall
      push [line1start]
      push [line1end]
      push [line1X]
      push [line1Y]
      call drawboard
      push [line2start]
      push [line2end]
      push [line2X]
      push [line2Y]
      call drawboard
      ret
  endp drawall
  proc boardup
      push bp
      mov bp,sp
      mov bx,[bp+4]
      mov si,[bp+6]
      cmp [word ptr bx],0 ;checks if board didnt get to border 
      je fn1
        call clearScrean
      sub [word ptr bx],5 ;3 pixels added to board
      sub [word ptr si],5
      call drawall ;prints both boards
fn1:
      pop bp
      ret 4
  endp boardup
  proc boarddown
      push bp
      mov bp,sp
      mov bx,[bp+4]
      mov si,[bp+6]
      cmp [word ptr si],200 ;checks if board didnt get to border 
      je fn2
        call clearScrean
      add [word ptr bx],5 ;3 pixels added to board
      add [word ptr si],5
      call drawall ;prints both boards
fn2:
      pop bp
      ret 4
  endp boarddown
start:
  mov ax, @data
  mov ds, ax
    mov bh,0
  call startVideo
  call clearScrean
  call drawall
checkskey: ;checks if key is being pressed
  mov ah,1
  int 16h
  jz checkskey ;jumps if key isnt pressed
  mov ah,0 ;checks which key is pressed
  int 16h
  cmp ah,11h ;if key pressed is w jump to upboard
  je upboard1
  cmp ah,01fh ;if key pressed is s jump to downboard
  je downboard1
  cmp ah,050h
  je downboard2
  cmp ah,048h
  je upboard2
  jmp checkskey ;if key isnt pressed jump to check key
upboard1: ;board 1 goes up
    push offset line1Y
  push offset line1X
  call boardup
  jmp checkskey
downboard1: ;board 1 goes down
    push offset line1Y
  push offset line1X
  call boarddown
  jmp checkskey
downboard2:
    push offset line2Y
  push offset line2X
  call boarddown
  jmp checkskey
upboard2:
    push offset line2Y
  push offset line2X
  call boardup
  jmp checkskey
exit:
  mov ax, 4c00h
  int 21h
END start

推荐答案

另一个答案涉及一个多人游戏,其中没有一个玩家持续按下专用键并占用键盘.尽管这种情况是相当合理的,但您可能希望允许玩家长时间按住其键.为此,我们可以用我们自己的处理程序代替BIOS/DOS提供的键盘处理程序.

The other answer deals with a multi-player game where none of the players keep pushing their dedicated keys and thus hogging the keyboard. Although this scenario is quite reasonable, you might want to allow the players to hold their key down for a longer period. To this effect we can substitute the keyboard handler that BIOS/DOS provides by a handler of our own.

键盘上的每个键都关联一个唯一的8位数字,我们称之为扫描代码.
每当按键被按下时,键盘就会在端口60h上提供相关按键的扫描代码.键盘还会产生一个中断09h.此中断的处理程序可以检查扫描代码并以其喜欢的任何方式对其进行处理.这就是下面的演示程序所做的.
当按下一个键时,扫描码是一个字节,其最高位关闭.释放键时,扫描码是一个字节,其最高位打开.其余7位在按下和释放时均保持不变.

With each key on the keyboard is associated a unique 8-bit number we call the scancode.
Whenever a key is pressed the keyboard makes the scancode of the concerned key available at port 60h. The keyboard also generates an interrupt 09h. A handler for this interrupt can examine the scancode and process it in any way it likes. That's what the below demonstration program does.
When a key is pressed the scancode is a byte with its highest bit off. When a key is released the scancode is a byte with its highest bit on. The other 7 bits remain the same for both presses and releases.

应该注意的是,尽管对于您的 pong 游戏而言,它很好,但其中包含的替换处理程序却是一种简约的处理程序.复杂的处理程序还将考虑以E0h或E1h代码为前缀的扩展扫描代码.

It should be noted that, although fine for the purpose of your pong game, the included substitution handler is a minimalistic one. A sophisticated handler would also take into account the extended scancodes that are prefixed with an E0h or E1h code.

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

The program has additional comments so you can easily understand what's happening. The code uses FASM syntax. The demo runs OK in the real DOS environment and in the DOSBox (0.74).

; 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

程序的 KeyList 记录键盘上所有键的当前状态.如果字节为0,则说明未按下该键.如果字节为1,则当前正在按下该键.

The program's KeyList records the current state of all of the keys on the keyboard. If a byte is 0, the key is not being pressed. If a byte is 1, that key is currently being pressed.

这篇关于在组装中制作乒乓游戏时,如何一次输入多个按键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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