我正在制作贪吃蛇游戏,遇到了两个问题。
dw 452, 743, 534
当我运行替换过程时,它看起来像:"new number", 452, 743
我尝试了以下方法(它不起作用。无论我向哪个方向移动,星星都不会删除自己):proc replace_stars
mov cx, [st_am] ;the amount of stars, how many loops
mov bx, [st_am]
dec bx
shl bx, 1
replace:
mov di, [stars+bx-2] ;the one before last stars
mov bx, [stars+bx] ;the last stars
mov [bx], di ;in the last one, now the one before it
sub di, 2
sub bx, 2
loop replace ;loop the amount of stars
ret
endp replace_stars
2)我不知道该怎么做,当我向任何方向移动并吃掉一个苹果时,另一颗星星及其坐标将添加到数组中。 (第一个数字是第一个星星的坐标)当我移动时(假设是对的),假设我在DS中:
dw 2342, 4532, 4653
移动后,它看起来像:(向右移动,所以-2)2340, 2342, 4532, 4653
我的整个代码是:
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
saveal db ' ' ;used in line 223-233
dir db 0
app dw 0 ;place of the apple
st_am dw 3
stars dw 0, 0, 0 ;places of the *
CODESEG
proc black
body:
mov [es:si], ax
add si, 2
cmp si, 25*80*2
jnz body
ret
endp black
proc up
mov di, 80*2
cmp si, di
jb not_move_up
cmp si, [app]
jnz move_up
call apple
move_up:
call delete
call replace_stars
;mov di, [stars+2] failed attempt
;mov [stars+4], di
;mov di, [stars]
;mov [stars+2], di
;sub di, 80*2
;mov ah, 156
;mov al, '*'
mov [es:di], ax
sub si, 80*2
mov ah, 156
mov al, '*'
mov [es:si], ax
not_move_up:
ret
endp up
proc down
mov di, (24*80*2)-1
cmp si, di
jg not_move_down
cmp si, [app]
jnz move_down
call apple
move_down:
call delete
call replace_stars
;mov di, [stars+2] failed attempt
;mov [stars+4], di
;mov di, [stars]
;mov [stars+2], di
;add di, 80*2
;mov ah, 156
;mov al, '*'
mov [es:di], ax
add si, 80*2
mov ah, 156
mov al, '*'
mov [es:si], ax
not_move_down:
ret
endp down
proc left
mov dx, 0
mov bx, si
mov ax, si
mov si, 80*2
div si
mov si, bx
cmp dx,0
jz not_move_left
cmp si, [app]
jnz move_left
call apple
move_left:
call delete
call replace_stars
;mov di, [stars+2] failed attempt
;mov [stars+4], di
;mov di, [stars]
;mov [stars+2], di
;mov ah, 156
;mov al, '*'
;mov [es:di], ax
mov [stars], si
sub si, 2
mov ah, 156
mov al, '*'
mov [es:si], ax
not_move_left:
ret
endp left
proc right
mov dx, 0
mov bx, si
mov ax, si
mov si, 80*2
div si
mov si, bx
cmp dx,158
jz not_move_right
cmp si, [app]
jnz move_right
call apple
move_right:
call delete
call replace_stars
;mov di, [stars+2] failed attempt
;mov [stars+4], di
;mov di, [stars]
;mov [stars+2], di
;mov ah, 156
;mov al, '*'
;mov [es:di], ax
mov [stars], si
add si, 2
mov ah, 156
mov al, '*'
mov [es:si], ax
not_move_right:
ret
endp right
proc apple
mov ax, 40h
mov es, ax
mov ax, [es:6ch]
and ax, 0000001111111110b
mov di,ax
mov [app], di
mov ax, 0b800h
mov es, ax
mov al, '@'
mov ah, 154
mov [es:di], ax
ret
endp apple
proc delete
mov bx, offset stars
mov di, [st_am]
dec di
shl di, 1
mov di, [bx+di]
mov ax, 0b800h
mov es, ax
mov al, ' '
mov ah, 0
mov [es:di], ax
;mov di, [stars+2]
;mov [stars+4], di
;mov di, [stars]
;mov [stars+2], di
mov [stars], si
ret
endp delete
proc replace_stars
mov cx, [st_am] ;the amount of stars, how many loops
mov bx, [st_am]
dec bx
shl bx, 1
replace:
mov di, [stars+bx-2] ;the one before last stars
mov bx, [stars+bx] ;the last stars
mov [bx], di ;in the last one, now the one before it
sub di, 2
sub bx, 2
loop replace ;loop the amount of stars
ret
endp replace_stars
proc first_3_dots
mov bx, offset stars
mov si, ((12*80+40)*2)-2
mov al, '*'
mov ah, 156
mov [es:si], ax
mov [bx], si
mov si, (12*80+40)*2
mov al, '*'
mov ah, 156
mov [es:si], ax
mov [bx+2], si
mov si, ((12*80+40)*2)+2
mov al, '*'
mov ah, 156
mov [es:si], ax
mov [bx+4], si
ret
endp first_3_dots
proc delay
mov cx, 0FFFFh
delay1:
mov ax, 300
delay2:
dec ax
jnz delay2
loop delay1
ret
endp delay
proc move_stars_right
mov cx, [st_am]
mov di, offset stars
mov bx, di
move_loop:
mov ax, [di]
add ax, 2
mov [bx], ax
mov ah, 156
mov al, '*'
mov [es:di], ax
add di, 2
add bx, 2
loop move_loop
ret
endp move_stars_right
start:
mov ax, @data
mov ds, ax
; --------------------------
; Your code here
; --------------------------
mov ax, 0b800h
mov es, ax
mov si,0
mov al, ' '
mov ah, 0
call black
call first_3_dots
mov si, ((12*80+40)*2)-2
call apple
wasd:
mov ah, 1h
int 21h
mov [byte ptr saveal], al
cmp [byte ptr saveal], 'w'
jz w
cmp [byte ptr saveal], 'a'
jz a
cmp [byte ptr saveal], 's'
jz s
cmp [byte ptr saveal], 'd'
jz d
cmp [byte ptr saveal], 'q'
jmp exit
w:
call up
jmp wasd
s:
call down
jmp wasd
a:
call left
jmp wasd
d:
call right
jmp wasd
exit:
mov ax, 4c00h
int 21h
END start
dw 452, 743, 534 dw 2342, 4532, 4653
我发现看到这些你认为可能出现在 stars 数组中的示例令人担忧。存储在 stars 数组中的值表示 80x25 文本屏幕的视频内存中线性地址 000B8000h 处的偏移地址。那有什么问题吗?
(第一个数字是第一个星星的坐标)
不是真的!数组中的第一个数字是第一个星星的屏幕上的偏移地址。坐标可以是列和行,或者 X 和 Y。
移动后,它看起来像:(向右移动,所以-2)2340, 2342, 4532, 4653
这又是一个没有真正理解移动蛇意味着什么的例子。当您在屏幕上向右移动时,地址(保留在 SI 中)会增加 +2,因此预期的数字将以 2344、2342、... 开头
replace_stars过程灾难性地将引用屏幕的地址与引用驻留在DATASEG
!中的
stars数组的地址混合在一起 它执行的一次迭代太多了,因为在具有 3 个元素的数组中,您只能执行其中 2 个移动。
mov cx, [st_am] ; The amount of stars (3 or more)
dec cx ; How many loops
mov bx, cx
shl bx, 1 ; Offset to the last star
replace:
mov ax, [stars+bx-2]
mov [stars+bx], ax
sub bx, 2
loop replace
ret
此循环的更好版本不使用 loop
指令(因此不会破坏 CX 寄存器):
mov bx, [st_am] ; The amount of stars (3 or more)
dec bx
shl bx, 1 ; Offset to the last star
replace:
mov ax, [stars+bx-2]
mov [stars+bx], ax
sub bx, 2
jnz replace
ret
move_stars_right过程是试图让蛇长大?算了,现在还太早了!您需要首先修复错误。您甚至没有应用我在之前的答案中谈到的更正......
与我所说的replace_stars 过程类似,这个过程也灾难性地将引用屏幕的地址与引用驻留在 DATASEG
中的 stars
数组的地址混合在一起!你玩过贪吃蛇游戏吗?
https://www.google.be/url?esrc=s&q=&rct=j&sa=U&url=https://www.quora.com/Why-cant-snakes-crawl-backwards&ved=2ahUKEwjr8-6n_oWEAxXe2gIHHTuzAsgQFnoECAIQAw&usg=AOvVaw2fkOBLUqGbzjfOYcYSdgdt
当蛇当前向左移动时,您不能允许请求向右移动。
当蛇当前向右移动时,您不能允许请求向左移动。
当蛇当前移动到顶部时,您不能允许请求移动到底部。
当蛇当前移动到底部时,您不能允许请求移动到顶部。
之前的回答中解决了这个问题。