我正在尝试在一个随机的地方(图形模式)打印一个角色的游戏(非常基本)。 然后,如果玩家用鼠标按下它,它就会变成其他随机位置。
我做了一些功能 - 计算随机位置,打印角色,然后检查玩家是否按下它 如果没有继续检查,如果是跳转到开头并计算随机位置打印等等...
但我有一个问题。 直到按下一切正常但是然后,在我按下后它从头开始。 但它不会等到我按下角色。它的工作方式就像我按下并一次又一次地继续(在屏幕上打印)。
我认为问题在于我没有重置鼠标或其他东西 - 并且它记得我按下了那种颜色,所以在我按下其他颜色之前它会自动工作。
我该怎么办?
如果您有办法通过一点点改变解决我的问题,或者您有新的方法来解决它。请帮帮我。
IDEAL
MODEL small
STACK 100h
pic_width equ 5
pic_height equ 6
DATASEG
pic db 0,0,0,0,0
db 0,2,0,2,0
db 0,0,2,0,0
db 0,2,0,2,0
db 0,2,2,2,0
db 0,0,0,0,0
picX dw 100- pic_width/2
picY dw 100 - pic_height/2
x dw ?
y dw ?
color db ?
CODESEG
start:
mov ax, @data
mov ds, ax
mov ax, 013h ; Open Graffic mode
int 010h
mov ax, 0A000h
mov es, ax
call Mouse_Activation
maincycle:
call rand
call DrawPic
check: ;call read key
call CheckClick
cmp si,1
jmp maincycle
casiex:
mov ax, 02h ; restore text mode
int 010h
exit:
mov ax, 4c00h
int 21h
proc ReadKey
push ax
mov ah, 0 ;read the key
int 016h
dec ah ; check if equal to ESC
je casiex ;if equal go to exit
pop ax
ret
endp ReadKey
proc PutPixel
; AX<-X, BX<-Y, DL<-Color
push dx
push ax
push bx
push si
push di
push cx
mov di, 0
mov dx, bx
shl dx, 8
shl bx, 6
add di, ax
add di, bx
add di, dx
mov al, cl
stosb
pop cx
pop di
pop si
pop bx
pop ax
pop dx
ret
endp PutPixel
proc DrawPic
push dx
push ax
push bx
push si
push di
mov dh, pic_height
mov dl, pic_width
mov ax, [picX]
mov bx, [picY]
lea si, [pic] ;mov si,offset pic
cycle:
mov cl, [byte ptr si]
call PutPixel
inc si
inc ax
dec dl
jnz cycle ; X loop
mov dl, pic_width
sub ax, pic_width
inc bx
dec dh
jnz cycle ; Y loop
pop di
pop si
pop bx
pop ax
pop dx
ret
endp DrawPic
proc Rand
push si
push ax
push cx
push bx
push dx
push es
xor si,si
mov ax, 40h ; initialize timer
mov es, ax
mov bx,0
RandLoop: ; generate random number, cx number of times
mov ax, [es:6Ch] ; read timer counter
mov ah, [byte cs:bx] ; read one byte from memory
xor al, ah ; xor memory and counter
and al, 00001111b ; leave result between 0-15
inc bx
cmp si,1
je y1
mov dl,15
mul dl
mov [picX],ax ;mov to x place, the random num
xor si,si
inc si
jmp RandLoop
mov dl,22
y1: mul dl
mov [picY],ax ;mov to x place, the random num
pop es
pop dx
pop bx
pop cx
pop ax
pop si
ret
endp Rand
proc Mouse_Activation
push ax
mov ax,00h ;Initializes the mouse – necessary when want to
int 33h
mov ax,01h ;Show a mouse
int 33h
pop ax
ret
endp Mouse_Activation
proc CleanScreen
push ax
mov ah,0 ;clean the screen
int 10h
pop ax
ret
endp CleanScreen
proc CheckClick
push ax
push cx
push dx
xor si,si
mov ax,05h ; Return button press data
int 33h
shr cx,1 ;CX contains double the real value
mov [x],cx
mov [y],dx
mov bh,0h ;read the value of that pixel
mov cx,[x]
mov dx,[y]
mov ah,0Dh
int 10h ;return al the color
cmp al,2
pop dx
pop cx
pop ax
je ntouch
jmp check
ntouch:
ret
endp CheckClick
END start
答案 0 :(得分:1)
maincycle: call rand call DrawPic check: ;call read key call CheckClick cmp si,1 jmp maincycle
由于cmp si, 1
之后是 UNconditional 跳转,您将获得一个无限循环,可以立即执行非常快速的填充屏幕!
但它不会等到我按下这个角色。
那是因为你从未通过检查BX
的第0位来检查按钮是否被按下。
CheckClick 程序遇到的问题最多。
BX
中提供按钮索引。你不是这样做的。您应该选择鼠标功能03h来检索鼠标位置和点击状态,而不是提供它。BX
并且您没有保留它。 (与 MouseActivation 程序相同。)以下是您可以编写的修改内容:
maincycle:
call rand
call DrawPic
check:
call CheckClick
test si, si ;This is either FALSE(=0) or TRUE(=-1)
jz check ;If FALSE continue checking
jmp maincycle ;If TRUE redraw elsewhere
...
proc CheckClick
push ax
push bx
push cx
push dx
xor si, si ;Start SI at FALSE
mov ax, 03h ; Return button press data
int 33h
test bx, 1 ;Do we have a left button click?
jz ntouch ;No, return FALSE in SI
shr cx,1 ;CX contains double the real value
mov [x], cx
mov [y], dx
mov bh, 0 ;Display page
;mov cx, [x]
;mov dx, [y]
mov ah, 0Dh ;Read pixel with BIOS
int 10h ;Color is in AL
cmp al, 2
jne ntouch
dec si ;Return TRUE in SI
ntouch:
pop dx
pop cx
pop bx
pop ax
ret
mov ax, 013h ; Open Graffic mode int 010h ... mov ax, 02h ; restore text mode int 010h
如果您根本不打算使用 CleanScreen 程序,为什么要编程呢?
mov al, 13h ; Open Graffic mode
call CleanScreen
...
mov al, 02h ; restore text mode
call CleanScreen