如何同时向 运行 发送两个代码? (DOS 程序集)

How do I make two codes to run at the same time? (DOS Assembly)

我制作了 2 个方块(我正在使用汇编 DOS),我试图让一个方块移动,而另一个方块会在用户按下 SPACE 时跳跃。 问题是用户只能在另一个方块停止移动后按SPACE。你能帮帮我吗?

代码:

IDEAL
MODEL small
STACK 100h
DATASEG

X dw ?
Y dw ?
SquareSize dw ?

PlayerSquareX dw 20
PlayerSquareY dw 193

BlockX dw 305
BlockY dw 193

color db 1  ; default color is blue

FloorY dw 194
FloorX dw 0




CODESEG



    proc HalfSecondDelay
    push cx ;Backup
    push dx
    push ax
    
    MOV CX, 1H
    MOV DX, 3H
    MOV AH, 86H
    INT 15H
    
    pop ax ;Backup
    pop dx
    pop cx
    ret
    endp HalfSecondDelay

    
    proc WaitForSpace
    EnterSpace:  ;Wait until user presses Space
    mov ah,0
    int 16h
    cmp al,32
    ;jne EnterSpace
    jne ReturnToMain
    call PlayerJump
    ReturnToMain:
    ret
    endp WaitForSpace
    
    proc ClearKeyboardBuffer
    push ax
    ClearKeyboardBuffer_loop:
    mov ah,01h
    int 16h                     ; is there a key pressed
    jz ClearKeyboardBuffer_ret  ; if not, return
    mov ah,00h
    int 16h                     ; "handle" the key
    jmp ClearKeyboardBuffer_loop

    ClearKeyboardBuffer_ret:
    pop ax
    ret
endp ClearKeyboardBuffer


    proc PlayerJump ;Makes The Square Jump
    push cx
    
    
    mov cx, 10
    MoveUp:
    Call HalfSecondDelay
    
    call RemovePlayerSquare
    sub [PlayerSquareY],4 ; Move Up
    call PaintPlayerSquare
    loop MoveUp
    
    mov cx, 10
    MoveDown:
    Call HalfSecondDelay
    call RemovePlayerSquare
    add [PlayerSquareY], 4 ; Move Down
    Call PaintPlayerSquare
    loop MoveDown

    pop cx
    ret
    endp PlayerJump


proc PaintFloorLine
    push bp
    mov bp,sp
    push cx


    
    mov cx, 320
LoopPaintFloorLine:
    call PaintPixel
    
    inc [X]
    loop loopPaintFloorLine
    

    pop cx
    pop bp
    ret
endp PaintFloorLine

proc PaintFloor ;Paints The Floor
    push bp
    mov bp,sp
    push cx
    
    mov [x], 0
    mov [y], 194
    mov [color], 0Ah
    
    mov cx, 7
    
loopPaintFloor:     
    call PaintFloorLine
    inc [Y]
    mov [x], 0
    loop loopPaintFloor
    
    
    pop cx
    pop bp
    ret
endp PaintFloor
    

proc PaintPixel
    push bp
    mov bp,sp

    push ax
    push bx
    push cx
    push dx 
    

    mov cx,[X]
    mov dx,[Y]
    mov al,[color]
    mov ah,0ch
    int 10h
    
    pop dx
    pop cx
    pop bx
    pop ax
    pop bp
    ret
endp PaintPixel

proc PaintLine
    push bp
    mov bp,sp
    push cx
    
    mov cx, [SquareSize]
    
loopPaintLine:  
    call PaintPixel
    inc [X]
    loop loopPaintLine
    
    mov cx, [SquareSize] ; Return The X
    sub [X], cx
    
    pop cx
    pop bp
    ret
endp PaintLine

    
proc PaintSquare ;Paints A Sqaure
    push bp
    mov bp,sp
    push cx
    
    mov cx, [SquareSize]
    
loopPrinSquare:     
    call PaintLine
    dec [Y]
    loop loopPrinSquare
    
    mov cx, [SquareSize] ; Return The Y
    add [Y], cx
    
    pop cx
    pop bp
    ret
endp PaintSquare

proc PaintPlayerSquare ; Paints The Player Square
    push bp
    mov bp,sp
    
    mov ax, [PlayerSquareX]
    mov [x], ax
    
    mov ax, [PlayerSquareY]
    mov [Y], ax
    
    mov [SquareSize], 25
    mov  [color], 1 ; blue color
    call PaintSquare ;  
    
    pop bp
    ret 
endp PaintPlayerSquare

proc RemovePlayerSquare ;Removes The Player Square
    push bp
    mov bp,sp
    
    push ax
    push bx
    push cx
    push dx 
    
    mov ax, [PlayerSquareX]
    mov [x], ax
    
    mov ax, [PlayerSquareY]
    mov [Y], ax
    
    mov [SquareSize], 25
    mov  [color], 0 ; black color
    call PaintSquare ;  
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    pop bp
    ret 
endp RemovePlayerSquare


proc PaintBlockSquare ; Paints The Block Square
    push bp
    mov bp,sp
    
    
    mov ax, [BlockX]
    mov [x], ax
    
    mov ax, [BlockY]
    mov [Y], ax
    
    mov [SquareSize], 15
    mov  [color], 4 ; red color
    call PaintSquare ;  
    
    pop bp
    ret 
endp PaintBlockSquare

proc RemoveBlockSquare ;Removes The block Square
    push bp
    mov bp,sp
    
    push ax
    push bx
    push cx
    push dx 
    
    
    mov ax, [BlockX]
    mov [x], ax
    
    mov ax, [BlockY]
    mov [Y], ax
    
    mov [SquareSize], 15
    mov  [color], 0 ; black color
    call PaintSquare ;  
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    pop bp
    ret 
endp RemoveBlockSquare

proc MoveBlockLeft ;Makes The Square Jump
    push cx
    
    
    mov cx, 77
    loopMoveBlockLeft:
    Call HalfSecondDelay
    
    call RemoveBlockSquare
    sub [BlockX], 4 ; Move Up
    call PaintBlockSquare
    loop loopMoveBlockLeft
    


    pop cx
    ret
endp MoveBlockLeft



proc GraphicsScreen
    mov al, 13h
    mov ah, 0
    int 10h
    ret
endp GraphicsScreen

proc ResetBlockLocation
    mov [BlockX], 305
    mov [BlockY], 193
    ret
endp ResetBlockLocation

    
start:
    mov ax, @data
    mov ds, ax
    
    Call GraphicsScreen
    Call PaintFloor
    Call PaintPlayerSquare
    
    
    call PaintBlockSquare
    call MoveBlockLeft
    call RemoveBlockSquare
    call ResetBlockLocation
    call ClearKeyboardBuffer
    call WaitForSpace
    

    

exit:
    mov ax, 4c00h
    int 21h
END start

一种方法是实施 game loop, or a similar concept - event loop

想法是将动画分成一系列帧,并且一次只更新一帧。假设你想做 30 FPS,你的移动速度是每秒 90px。这意味着你需要在1帧内将物体移动大约3px,然后停顿0.033秒(33毫秒)。

在每一帧之后检查输入和处理动作。

它运行的方式是你开始第一个动画,记住你的动画状态,更新到下一帧,然后检查输入,更新到下一帧,然后再次检查输入,也许开始第二个动画(现在您一次处理 2 个动画状态),更新到下一帧,再次检查输入等