I am making a Pong game in assembly and for the ball mechanic I am drawing a blank ball in the place where the last ball location was but when I added it to my game loop the ball started flashing and it looks buggy, Here is the code I use for the ball, any way to make the deleting process better so it won’t flash (including different methods from the one I am using)?
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
CodePudding user response:
pusha
is going to be a pretty expensive operation. Only pushing/popping the registers you modify might be a savings.
That said, how about something like this? It gets rid of the call to draw_pixel (thus a pusha/popa), plus the constant repopulating of the registers.
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
(Obviously) I have not tried this, but there may be some useful ideas there.