Assembly 在游戏中使用鼠标
我正试图做一个游戏(真的很基本),一个字符打印在一个随机的地方(在图形模式)。 然后,如果玩家用鼠标按住它,它会变为其他随机位置 我做了一些功能——计算一个随机的位置,打印字符,然后检查玩家是否按下它 如果没有继续检查,如果是跳转到开始,并计算一个随机位置打印和更多 但我有个问题。 在按下按钮之前,一切都正常,但在按下按钮之后,它会从头开始。 但它不会等到我按下这个角色。它的工作原理就像我一次又一次地按下并继续(在整个屏幕上打印) 我想问题是我没有重置鼠标或其他东西,而且它记得我按了那个颜色,所以直到我按了其他颜色,它才会自动工作 我该怎么办 如果你有办法解决我的问题,或者你有新的方法来解决它。请帮帮我Assembly 在游戏中使用鼠标,assembly,mouse,dos,x86-16,Assembly,Mouse,Dos,X86 16,我正试图做一个游戏(真的很基本),一个字符打印在一个随机的地方(在图形模式)。 然后,如果玩家用鼠标按住它,它会变为其他随机位置 我做了一些功能——计算一个随机的位置,打印字符,然后检查玩家是否按下它 如果没有继续检查,如果是跳转到开始,并计算一个随机位置打印和更多 但我有个问题。 在按下按钮之前,一切都正常,但在按下按钮之后,它会从头开始。 但它不会等到我按下这个角色。它的工作原理就像我一次又一次地按下并继续(在整个屏幕上打印) 我想问题是我没有重置鼠标或其他东西,而且它记得我按了那个颜色,所
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
理想
模型小
堆栈100小时
图5宽度相等
图6高度相等
数据集
pic db 0,0,0,0,0
分贝0,2,0,2,0
分贝0,0,2,0,0
分贝0,2,0,2,0
分贝0,2,2,0
分贝0,0,0,0,0
picX dw 100-pic_宽度/2
picY dw 100-pic_高度/2
x dw?
y-dw?
彩色数据库?
代码段
开始:
mov-ax,@data
mov-ds,ax
mov-ax,013h;开放涂鸦模式
int 010h
移动轴,0A000h
斧头
调用鼠标激活
主循环:
打电话给兰德
打电话给DrawPic
支票:;调用读取键
呼叫CheckClick
cmp-si,1
jmp主循环
卡西克斯:
mov-ax,02h;恢复文本模式
int 010h
出口:
mov-ax,4c00h
int 21h
过程读取键
推斧
mov-ah,0;读钥匙
int 016h
十二月啊,;检查是否等于ESC
杰卡西埃克斯;如果相等,则退出
爆斧
ret
endp读取键
过程计算像素
; 斧头
由于cmp si,1
后面跟着一个无条件跳转,因此您会得到一个无限循环,该循环也会在短时间内以非常快的速度在屏幕上执行
但它不会等到我按下这个角色
这是因为您从不通过检查BX
的位0来检查按钮是否按下
CheckClick过程的问题最多
- 鼠标功能05h依赖于您在
BX
中提供按钮索引。你不能这样做。与其提供它,不如选择鼠标功能03h来检索鼠标位置和单击状态
- 该过程使用了
BX
,您没有保留它。(鼠标激活过程也存在同样的问题。)
- 当像素恰好有错误的颜色时,您只需跳出程序,将返回地址留在堆栈上李>
以下是您可以编写的修改:
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
如果你根本不打算使用它,为什么要编写一个CleanScreen程序
mov al, 13h ; Open Graffic mode
call CleanScreen
...
mov al, 02h ; restore text mode
call CleanScreen
你能给我们看一些你认为可能导致问题的代码吗?我认为我的代码中没有导致问题的东西。我在征求你的经验。游戏中的碰撞很少基于像素数据,更多的时候是基于单独的几何数据,为碰撞计算而优化,也不受最终特殊图形效果或多层图形的影响。也就是说,在你的例子中,像素测试应该足够了,所以你的代码中可能有一些bug。每个操作系统都有自己的与鼠标交互的方法。强调多种方法,因为在我使用过的每个操作系统上,与鼠标交互的方法不止一种。所以这个问题没有给我们任何信息,我们可以帮助你找到代码中的错误。好的,我感谢你的帮助。我明天会添加我的代码,我希望这能帮助我们理解这个问题。我忘了说。。。我将使用干净的屏幕程序,这就是我为什么这么做的原因//
mov ax, 013h ; Open Graffic mode
int 010h
...
mov ax, 02h ; restore text mode
int 010h
mov al, 13h ; Open Graffic mode
call CleanScreen
...
mov al, 02h ; restore text mode
call CleanScreen