我的问题是,当我向左或向右移动蛇时,删除"追踪"在它没有改变之后,我已经调试了几天的代码,但仍然无法找到问题.... 我将删除轨迹更改为白色,以查看当x应该更改时它是如何移动的。
逻辑是我在数组中有x,y,最后一个数组将转到x_remove和y_remove,在那些像素中,它将删除它(用黑色绘制它,在这种情况下是白色,因为我想看看如何它正在移动。
这是我的代码:
%TITLE "Project"
IDEAL
;---------------------------------------
;Choice_Enter enters to the requested option (Game/Settings/Exit)
;---------------------------------------
;Input:
; Y = y of the pointer
;Output:
; None
;Registers:
; AH
;---------------------------------------
MACRO Choice_Enter y
cmp y,8
je Choice_Enter_1
cmp y,10
je Choice_Enter_2
cmp y,12
je Choice_Enter_3
ENDM Choice_Enter
;---------------------------------------
;Pointer_up moves y of the object that points to the options in the main menu
;---------------------------------------
;Input:
; Y = y of the pointer
;Output:
; None
;Registers:
; AH
;---------------------------------------
MACRO Pointer_up y
cmp y,8
je up_2
cmp y,10
je up_1
cmp y,12
je up_1
ENDM Pointer_up
;---------------------------------------
;Pointer_down moves y of the object that points to the options in the main menu
;---------------------------------------
;Input:
; Y1 = y of the pointer
;Output:
; None.
;Registers:
; None.
;---------------------------------------
MACRO Pointer_down y
cmp y,8
je down_1
cmp y,10
je down_1
cmp y,12
je down_2
ENDM Pointer_down
;---------------------------------------
;Print Prints the object that given
;---------------------------------------
;Input:
; X = x of the string,Y = y of the string,Object_to_print = string
;that requested to print
;Output:
; BX,AH,DX
;Registers:
; DX,BX,AH
;---------------------------------------
MACRO Print x,y,object_to_print
mov dl, x ; Column
mov dh, y ; Row
mov bx, 0 ; Page number, 0 for graphics modes
mov ah, 2h
int 10h
mov dx, offset object_to_print
mov ah, 9h
int 21h
ENDM Print
MODEL small
P386
STACK 256
SPAN equ 500 ; interval 500 loops
ENTER_KEY equ 01Ch
UP_KEY equ 72
DOWN_KEY equ 80
KEY_RIGHT equ 77
KEY_LEFT equ 75
ESC_KEY equ 1
screen_RAM_graphics equ 0A000h
;----- Equates
DATASEG
c_remove dw 1
X_remove dw 0020h
Y_remove dw 0008h
Check_j dw 4
Check_n dw 4
check_i dw 0
check_k dw 0
Counter dw SPAN
X_object dw 18
Y_object dw 12
DeltaX dw 0
DeltaY dw 0
i dw 4
k dw 4
j dw 4
n dw 4
Color db 11
Del_Pointer db ' $'
Main_Screen_Pointer db '->$'
Main_Screen_Game db 'Start game$'
Main_Screen_Settings db 'Settings$'
Main_Screen_Exit db 'Exit$'
Print_Settings db 'Who created the game ? ',13,10
db 'You can play in this game with the keys : ',13,10
db 'up,down,left,right',13,10,13,10
db 'press esc to exit$'
Print_End db 'See you next time ;)',13,10
db 'press esc to exit$'
x db 13
y db 8
ArrayX dw 0020h,0020h,0020h
ArrayY dw 0012h,0012h,0012h
CODESEG
Start:
mov ax, @data
mov ds, ax
;-------Changing to graphics mode.
call GraphicsMode
Return:
call CleanScreenGraphicsMode
;-------Printing main_menu
Print 15,8,Main_Screen_Game
Print 15,10,Main_Screen_Settings
Print 15,12,Main_Screen_Exit
Pointer_reprint:
Print [x],[y],Main_Screen_Pointer
;-------clearing keyboard buffer
mov ah,0ch
mov al,07h
int 21h
;-------scanning code from keyboard
in al,060h
;scan end
cmp al,UP_KEY
je l2
cmp al,DOWN_KEY
je l1
cmp al,ENTER_KEY
je Ent
return_back:
jne Pointer_reprint
;If the user chooses "Game" option.
Ent:
Choice_Enter [y]
Choice_Enter_1:
call CleanScreenGraphicsMode
mov ah,8
mov [y],ah ; Lines 189-190 are for bringing the pointer back to his place.
call GraphicsMode
jmp GamePlay
Return_GamePlay:
jmp return
;If the user chooses "Settings" option.
Choice_Enter_2:
mov ah,8
mov [y],ah
call CleanScreenGraphicsMode
call GraphicsMode
mov ah,0
Print 0,0,Print_Settings
re_scan_2:
;-------clearing keyboard buffer
mov ah,0ch
mov al,07h
int 21h
;return to main menu by getting input.
in al,060h
cmp al,ESC_KEY
je Return
jne re_scan_2
;If the user chooses "Exit" option.
Choice_Enter_3:
jmp exit
;If the user presses down key in main menu in one of those options(Start
;Game,Settings)
down_1:
Print [x],[y],Del_Pointer
mov ah,2
add [y],ah
jmp return_back
;If the user presses down key in main menu in this function(Exit)
down_2:
Print [x],[y],Del_Pointer
mov ah,4
sub [y],ah
jmp return_back
;If the user presses up key in main menu in one of those options(Settings,Exit)
up_1:
Print [x],[y],Del_Pointer
mov ah,2
sub [y],ah
jmp return_back
;If the user presses up key in main menu in this function(Start Game)
up_2:
Print [x],[y],Del_Pointer
mov ah,4
add [y],ah
jmp return_back
;If the user presses down key, it updates it.
l1:
Print [x],[y],Del_Pointer
Pointer_down [y]
jmp Pointer_reprint
;If the user presses up key, it updates it.
l2:
Print [x],[y],Del_Pointer
Pointer_up [y]
jmp Pointer_reprint
GamePlay:
;----- Read SCAN code and ASCII code from keyboard port
in al,060h
push ax
;----- Checking key is pressed
cmp al, UP_KEY
je Up
cmp al, DOWN_KEY
je Down
cmp al, KEY_RIGHT
je Right
cmp al, KEY_LEFT
jne cont
mov [deltaX], -2
mov [deltaY],0
jmp cont
Up: mov [deltaY], -2
mov [deltaX],0
jmp Cont
Down:
mov [deltaY],2
mov [deltaX],0
jmp Cont
Right:
mov [deltaX],2
mov [deltaY],0
jmp Cont
Cont:
mov dx, [deltaX]
add [X_object], dx
mov dx, [deltaY]
add [Y_object], dx
call WriteSnake <-- The problem is here
call Move_Snake <-- And here
dec [counter]
jnz NoArrow
mov ax,[span]
mov [counter],ax
NoArrow:
pop ax
dec al
jz Return_GamePlay
jmp GamePlay
;----------------------------------------------------------
; GraphicsMode sets the mode of the dosbox to Graphics mode
;----------------------------------------------------------
; Input:
; AH
; Output:
; AL,AH
; Registers:
;
;----------------------------------------------------------
PROC GraphicsMode
mov al,13h
mov ah,0h
int 10h
ret
ENDP GraphicsMode
;----------------------------------------------------------
; GraphicsMode sets the mode of the dosbox to Graphics mode
;----------------------------------------------------------
; Input:
; AL = first color,AH = second color, ES
; Output:
; AX
; Registers:
; AX
;----------------------------------------------------------
PROC CleanScreenGraphicsMode
mov ax,screen_RAM_graphics
mov es,ax ; es:di - video memory
xor di,di
mov cx,320*200/2
mov al,0d ; color
mov ah,0d ; color
rep stosw ; mov es:[di],ax add di,2
ret
ENDP CleanScreenGraphicsMode
;----------------------------------------------------------
; WriteSnake Drawing point
;----------------------------------------------------------
; Input:
; CX = x, DX = y, AL = color
; Output:
; The point
; Registers
; AX, BH, CX, DX,
;----------------------------------------------------------
PROC WriteSnake
push cx
push dx
push bx
push ax
keep_printing:
;----------------First pixel(left up)
mov bh,0
mov si,[check_i]
mov cx,[ArrayX+si]
mov si,[check_k]
mov dx,[ArrayY+si]
mov al,[color]
mov ah,0ch
int 10h
;----------------Second pixel(right up)
mov bh,0
mov si,[check_i]
mov cx,[ArrayX+si]
add cx,1
mov si,[check_k]
mov dx,[ArrayY+si]
mov al,[color]
mov ah,0ch
int 10h
;----------------Third pixel(left down)
mov bh,0
mov si,[check_i]
mov cx,[ArrayX+si]
mov si,[check_k]
mov dx,[ArrayY+si]
add dx,1
mov al,[color]
mov ah,0ch
int 10h
;----------------Fourth pixel(right down)
mov bh,0
mov si,[check_k]
mov cx,[ArrayX+si]
add cx,1
mov si,[check_i]
mov dx,[ArrayY+si]
add dx,1
mov al,[color]
mov ah,0ch
int 10h
inc [check_i]
inc [check_i]
inc [check_k]
inc [check_k]
mov ax,[check_i]
cmp ax,6
jne keep_printing
;-----------------------Deleting:
;-----------------------Delay
mov dx,0C380h ;dx, right side of the miliseconds
mov cx,01C9h ; cx, left side of the miliseconds ex: cx = 5, dx = ;
; 012DFh so it will wait 0512DFh seconds
mov ah,86
int 15h
;------------------------First pixel(left up)
mov bh,0
mov cx,[y_remove]
mov dx,[x_remove]
mov al,15
mov ah,0ch
int 10h
;----------------------Second pixel(right up)
mov bh,0
mov cx,[y_remove]
mov dx,[x_remove]
add cx,1
mov al,15
mov ah,0ch
int 10h
;--------------------Third pixel(left down)
mov bh,0
mov cx,[y_remove]
mov dx,[x_remove]
add dx,1
mov al,15
mov ah,0ch
int 10h
;--------------------Fourth pixel(right down)
mov bh,0
mov cx,[y_remove]
mov dx,[x_remove]
add cx,1
add dx,1
mov al,15
mov ah,0ch
int 10h
end_print_func:
pop ax
pop bx
pop dx
pop cx
mov [check_i],0
mov [check_k],0
ret
ENDP WriteSnake
;---------------------------------------
;Move_Snake Changes the x and y array of the snake.
;---------------------------------------
;Input:
; Y1 = new first y of the snake , X1 = new first x of the snake.
;Output:
; None.
;Registers:
; AH
;---------------------------------------
PROC Move_Snake
push si
push ax
push bx
;---------------------Data of removing last pixel(last in array)
mov bx,[ArrayX+6]
mov [X_remove],bx
mov bx,[ArrayY+6]
mov [Y_remove],bx
re_func:
cmp [Check_j],0
je End_Func
;---------------------Transferring X of the snake.
mov si,[Check_j] ;Moving to register because can't compare memory to
;memory.
mov ax,[ArrayX+si]
mov [ArrayX+si+2],ax
;---------------------Transferring in array Y of the snake(new to old).
mov si,[Check_n] ;Moving to register because can't compare memory to
;memory.
mov ax,[ArrayY+si]
mov [ArrayY+si+2],ax
dec [Check_j]
dec [Check_j]
dec [Check_n]
dec [Check_n]
jmp re_func
;---------------------First new coordinates of the snake.
End_Func:
mov si,[Y_object]
mov [ArrayY+0],si
mov si,[X_object]
mov [ArrayX+0],si
add [Check_j],4
add [Check_n],4
pop bx
pop ax
pop si
ret
ENDP Move_Snake
Exit:
call CleanScreenGraphicsMode
mov ah,00
mov al,03 ;text mode 3
int 10h
mov ax, 4C00h
int 21h
END start
答案 0 :(得分:1)
由于 check_i 和 check_k 变量在整个程序中具有相同的值(请参阅我的上一点),因此您不会在屏幕上看到此错误。
;----------------Fourth pixel(right down) mov bh,0 mov si,[check_k] <- WRONG mov cx,[ArrayX+si] add cx,1 mov si,[check_i] <- WRONG mov dx,[ArrayY+si] add dx,1 mov al,[color] mov ah,0ch int 10h
在 WriteSnake 程序的这一部分中,您选择了错误的偏移变量!
第四个像素应该与其他三个像素没有区别。
;----------------Fourth pixel(right down)
mov bh,0
mov si,[check_i] <- Corrected
mov cx,[ArrayX+si]
add cx,1
mov si,[check_k] <- Corrected
mov dx,[ArrayY+si]
add dx,1
mov al,[color]
mov ah,0ch
int 10h
此外,您可以考虑简化绘制4个像素的代码:
;left up
mov bh,0
mov si,[check_i]
mov cx,[ArrayX+si]
mov si,[check_k]
mov dx,[ArrayY+si]
mov al,[color]
mov ah,0ch
int 10h
;right up
inc cx
int 10h
;right down
inc dx
int 10h
;left down
dec cx
int 10h
add [check_i], 2
add [check_k], 2
;------------------------First pixel(left up) mov bh,0 mov cx,[y_remove] <- WRONG mov dx,[x_remove] <- WRONG mov al,15 mov ah,0ch int 10h
BIOS PlotPixel 功能0Ch需要CX
中的X坐标和DX
中的Y坐标。
在这里,您也可以采用与上述相同的方式优化代码:
;left up
mov bh,0
mov cx,[x_remove] <- Corrected
mov dx,[y_remove] <- Corrected
mov al,15
mov ah,0ch
int 10h
;right up
inc cx
int 10h
;right down
inc dx
int 10h
;left down
dec cx
int 10h
mov [check_i], 0
mov [check_k], 0
mov bx,[ArrayX+6] mov [X_remove],bx mov bx,[ArrayY+6] mov [Y_remove],bx
由于这两个字大小的数组只包含3个项目(= 6个字节),因此从偏移量+6读取将产生垃圾!
check_i 和 check_k 变量
check_j 和 check_n 变量
这些变量似乎总是在程序中一起变化。考虑通过不使用第二个实例进行简化。