第一次与苹果碰撞后,它有时会移动,但之后你就没有机会让它移动了。这是使用 check_collision 函数进行检查的,该函数将苹果的 x 和 y 与蛇的 x 和 y 进行比较。
IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
Y dw 100
X dw 100
Board dw 200
TIME_AUX DB 0
PressFlag db 0
SnakeBody dw 8
Xapple dw 80
yapple dw 80
Random dw 50
; --------------------------
CODESEG
PROC moves
MOV AH, 01h ; Function 01h - Check for Key Press
INT 16h
JZ exit_moves ; Jump if ZF is set (no key pressed)
MOV AH, 00h ; Function 00h - Read Key Stroke
INT 16h
; Check if AH contains 'W' (ASCII value 87)
CMP AL, 'w'
je w_pressed
; Check if AH contains 'S' (ASCII value 83)
CMP AL, 's'
je s_pressed
; Check if AH contains 'D' (ASCII value 68)
CMP AL, 'd'
je d_pressed
; Check if AH contains 'A' (ASCII value 65)
CMP AL, 'a'
je a_pressed
; Check if AH contains '1B' (Escape key)
exit_moves:
RET
ENDP moves
PROC w_pressed
mov [PressFlag], 1
SUB [Y], 5
CHECK_TIME1: ;time checking loop
MOV AH,2Ch ;get the system time
INT 21h ;is the current time equal to the previous one(TIME_AUX)?
CMP DL,[TIME_AUX] ;is the current time equal to the previous one(TIME_AUX)?
JE CHECK_TIME1
MOV [TIME_AUX],DL
CALL draw_player
call moves
CMP [PressFlag],1
je w_pressed
RET
ENDP w_pressed
PROC d_pressed
mov [PressFlag], 2
ADD [X], 5
CHECK_TIME2: ;time checking loop
MOV AH,2Ch ;get the system time
INT 21h ;is the current time equal to the previous one(TIME_AUX)?
CMP DL,[TIME_AUX] ;is the current time equal to the previous one(TIME_AUX)?
JE CHECK_TIME2
MOV [TIME_AUX],DL
CALL draw_player
call moves
cmp [PressFlag],2
je d_pressed
ret
ENDP d_pressed
PROC a_pressed
mov [PressFlag], 3
SUB [X], 5
CHECK_TIME3: ;time checking loop
MOV AH,2Ch ;get the system time
INT 21h ;is the current time equal to the previous one(TIME_AUX)?
CMP DL,[TIME_AUX] ;is the current time equal to the previous one(TIME_AUX)?
JE CHECK_TIME3
MOV [TIME_AUX],DL
CALL draw_player
call moves
CMP [PressFlag],3
je a_pressed
ret
ENDP a_pressed
PROC s_pressed
ADD [Y], 5
mov [PressFlag], 4
CHECK_TIME4: ;time checking loop
MOV AH,2Ch ;get the system time
INT 21h ;is the current time equal to the previous one(TIME_AUX)?
CMP DL,[TIME_AUX] ;is the current time equal to the previous one(TIME_AUX)?
JE CHECK_TIME4
MOV [TIME_AUX],DL
CALL draw_player
call moves
CMP [PressFlag],4
je s_pressed
RET
ENDP s_pressed
PROC draw_player
MOV AX, 13h
INT 10h
MOV AX, 0C07h ; Function 0Ch, Set Pixel Color
MOV BH, 0 ; Page number (usually 0 in mode 13h)
MOV CX, [X] ; X-coordinate
MOV DX, [Y] ; Y-coordinate
MOV SI, 0
MOV DI, 0
MOV AL, 2; Color green
draw_row_loop:
draw_pixel_loop:
INC CX
INC DI
INT 10h
CMP DI, [SnakeBody]
JNE draw_pixel_loop
SUB CX, [SnakeBody]
MOV DI, 0
INC DX
INC SI
CMP SI, [SnakeBody]
JNE draw_row_loop
CALL check_collision
CALL draw_apple
RET
ENDP draw_player
PROC check_collision
mov ax, [yapple]
cmp ax, [Y]
jne skip_draw_apple
mov bx, [Xapple]
cmp bx, [X]
jne skip_draw_apple
call rnd
mov dx, [Random]
mov [Xapple], dx
CALL draw_apple
RET
skip_draw_apple:
RET
ENDP check_collision
PROC draw_apple
MOV AX, 0C07h ; Function 0Ch, Set Pixel Color
MOV BH, 0 ; Page number (usually 0 in mode 13h)
MOV CX, [Xapple] ; X-coordinate
MOV DX, [yapple] ; Y-coordinate
MOV AL, 2; Color red
INT 10h
RET
ENDP draw_apple
Proc rnd
mov ah, 2ch
int 21h
mov ax , [Random]
mov [byte ptr Random], dl
ADD [Random] , AX
ret
ENDP rnd
PROC game_logic
CHECK_TIME: ;time checking loop
MOV AH, 2Ch ;get the system time
INT 21h ;is the current time equal to the previous one(TIME_AUX)?
CMP DL, [TIME_AUX] ;is the current time equal to the previous one(TIME_AUX)?
JE CHECK_TIME ;if it is the same, check again
; If it reaches this point, it's because the time has passed
MOV [TIME_AUX], DL ;update time
CALL moves
CALL draw_player
RET
ENDP game_logic
MOV AX, 13h
INT 10h ; Set video mode 13h (320x200 pixels, 256 colors)
start:
MOV AX, @data
MOV DS, AX
MOV AX, 13h
INT 10h ; Set video mode 13h (320x200 pixels, 256 colors)
game_loop:
CALL game_logic
JMP game_loop
exit:
MOV AX, 4C00h
INT 21h
END start
我什至不知道如何解决这个问题,因为我是 x86 Tasm 组装的初学者,我希望这会很简单
像素未正确对齐,因此当代码尝试检查碰撞时,它会检查蛇的所有
y
值和苹果的所有 y
值以及 x
值,这不会之所以有效,是因为它们的尺寸不同,无论是否发生碰撞,都可以进行幸运抽奖。
我通过将苹果和蛇设置为相同大小来修补它。