News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

A game in graphic mode

Started by amrac, December 28, 2009, 03:50:31 PM

Previous topic - Next topic

amrac

We're doing a game which consists of a block that deslocates itself through different columns. This blocks catches little points that fall and when that happends the player gets points. This is a kind of pong game. We already have a beginning  of the game in which we have a square, a little point and the mouse. There are several things that we don't know how to do but my first question is: how can I deslocate the square horizontaly with the help of the mouse or the arrow keys? The next step will be to make the little points fall randomly.

amrac

I'm sorry, I forgot to post my code:
stack segment para stack
   db 64 dup ('mystack' )
   stack ends
   

   mycode segment para 'code'
   myproc proc far
   assume cs:mycode, ss:stack
   
   push ds
   sub  ax,ax
   push ax
   
   mov ah, 00h ; prepara para definir o mod grafico
   mov al, 04  ;modo graf 320x200 color mode
   int 10h         ;invoca a int 10h da BIOS   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,00      ;inicializa a cor de background
   mov bl,01      ;background azul
   int 10h         ;invoca a interrupção 10h da BIOS
   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,01      ;prepara conf do foreground
   mov bl,00      ;verde,vermelho e amarelo
   int 10h         ;invoca a intrrupção 10h 10 da Bios
   
   call rato
   ;desenhar o pontinho
   mov dx,64h      ;selecciona a linha 100
   mov cx,9eh       ; seleciona a coluna 158
   
   
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   ;inc dx         ;vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h      
   
   ;desenhar o primeiro rectangulo
   mov dx,98h      ;selecciona a linha 100
   mov cx,32h      ;selecciona a coluna 158
   call proc1
   
   
   ;2 rectangulo
   ;mov dx,64h      ;selecciona a linha 50
   ;mov cx,032h      ;selectiona a coluna 64
   ;call proc1
   ;desenhar um ponto
   
   
   ;terceiro rectangulo
   ;mov dx,32h      ;selecciona a linha 50
   ;mov cx,064h      ;selectiona a coluna 64
   ;call proc1
   
   
   mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   
   mov ah,00h      ;prepara para definir o modo grafico
   mov al,02h      ;repor modo texto.80.25
   int 10h   
   ;invoca a intrrupção 10h 10 da Bios
   ret
   myproc endp
   
proc1 proc near
   mov bl,0h         ;
   mov bh,0h         ;
   
um:
   mov al,bl
   cmp al,20      ;compara o valor que esta em AL é igual a  20
   jg iniciofor2   ; salta se for igual a 20
   call linha1
   inc bl
   jmp um
   
   ;linhas na vertical
   iniciofor2:
   mov bl,0h   ;inicia for a zero
dois:   
   mov al,bl      ;colocar o valor de bl em al
   cmp al,30      ;compara se o valor que está no al é igual a 30
   jg iniciofor3
   call coluna1
   inc bl
   jmp dois
   
   ;linha horizontal
   iniciofor3:   
   mov bl,0   ;coloca  o 0 no bl
tres:
   mov al,bl
   cmp al,20
   jg iniciofor4      ; salta para inicio4 se for menor  20
   call linha2         ; senão chama o procedimento linha esquerda, que é para desenhar as linhas
   inc bl            ;incrementa o bl
   jmp tres         ;salta para 3
   ;++++++++++++++++++++++++linha vertical em comprimentos ao anterior++++++++++++++++++++++++++++++++++++++++
   iniciofor4:
   mov bl,0h   ;inicia  a zero
quatro:
   mov al,bl
   cmp al,30   ; número de vezes que faz
   jg sair
   call coluna2
   inc bl
   jmp quatro
   
   sair:
   ret
   proc1 endp   ; acaba o procedimento forproc
   
   linha1 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc dx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha1 endp

linha2 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec dx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha2 endp

   
   coluna2 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc cx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna2 endp

coluna1 proc near
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec cx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna1 endp
rato proc near    ;
   mov ax,00
   int 33h
   mov ax,01
   int 33h
   ret
   rato endp


mycode ends
end   

FORTRANS

Hi,

   Just took a quick look.  But what you are going to want
is probably something like the following pseudo code:


MainLoop:
    Check for key
        If key is Right, then
            Erase Box
            Inc Box X position
            Draw Box
        End if
        If key is Left, then
            Erase Box
            Dec Box X position
            Draw Box
        End if
    Erase Point1
    Inc Point1 Y position
    Draw Point1
    Erase Point2
    {And so forth}
    ...
    Wait for a short while,
Loop MainLoop


Steve

amrac

Yes, thank you for your reply. But how can I do it with the mouse? Do you know an example from which I can guide myself?

FORTRANS

Hi,

   Here are two examples.  Simple paint programs.

HTH,

Steve N.


amrac

I have a problem with this game. I have a procedure in which I define the color of the square with the code:
mov al ,01

But when I move the square with the arrow keys I have to paint the square with the color of the background and paint it again to the left. It would be simple to create a variable:
color db 02
and that way I would easily change the value of the variable. But when I change the code to:
mov al,color
I get the error:
"Cannot address with segment register"
How can I solve this problem?

FORTRANS

Hi,

   You need to correctly initialize the DS segment register.
And then tell MASM that you did so with an ASSUME
statement.

   How you initialize DS depends on where you are putting
the "color" variable.  Are you making a separate data
segment or putting it in the code segment?  If the first
try something like.


DATASEG SEGMENT
color   DB      0
DATASEG ENDS

... then go to where you have.
   push ds
   sub  ax,ax
   push ax

... and add
; - - - Initialization - - -
        MOV     AX,SEG DATASEG  ; Set DS for rest of code ...
        MOV     DS,AX
        ASSUME  DS:DATASEG   


Regards,

Steve N.

amrac

Yes, a very basic mistake, I forgot to put the assume directive. Thanks

amrac

Our game has changed and now we detect if the user has clicked the left key and in that case we paint the square with the color of the background. But the problem is that the square doesn't disappear and letters appear on the screen. The program ends if we click the enter key. On the end we receive the message that the program is doing an ilegal instruction. Here is our code:
stack segment para stack
   db 64 dup ('mystack' )
   stack ends

   mydata segment para 'data'
   color db 02
   lado dw 0
   mydata ends

   mycode segment para 'code'
   myproc proc far
   assume cs:mycode, ss:stack, ds:mydata
   
   push ds
   sub  ax,ax
   push ax
   
   mov ah, 00h ; prepara para definir o mod grafico
   mov al, 04  ;modo graf 320x200 color mode
   int 10h         ;invoca a int 10h da BIOS   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,00      ;inicializa a cor de background
   mov bl,01      ;background azul
   int 10h         ;invoca a interrupção 10h da BIOS
   
   
   mov ah,11      ;prepara configuração da palete de cores
   mov bh,01      ;prepara conf do foreground
   mov bl,00      ;verde,vermelho e amarelo
   int 10h         ;invoca a intrrupção 10h 10 da Bios
   
   call rato
   ;desenhar o pontinho
   mov dx,10h      ;selecciona a linha 100
   mov cx,9eh       ; seleciona a coluna 158
   
   
   mov al,02      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   ;inc dx         ;vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h      
   
   ;desenhar o primeiro rectangulo
   mov dx,98h      ;selecciona a linha 100
   mov cx,32h      ;selecciona a coluna 158
   call proc1
   
here:mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   cmp ax, 4b00h
   mov lado,4b00h
   je apaga
   cmp ax,4d00h
   mov lado,4d00h
   je apaga
   mov ah,01        ;apenas espera
   int 21h         ;por outra tecla
   cmp al, 0dh      ;enquanto for diferente de ENTER não sai do programa
   jne here
apaga:mov color,01
   call proc1
   mov ah,00h      ;prepara para definir o modo grafico
   mov al,02h      ;repor modo texto.80.25
   int 10h      ;invoca a interrupção 10h 10 da Bios
   ret
   myproc endp
   
proc1 proc near
   mov bl,0h         ;
   mov bh,0h         ;
   
um:
   mov al,bl
   cmp al,20      ;compara o valor que esta em AL é igual a  20
   jg iniciofor2   ; salta se for igual a 20
   call linha1
   inc bl
   jmp um
   
   ;linhas na vertical
   iniciofor2:
   mov bl,0h   ;inicia for a zero
dois:   
   mov al,bl      ;colocar o valor de bl em al
   cmp al,30      ;compara se o valor que está no al é igual a 30
   jg iniciofor3
   call coluna1
   inc bl
   jmp dois
   
   ;linha horizontal
   iniciofor3:   
   mov bl,0   ;coloca  o 0 no bl
tres:
   mov al,bl
   cmp al,20
   jg iniciofor4      ; salta para inicio4 se for menor  20
   call linha2         ; senão chama o procedimento linha esquerda, que é para desenhar as linhas
   inc bl            ;incrementa o bl
   jmp tres         ;salta para 3
   ;++++++++++++++++++++++++linha vertical em comprimentos ao anterior++++++++++++++++++++++++++++++++++++++++
   iniciofor4:
   mov bl,0h   ;inicia  a zero
quatro:
   mov al,bl
   cmp al,30   ; número de vezes que faz
   jg sair
   call coluna2
   inc bl
   jmp quatro
   
   sair:ret
   cmp color,01
   je muda
   ret
   proc1 endp   ; acaba o procedimento proc1
   
   
   muda proc near
   mov color,02
   jmp here
   ret
   muda endp
linha1 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc dx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha1 endp

linha2 proc near
   
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec dx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
linha2 endp

   
coluna2 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   inc cx         ; vai incrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna2 endp

coluna1 proc near
   mov al,color      ;cor dos pontos vermelho, configura
   mov ah,12      ;conf int 10h para plot do pixel
   dec cx         ; vai decrementar o número de vezes que for chamado dentro do FOR
   int 10h         ;invoca a int 10h
   ret
coluna1 endp
rato proc near    ;
   mov ax,00
   int 33h
   mov ax,01
   int 33h
   ret
   rato endp
   


mycode ends
end   

FORTRANS

Hi,

   You put in the ASSUME, but Idon't see where you
actually initialize DS.

Steve N.


dedndave

also a good idea to name the entry point in the END directive...

        END     myproc

amrac

I have been dividing my game into several parts . In this part I have the little "balls" falling and on the other part I have the square going to the right and to the left. But now I have this problem. I need to have the little balls continuously falling so this means I have an infinite loop. But when I'm in this infinite loop nothing else goes on. But how can I make the infinite loop go on and simultaneously wait for the user to press some keys. For example if he presses 1 it means that the balls fall at velocity one and if he presses 2 it means they'll fall at velocity two and so on. What I mean is that I have my game at an infinite loop but I need other things to go on. How do I do that? Here goes my code:
STACK SEGMENT PARA STACK
   DB   64 DUP ('MYSTACK ')
STACK ENDS
MYDATA SEGMENT PARA 'DATA'
frase1 db 'DDDddddddddd','$'
nivel dw 200
coluna dw 96h
MYDATA ENDS
MYCODE SEGMENT PARA 'CODE'
MYPROC PROC FAR
   ASSUME CS:MYCODE,SS:STACK,DS:MYDATA
   
      PUSH DS
      SUB AX,AX
      PUSH AX
      MOV AX,MYDATA
      MOV DS,AX
      
      MOV AH, 00h
      MOV AL, 04h
      INT 10h
      
      ; MOV AH, 11
      ; MOV BH, 00
      ; MOV BL, 01
      ; INT 10h
      
      MOV AH, 11
      MOV BH, 01
      MOV BL, 00
      INT 10h
      
      
      
      ;push ax
      ;push bx
      ;por a mensagem no ecran
      ;MOV     DX,0       ;256 * row + column (0,0 = upper left corner)
        ;MOV     BH,0
        ;MOV     AH,2
        ;INT     10h
      ;lea dx,frase1         ;coloca mensagem
      ;mov ah,09h            ;inicialização de parâmetro de interrupção
      ;int 21h               ;interrupção que envia frase para o ecran
      ;pop bx
      ;pop ax
      
      ;
      
      push ax
      pix:call pixel
      mov ax,10
      call MsDelay
      jmp pix
      pop ax
      
      push dx
      mov ah,6        ;apenas espera
      mov dl,0ffh
      int 21h         ;por outra tecla
      cmp al,31h      ;se o utilizador carrega na tecla 1 escolhe o nivel um
      je um
      cmp al,32h      ;se o utilizador carrega no 2 escolhe nivel dois (mais lento)
      je dois
      um:mov nivel,200
      dois:mov nivel,500
      pop dx
      
      MOV ah, 01
      INT 21h
      
      MOV AH, 00h
      MOV AL, 02h
      INT 10h
      
      RET
MYPROC ENDP
pixel proc near
      push ax
      push bx
      mov ah,2ch      ;para ir buscar as centésimas de segundo
      int 21h
      sub dh,dh
      mov ax,dx      ;para fazer a multiplicação do valor por ah
      mov cx,0ah
      mul cx
      ;mov aleatorio, ax   ;guarda os centesimos de segundo em aleatorio
      ;o resultado da multiplicação está em ax
      ;o resto fica em dx
      ;vai dividir ax por 2bch
      mov bx,2bch
      div bx
      cmp dx,12ch      ;verificar se o resto da divisao é maior q 300
      jg maior
      maior: mov coluna,12ch      ; se o resto da divisao for maior que 300 retorna a coluna 300
      mov coluna,dx            ;poe o resto da divisao na coluna
      pop bx
      pop ax
            
      mov dx,10h      ;selecciona a linha 100
      mov cx,coluna       ; seleciona a coluna
      
      
      ;MOV DX, 64h
      MOV CX,180
      
Game:
      PUSH CX
      MOV AL, 02      ;pixel cor vermelha
      MOV AH, 12
      MOV CX, coluna
      INT 10h
      
      ;MOV ah, 01
      ;INT 21h      ;espera por uma tecla
      mov     ax, nivel
        call    MsDelay
      
      MOV AL, 00      ;pixel cor preto
      MOV AH, 12
      MOV CX, coluna   ;considerando que temos 300 colunas
      INT 10h
      
      INC DX
      POP CX
      Loop Game
pixel endp
MsDelay proc near
; -----------------------------------------------------------
; This proc delays for the specified number of milliseconds.
; It does this by counting memory refresh requests, which
; for AT-class systems are generated by system timer 1,
; normally programmed by the BIOS to generate an output once
; every 18/1193182 = 15.09 microseconds. Each request toggles
; bit 4 of I/O port 61h. We are counting full cycles of the
; bit, with two toggles per cycle, so each cycle takes 30.18
; microseconds and we count 34 cycles for each millisecond.
;
; Call with the number of milliseconds in AX.
;
; Preserves all registers other than AX.
;
; Note that the delay will be much shorter when running
; under the NT versions of Windows.
; -----------------------------------------------------------
    push cx

    mov cx, ax            ; load msLoop count
  msLoop:
    push cx               ; preserve msLoop counter
    mov cx, 34            ; load repeat count
  wait1:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jz  wait1             ; jump if bit clear
  wait2:
    in  al, 61h           ; read byte from port
    test al, 10h          ; test bit 4
    jnz wait2             ; jump if bit not clear
    dec cx                ; decrement repeat count
    jnz wait1             ; jump if count not zero
    pop cx                ; recover msLoop counter
    dec cx                ; decrement msLoop count
    jnz msLoop            ; jump if count not zero

    pop cx
    ret
MsDelay endp
MYCODE ENDS

   END

amrac

I think I didn't explain myself very well. I have 2 procedures. One is continuously making these balls fall. And the other is waiting for the user to press the keys for right and left to move a rectangle right and left. If I can't use threads of course I will have to interrupt the procedure that makes the balls fall to wait for the keys that are pressed by the user. Is there a way in which I can make a procedure function for some milliseconds and then make the other procedure function another milliseconds?

dedndave

tomorrow, i will have a look at it and see what we can figure out   :U