为什么它在屏幕上添加一个随机像素?

问题描述 投票:0回答:1

我正在制作贪吃蛇游戏,我已经到了(目前)有 3 * 制作贪吃蛇的部分。当我从垂直移动到水平以及从水平移动到垂直时,它会添加另一个* 由于某种原因,每次都会在同一位置的 * 行中添加另一个 *

现在我的代码是:

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------
saveal db, ' '  ;used in line 223-233

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
    
    mov di, [stars+2]
    mov [stars+4], di
    mov di, [stars]
    mov [stars+2], di
    sub di, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:di], ax
    mov [stars], si
    
    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, [offset app]
    jnz move_down
    call apple
    
move_down:
    call delete
    
    mov di, [stars+2]
    mov [stars+4], di
    mov di, [stars]
    mov [stars+2], di
    add di, 80*2
    mov ah, 156
    mov al, '*'
    mov [es:di], ax
    mov [stars], si
    
    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, [offset app]
    jnz move_left
    call apple
    
move_left:
    call delete
    
    mov di, [stars+2]
    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
    
    mov di, [stars+2]
    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 [offset 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
  ret
endp delete
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
    
    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
    mov si, ((12*80+40)*2)-2    

    call apple
    
yesOrno:
    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 yesOrno
s:
    call down
    jmp yesOrno 
a:
    call left
    jmp yesOrno
d:
    call right
    jmp yesOrno
    
exit:
    mov ax, 4c00h
    int 21h
END start

我试着自己思考,但我想不出什么。

很抱歉问了很多。

assembly pixel x86-16 dosbox
1个回答
0
投票

为什么会有多余的字符。

stars dw 0, 0, 0  ; addresses for the Head, Body, and Tail

您没有使用蛇新头的正确位置更新您的stars数组!

mov [stars], si
指令需要在SI寄存器更新之后执行(无论是负160、正160、负2还是正2)。

您在所有移动程序中都写了多余的

*


move_upmove_down 中,多余的第二个 *
 放置在将绘制新头部的位置。在 
move_leftmove_right 中,多余的第二个 *
 被放置在已经绘制旧头部的位置。

考虑无效的动作。

你不能让蛇移动到已经包含蛇的一部分的位置!只需检查屏幕上是否已经有

*

 并相应地放弃移动即可。例如 
move_up 代码。其他的也类似:

... move_up: lea di, [si - 160] ; Intended address for the new head cmp byte [es:di], '*' je not_move_up ; Illegal move call delete mov ax, [stars+2] \ These 3 lines really belong to mov [stars+4], ax | the DELETE procedure (right before RET). mov [stars+2], si / Try to not repeat too much code. sub si, 160 mov [stars], si ; Update for the snake's new head mov ax, 156 * 256 + '*' mov [es:si], ax not_move_up: ret endp up
这足够随机吗?

proc apple mov ax, 40h mov es, ax mov ax, [es:6ch] and ax, 0000001111111110b mov di,ax mov [offset app], di

对我来说,这种为苹果选择随机位置的方法已经被破坏了。您认为我在回答您的

上一个问题时提出的建议有什么问题吗?

© www.soinside.com 2019 - 2024. All rights reserved.