Assembly Pong - 以更有效的方式删除球

Assembly Pong - deleting the ball in a more efficient way

我正在组装一个 Pong 游戏,对于球技师,我在最后一个球位置所在的地方画了一个空白球,但是当我将它添加到我的游戏循环中时,球开始闪烁并且看起来有问题,这是我用于球的代码,有什么方法可以使删除过程更好以使其不会闪烁(包括与我使用的方法不同的方法)?

IDEAL
MODEL small
jumps
STACK 100h
p186
DATASEG
;-------------------------
temp_x dw 0
temp_y dw 0
color dw 4
lengthOfDrawings dw 9
pic_off dw 0
x_ball dw 150
y_ball dw 50
h_ball dw 9
w_ball dw 9
ballSpeed dw 03AFFh
y_direction_ball dw 'd'
x_direction_ball dw 'r'
temp_var dw 0
ball db 00h, 00h, 08h, 08h, 08h, 08h, 08h, 00h, 00h
     db 00h, 08h, 08h, 07h, 07h, 07h, 08h, 08h, 00h
     db 08h, 08h, 07h, 07h, 07h, 07h, 07h, 08h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 07h, 07h, 07h, 07h, 07h, 07h, 07h, 08h
     db 08h, 08h, 07h, 07h, 07h, 07h, 07h, 08h, 08h
     db 00h, 08h, 08h, 07h, 07h, 07h, 08h, 08h, 00h
     db 00h, 00h, 08h, 08h, 08h, 08h, 08h, 00h, 00h
     
;----------------------
CODESEG

proc draw_pixel
    pusha
    xor bh, bh
    mov cx, [temp_x]
    mov dx, [temp_y]
    mov ax, [color]
    mov ah, 0ch
    int 10h
    popa
    ret
endp draw_pixel

proc draw_line_ball
    pusha
    mov cx, [lengthOfDrawings]
    mov ax, [x_ball]
    mov [temp_x], ax
drawpr:
    call draw_pixel
    inc [temp_x]
    loop drawpr
    popa
    ret
endp draw_line_ball

proc draw_ball
    pusha
    mov cx, [x_ball]
    mov dx,[y_ball]
    mov ax, 0ch
    int 10H ; AL = COLOR
    cmp al, 4
    je endDrawBall
    cmp al, 9
    je endDrawBall
    ; DI  שמירה כתובת התחלתית של מערך דמות 
    mov di,[pic_off]
    mov dx, [y_ball]
    
print_line:
    mov cx, [x_ball] ; x pos
    mov si, [w_ball] ; ball width

print_columns: 
    mov al, [di] copy color to AL
    inc di  ; next item in array
    
    ; painting a pixel
    ;  cx = x coordinate , dx = y coordinate, al- color
    mov bh,0
    mov ah,0ch
    int 10h 
    
    inc cx ; inc x
    dec si ; decrease col counter
    cmp si, 0
    jne print_columns
    
    inc dx ;inc Y
    dec [h_ball] ; decreasing row counter
    cmp [h_ball], 0
    jne print_line
endDrawBall:
    popa
    ret
endp draw_ball

proc draw_blank_ball
    pusha
    mov cx, 9
    mov ax, [y_ball]
    mov [temp_y], ax
    mov [color], 0
rectanl:
    call draw_line_ball
    inc [temp_y]
    loop rectanl
    mov [color], 4
    popa
    ret
endp draw_blank_ball

proc delay
    pusha
    mov cx, 00h ;Higher part of the number
    mov dx, [ballSpeed] ;Lower part of the number
    mov al, 0
    mov ah, 86h
    int 15h
    popa
    ret
endp delay

start:

mov ax, @data
mov ds, ax

;---------------------------
    ;Changing to graphic mode
    mov ax, 13h
    int 10h
    
gameLoop:
    add [x_ball], 2h
    inc [y_ball]
    mov [pic_off], offset ball
    mov [h_ball], 9
    mov [w_ball], 9
    call draw_ball
    call delay
    call draw_blank_ball
    jmp gameLoop

    
endGame:
    ;Returns to text mode
    mov ax, 2h
    int 10h
;---------------------------


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

pusha 将是一个相当昂贵的操作。只有 pushing/popping 您修改的寄存器可能会节省。

也就是说,这样的事情怎么样?它摆脱了对 draw_pixel 的调用(因此是 pusha/popa),加上不断重新填充寄存器。

proc draw_line_ball
    pusha
    mov si, [lengthOfDrawings]

    xor bh, bh
    mov cx, [x_ball]
    mov dx, [temp_y]
    mov ax, [color]
    mov ah, 0ch

drawpr:

    int 10h

    inc cx
    dec si
    jnz drawpr

    popa
    ret
endp draw_line_ball

(显然)我没有尝试过这个,但那里可能有一些有用的想法。