intterrupt, который проверяет, была ли нажата клавиша, и читает, какая клавиша была - PullRequest
1 голос
/ 18 мая 2019

В рамках своего школьного проекта я пытаюсь создать игру со змеями.Мне удалось нарисовать пиксель и заставить его двигаться, используя клавиши a, w, s, d в качестве стрелок.Моя проблема в том, что вместо того, чтобы моя змея двигалась и меняла направление только при нажатии клавиши, моя змея ждет нажатия клавиши (то есть приостанавливает всю мою программу) и только потом продолжает двигаться.Насколько я понимаю, я использовал неправильное прерывание (int 16h \ 00) и хотел бы знать, какие другие прерывания я могу использовать вместо этого.

Я пробовал int 16h \ 01, но все это сделалбыл изменен один раз, а затем продолжил движение в этом направлении.

это часть моего кода, которая отвечает за изменение расположения моего пикселя:

      proc check_press


        ; check for a key press
            mov ah,0
            int 16h 


        ;check what key
        check_key:
            cmp al,119
            je down
            cmp al,97
            je left
            cmp al,100
            je right
            cmp al,115
            je up
            cmp al, 27
            je escape

        up:
        inc [y]
        jmp bye

        left:
        dec [x]
        jmp bye

        down:
        dec [y]
        jmp bye

        right:
        inc [x]
        jmp bye

        escape:
        mov ah, 0
        mov al, 2
        int 10h 

        bye:

    ret 
   endp check_press 

Я бы поблагодарил кого-нибудь с любымидея или даже если кто-то когда-либо писал игру со змеями в сборке, это очень помогло бы

Ответы [ 2 ]

3 голосов
/ 18 мая 2019

Я попробовал int 16h \ 01, но все, что он сделал, это изменил направление один раз, а затем продолжил движение в этом направлении.

Список прерываний Ральфа Брауна содержитописание почти всех прерываний MS-DOS и BIOS.

Описание int 16h, функция 01 на этой странице гласит:

...
Return:
ZF установлено, если нажатие клавиши недоступно
ZF сбрасывается, если доступно нажатие клавиши
AH = код сканирования BIOS
AL = символ ASCII

Примечание: если присутствует нажатие клавиши, это не удалено из буфера клавиатуры
...

Это означает, что функция вернет значение в AX, которое представляет собой значение, которое будет возвращено при вызове функции 00 позже.

Предположим, вы нажимаете клавиши "A", "B", "C" и "D", и вы не вызываете функцию int 16h.Позже вы вызываете функцию 00 четыре раза.В этом случае вы ожидаете, что «A» возвращается в первый раз, «B» во второй раз, «C» в третий раз и «D» в четвертый раз.

Если вы вызываете функцию 01 доВызывая функцию 00 в первый раз, функция всегда будет возвращать «A» (хотя вы нажали «B», «C» и «D» позже), потому что функция 00 вернет «A», когда она будет вызванав следующий раз.

Если вы не вызовете функцию 00, функция 01 вернет "нажатую клавишу" A "навсегда.

Вы должны вызватьint 16h, функция 00, если функция 01 вернула ZF=clear:

  mov ah, 1
  int 16h
  jz noKeyPressed
  mov ah, 0
  int 16h
  ; AX contains information about the key pressed
  ...
noKeyPressed:
  ...
2 голосов
/ 18 мая 2019

Обычно вы хотите, чтобы змея двигалась сама по себе, а не на один блок влево, когда вы нажимаете влево.Так что вы должны установить переменную направления вместо изменения x или y.Весь ваш дизайн построен на этом поведении при нажатии для перемещения, поэтому вам придется его переписать.

Возможно, вы захотите использовать неблокирующее чтение с клавиатуры для проверки ввода с клавиатуры непосредственно передобновление змеи.Или подключите прерывание клавиатуры и обновите переменную направления оттуда.

Вы можете использовать hlt для сна до следующего прерывания (например, по таймеру или клавиатуре), затем проснуться и посмотреть, пора ли перерисовать змею..

Другой вариант может рисовать змею из прерывания по таймеру, но выполнение большой работы в обработчике прерываний - это плохо.

...