在游戏中使用鼠标 [英] Using the mouse in a game

查看:84
本文介绍了在游戏中使用鼠标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做一个游戏(实际上是基本的),将角色打印在一个随机的地方(在图形模式下). 然后,如果玩家用鼠标按下它,它将切换到其他随机位置.

I’m trying to do a game (really basic) that a character printed on a random place (in graphic mode). And then if the player pressed with the mouse on it, it changes to other random place.

我做了一些功能-计算一个随机位置,打印角色,然后检查玩家是否按下了它 如果不是,则继续检查,如果是,则跳到开头并计算随机放置的打印内容,等等.

I did some function - which calculating a random place, print the character, and then checked if the player pressed on it If no continue to check, if yes jumps to the beginning and calculating a random place print and more...

但是我有一个问题. 在按下之前,一切正常,但是在我按下之后,它从头开始. 但是它不会等到我按下字符时才开始.就像我按下并一次又一次地继续操作(在屏幕上打印)一样.

But I have a problem. Until the pressing everything works fine but then, after I pressed it starts from the beginning. But it doesn’t wait until I press the character. It works like I pressed and continue again and again (print all over the screen).

我的问题是我没有重置鼠标或其他东西-并且记得我按了该颜色,所以直到我按其他颜色后它才自动起作用.

I thing that the problem is that I didn’t reset the mouse or something- and it’s remembers that I pressed on that color so until I pressed on other color it’s works automatically.

我该怎么办?

如果您有办法通过一点零钱来解决我的问题,或者有新的方式来解决它.请帮助我.

If you have a way to solve my problem by little change or if you have a new way to solve it. Please help me.

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

推荐答案

maincycle:
        call rand
        call DrawPic
check:  ;call read key
        call CheckClick
        cmp si,1
        jmp maincycle

由于cmp si, 1之后是无条件跳转,因此您将获得一个无限循环,该循环还可以立即执行非常快的填充屏幕!

Since cmp si, 1 is followed by an UNconditional jump, you get an infinite loop that also executes very fast filling the screen in no time!

但是它不会等到我按下字符.

But it doesn’t wait until I press the character.

那是因为您永远不会通过检查BX的位0来检查是否按下了按钮.

That's because you never check if the button is pressed or not by inspecting bit 0 of BX.

CheckClick 过程的问题最多.

  • 鼠标功能05h依赖于您在BX中提供按钮索引.你不这样做.与其提供它,不如选择鼠标功能03h来检索鼠标位置和单击状态.
  • 该过程使用BX,并且您没有保留它. (与 MouseActivation 过程相同的问题.)
  • 当像素碰巧颜色错误时,您只需跳出该过程即可,将返回地址留在堆栈上!
  • Mouse function 05h relies on you providing the button index in BX. You don't do this. Rather than providing it, you should choose the mouse function 03h to retrieve the mouse position AND the click status.
  • The procedure uses BX and you didn't preserve it. (Same problem with the MouseActivation procedure.)
  • When the pixel happens to have the wrong color, you simply jump out of the procedure leaving the return address on the stack!

以下是您可以编写的修改内容:

Here are modification you can write:

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 程序,为什么要编程呢?

Why did you program a CleanScreen procedure if you're not going to use it at all?

mov  al, 13h    ; Open Graffic mode
call CleanScreen
...
mov  al, 02h    ; restore text mode
call CleanScreen

这篇关于在游戏中使用鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆