Как мне сделать два кода для запуска одновременно?(Сборка DOS) - PullRequest
0 голосов
/ 31 марта 2019

Я сделал 2 квадрата (я использую ассемблер DOS), и я пытаюсь сделать так, чтобы один квадрат двигался, а другой квадрат подпрыгнет, когда пользователь нажмет пробел. Проблема в том, что пользователь может нажать клавишу ПРОБЕЛ только после того, как другой квадрат перестанет двигаться. Можете ли вы помочь мне, пожалуйста?

КОД:

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

1 Ответ

0 голосов
/ 31 марта 2019

Один из способов - реализовать игровой цикл или аналогичную концепцию - цикл событий .

Идея состоит в том, чтобы разбить анимацию на сериюкадров, и обновлять только 1 кадр за раз.Допустим, вы хотите сделать 30 кадров в секунду, а скорость вашего движения составляет 90 пикселей в секунду.Это означает, что вам нужно переместить объект примерно на 3 пикселя в 1 кадре, а затем сделать паузу на 0,033 секунды (33 мс).

После каждого кадра вы проверяете действия ввода и обработки.

он запускается так, что вы запускаете первую анимацию, запоминаете состояние анимации, обновляете до следующего кадра, затем проверяете на ввод, обновляете до следующего кадра, затем снова проверяете на ввод, возможно запускаете вторую анимацию (теперь вы обрабатываете 2 анимациисостояния одновременно), обновите оба до следующего кадра, снова проверьте вход и т. д.

...