2015-03-25 2 views
0

Я работаю над своим окончательным проектом, который является игрой, написанной на ассемблере. Поэтому у меня есть вопрос о том, как сделать таймер во время игры.Как сделать таймер сборки в игре?

Моя игра - простой лабиринт, который работает с W S A D, я уже использую эту команду для запуска программы, пока буфер не получит какой-либо символ.

WaitForData: 
mov ah, 1 
int 16h 
jz WaitForData 
mov ah, 0 
int 16h 

Теперь мне нужен только один таймер, работающий с часами, а не с задержкой.

+2

«Поэтому у меня есть некоторые вопросы о том, как сделать таймер во время игры»: каковы эти вопросы. Вы не задаете ни одного вопроса. –

+0

Это проверка клавиатуры. Почему бы не попробовать 'int 1Ah ah = 0', который извлекает счетчик системных часов? –

+1

https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8&client=ubuntu#q=ralf+brown%27s+interrupt+list&spell=1 –

ответ

1

Таймер создается путем считывания времени из системы, а затем сравнения секунд (например) с предыдущими секундами, если оба они изменились, прошла одна секунда, и вы что-то сделали. Следующий пример - игра змеи, которую я сделал (это на испанском, потому что я costarrican). Часть таймера начинается с комментария «OBTENER HORA DEL SISTEMA». Вы можете скопировать-вставить следующий код в EMU8086 и запустить его.

.MODEL SMALL 

.STACK 1024 

.DATA 

;    0 1 2 3 4 ... 
;   |----|----|----|----|----| 
;  X | 40 | 40 | 40 | 39 | 38 | 
;  Y | 10 | 11 | 12 | 12 | 12 | 
;DIRECCION | A | A | D | D | D | 
;   |----|----|----|----|----| 
; 
;   *  
;   * 
;  *** 

ARRAY_X   DB 100 DUP(0)    

ARRAY_Y   DB 100 DUP(0)    

ARRAY_DIRECCIONES DB 100 DUP(0)    

CUANTOS   DW 3 

SEGUNDOS   DB ? 

ASTERISCO   DB 219,'$' 

BLANCO   DB ' $' 

MINIMO   DW ? 

MAXIMO   DW ? 

SEMILLA   DW ? 

RAND    DB ? 

COLUMNA   DB ? 

FILA    DB ? 

ALIMENTO   DB 1,'$' 

.CODE 

;INICIALIZAR DS. 

MOV AX,@DATA 

MOV DS,AX 

;INICIALIZAR SNAKE CON TRES ELEMENTOS. 

;1. 

MOV SI,OFFSET ARRAY_X + 0 

MOV AL,40 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_Y + 0 

MOV AL,12 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_DIRECCIONES + 0 

MOV AL,'D' 

MOV [SI],AL 

;2. 

MOV SI,OFFSET ARRAY_X + 1 

MOV AL,39 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_Y + 1 

MOV AL,12 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_DIRECCIONES + 1 

MOV AL,'D' 

MOV [SI],AL 

;3. 

MOV SI,OFFSET ARRAY_X + 2 

MOV AL,38 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_Y + 2 

MOV AL,12 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_DIRECCIONES + 2 

MOV AL,'D' 

MOV [SI],AL 

;OBTENER HORA DEL SISTEMA. 

MOV AH,2CH 

INT 21H 

MOV SEGUNDOS,DH 

CALL COMIDA 

LABEL_MOVIMIENTO: 

;VERIFICAR Q. 

MOV AH,0BH 

INT 21H 

CMP AL,0 

JE HORA 

MOV AH,0 

INT 16H 

CMP AL,'Q' 

JNE NO_TERMINAR 

JMP TERMINAR_PROGRAMA 

NO_TERMINAR: 

CMP AL,0 

JNE HORA 

CMP AH,72 

JE LABEL_SUBIR 

CMP AH,80 

JE LABEL_BAJAR 

CMP AH,75 

JE LABEL_IZQUIERDA 

CMP AH,77 

JE LABEL_DERECHA 

JMP HORA 

LABEL_SUBIR: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

MOV AL,'A' 

MOV [SI],AL 

JMP HORA 

LABEL_BAJAR: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

MOV AL,'B' 

MOV [SI],AL 

JMP HORA 

LABEL_IZQUIERDA: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

MOV AL,'I' 

MOV [SI],AL 

JMP HORA 

LABEL_DERECHA: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

MOV AL,'D' 

MOV [SI],AL 

;MOVIMIENTO. 

HORA: 

MOV AH,2CH 

INT 21H 

CMP DH,SEGUNDOS 

JE LABEL_MOVIMIENTO 

MOV SEGUNDOS,DH 

;EXAMINAR DIRECCION. 

MOV BP,0 ;CONTADOR DEL FOR. 

FOR: 

;TERMINAR FOR. 

CMP BP,CUANTOS 

JB SIGUE ;JUMP IF BELOW. 

JMP LABEL_MOVIMIENTO 

SIGUE: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

ADD SI,BP 

MOV AL,[SI] 

CMP AL,'D' 

JE MOVIMIENTO_DERECHA 

CMP AL,'A' 

JE MOVIMIENTO_ARRIBA 

CMP AL,'B' 

JE MOVIMIENTO_ABAJO 

CMP AL,'I' 

JE MOVIMIENTO_IZQUIERDA 

MOVIMIENTO_DERECHA: 

CALL BORRAR 

;AVANZA. 

MOV SI,OFFSET ARRAY_X 

ADD SI,BP 

MOV AL,[SI] 

CMP AL,79 

JB DERECHA_BIEN 

JMP TERMINAR_PROGRAMA 

DERECHA_BIEN: 

INC AL 

MOV [SI],AL 

CALL DESPLEGAR 

JMP FOR 

MOVIMIENTO_ARRIBA: 

CALL BORRAR 

;AVANZA. 

MOV SI,OFFSET ARRAY_Y 

ADD SI,BP 

MOV AL,[SI] 

CMP AL,0 

JA ARRIBA_BIEN 

JMP TERMINAR_PROGRAMA 

ARRIBA_BIEN: 

DEC AL 

MOV [SI],AL 

CALL DESPLEGAR 

JMP FOR 

MOVIMIENTO_ABAJO: 

CALL BORRAR 

;AVANZA. 

MOV SI,OFFSET ARRAY_Y 

ADD SI,BP 

MOV AL,[SI] 

CMP AL,24 

JB ABAJO_BIEN 

JMP TERMINAR_PROGRAMA 

ABAJO_BIEN: 

INC AL 

MOV [SI],AL 

CALL DESPLEGAR 

JMP FOR 

MOVIMIENTO_IZQUIERDA: 

CALL BORRAR 

;AVANZA. 

MOV SI,OFFSET ARRAY_X 

ADD SI,BP 

MOV AL,[SI] 

CMP AL,0 

JA IZQUIERDA_BIEN 

JMP TERMINAR_PROGRAMA 

IZQUIERDA_BIEN: 

DEC AL 

MOV [SI],AL 

CALL DESPLEGAR 

JMP FOR 

TERMINAR_PROGRAMA: 

MOV AX,4C00H 

INT 21H  



DESPLEGAR PROC 

;GOTOXY. 

MOV SI,OFFSET ARRAY_X 

ADD SI,BP 

MOV DL,[SI] 

MOV SI,OFFSET ARRAY_Y 

ADD SI,BP 

MOV DH,[SI] 

MOV AH,2 

MOV BH,0 

INT 10H 

;DISPLAY. 

MOV AH,9 

MOV DX,OFFSET ASTERISCO 

INT 21H 

;VERIFICAR SI HA COMIDO. 

MOV SI,OFFSET ARRAY_X 

ADD SI,BP 

MOV AL,[SI] 

MOV SI,OFFSET ARRAY_Y 

ADD SI,BP 

MOV AH,[SI] 

CMP AL,COLUMNA 

JNE CAMBIO 

CMP AH,FILA 

JNE CAMBIO 

CALL COMIDA 

;OBTENER DATOS DEL ULTIMO ELEMENTO. 

MOV SI,OFFSET ARRAY_X 

ADD SI,CUANTOS 

DEC SI 

MOV AL,[SI] 

MOV SI,OFFSET ARRAY_Y 

ADD SI,CUANTOS 

DEC SI 

MOV AH,[SI] 

MOV SI,OFFSET ARRAY_DIRECCIONES 

ADD SI,CUANTOS 

DEC SI 

MOV BL,[SI] 

;NUEVO ULTIMO ELEMENTO. 

CMP BL,'A' 

JE POQUITO_ABAJO 

CMP BL,'B' 

JE POQUITO_ARRIBA 

CMP BL,'D' 

JE POQUITO_IZQUIERDA 

POQUITO_DERECHA: 

INC AL 

JMP GUARDAR_DATOS 

POQUITO_IZQUIERDA: 

DEC AL 

JMP GUARDAR_DATOS 

POQUITO_ARRIBA: 

DEC AH 

JMP GUARDAR_DATOS 

POQUITO_ABAJO: 

INC AH 

GUARDAR_DATOS: 

MOV SI,OFFSET ARRAY_X 

ADD SI,CUANTOS 

MOV [SI],AL 

MOV SI,OFFSET ARRAY_Y 

ADD SI,CUANTOS 

MOV [SI],AH 

MOV SI,OFFSET ARRAY_DIRECCIONES 

ADD SI,CUANTOS 

MOV [SI],BL 

INC CUANTOS 

CAMBIO: 

MOV SI,OFFSET ARRAY_DIRECCIONES 

ADD SI,BP 

MOV BL,[SI] 

MOV BL,'A' 

CMP [SI],BL 

JE VERTICAL 

MOV BL,'B' 

CMP [SI],BL 

JE VERTICAL 

HORIZONTAL: 

MOV DI,OFFSET ARRAY_Y 

ADD DI,BP 

MOV AL,[DI] 

INC DI 

CMP [DI],AL 

JNE FIN 

MOV AL,[SI] 

INC SI 

MOV [SI],AL     

JMP FIN 

VERTICAL: 

MOV DI,OFFSET ARRAY_X 

ADD DI,BP 

MOV AL,[DI] 

INC DI 

CMP [DI],AL 

JNE FIN 

MOV AL,[SI] 

INC SI 

MOV [SI],AL     

FIN: 

INC BP 

RET 

ENDP 



BORRAR PROC 

;GOTOXY. 

MOV SI,OFFSET ARRAY_X 

ADD SI,BP 

MOV DL,[SI] 

MOV SI,OFFSET ARRAY_Y 

ADD SI,BP 

MOV DH,[SI] 

MOV AH,2 

MOV BH,0 

INT 10H 

;DISPLAY. 

MOV AH,9 

MOV DX,OFFSET BLANCO 

INT 21H 

RET 

ENDP 


COMIDA PROC 

;COLUMNA ALEATORIA. 

MOV MINIMO,0 

MOV MAXIMO,79 

CALL ALEATORIO 

MOV AL,RAND 

MOV COLUMNA,AL 

;FILA ALEATORIA. 

MOV MINIMO,0 

MOV MAXIMO,24 

CALL ALEATORIO 

MOV AL,RAND 

MOV FILA,AL 

;GOTOXY. 

MOV DL,COLUMNA 

MOV DH,FILA 

MOV AH,2 

MOV BH,0 

INT 10H 

;DISPLAY. 

MOV AH,9 

MOV DX,OFFSET ALIMENTO 

INT 21H 

RET 

ENDP 


ALEATORIO PROC 

REPETICION:  

MOV AH,0 

INT 1AH 

ADD SEMILLA,DX 

MOV AX,SEMILLA 

MOV BX,2053 

MOV DX,0 

MUL BX 

MOV BX,13849 

CLC  

ADD AX,BX 

ADC DX,0 

MOV BX,65535 

DIV BX 

MOV AX,DX 

MOV SEMILLA,DX 

MOV AH,0 

SHR AL,1 

CMP AX,MINIMO 

JB REPETICION 

CMP AX,MAXIMO 

JA REPETICION 

MOV AH,0 

CMP AL,RAND 

JE REPETICION 

MOV AH,0 

MOV RAND,AL 

RET 

ENDP  

END 

Мне сказали, что предыдущий код был слишком большим, поэтому я отправляю небольшой таймер. Все, что он делает, это отображать текст каждую секунду. Алгоритм прост: получить системное время, обнаружить, если один вторые прошел, а затем отобразить текст:

.stack 100h 
.data 

text  db 'text$' 
seconds db 99 

.code   
;INITILIZE DATA SEGMENT. 
    mov ax, @data 
    mov ds, ax 

while: 
;GET SYSTEM TIME. 
    mov ah, 2ch 
    int 21h ;RETURN SECONDS IN DH. 
;CHECK IF ONE SECOND HAS PASSED. 
    cmp dh, seconds 
    je no_change 
;IF NO JUMP, ONE SECOND HAS PASSED. VERY IMPORTANT : PRESERVE SECONDS TO 
;USE THEM TO COMPARE WITH NEXT SECONDS. THIS IS HOW WE KNOW ONE SECOND 
;HAS PASSED. 
    mov seconds, dh 
;DISPLAY TEXT EVERY SECOND. 
    mov ah, 9 
    mov dx, offset text 
    int 21h 
no_change: 
    jmp while 

;FINISH THE PROGRAM PROPERLY. 
    mov ax, 4c00h 
    int 21h   

С помощью таймера, как этого можно контролировать призрак с таймером, в то время как pacman находится под контролем клавиатура (например).

+0

Спасибо, Хосе. К сожалению, я проверил бы это еще несколько дней. (У меня есть тест, чтобы пройти первым). Еще немного вопросов. Пример, который вы мне дали, довольно интересный, вы можете объяснить мне, как я могу управлять призраками в Pac-Man? 2) * Только если вы можете * подгонять свой код к моему. Это будет действительно полезно !!! – Ohad

+0

Когда вы обнаруживаете одну секунду, вместо отображения слова «текст», вы перемещаете призрак на два пикселя влево или вправо, вверх или вниз. –

+0

Как мне отобразить второй код с кодом, который вы мне дали? – Ohad