Новичок
Профиль
Группа: Участник
Сообщений: 1
Регистрация: 22.3.2008
Репутация: нет Всего: нет
|
Попробовал написать программу (я в ассемблере начинающий), но столкнулся с проблемами. - Когда кубик движется вниз, то всё нормально (он движется постепенно), но при отскакиваниии от платформы мгновенно перемещается по диагонали до правой границы экрана.
- По идее программа должна реагировать на нажатие клавиши Esc, но он почему-то не реагирует.
Разбирался с этим делом до тех пор, пока мой ЖК монитор (надеюсь временно) перестал вообще отображать что либо в этом графическом режиме.
Если Вас не затруднит, не могли бы мне указать мои ошибки, чтобы эта прога работала нормально и выходила только при потере кубика или нажатии Esc, а не через Alt+Enter и диспетчер задач. Я ещё также переместил блок проверки положения куба в ту часть кода, которая выполняется только тогда, когда его координаты меняются, но проверить уже не смог:(, Впрочем: | Код | .model small .stack 256 .386
.data ;Data Segment--------------------------------
saveMode db ? ; сохраненный видео режим xVal dw 151 ; координата X платформы 160-8-1, т.к. ширина платформы - 16 и смещение с 0 yVal dw 189 ; координата Y платформы xc dw 0; координата X куба yc dw 0; координата Y куба adxc db 1; значение Х, прибавляемое к положению куба при перемещении adyc db 1; значение У, прибавляемое к положению куба при перемещении
.code ; Code Segment-------------------------------- main proc .startup ;инициализация сегмента данных
call SetVideoMode Установить видеорежим call SetIndexes Определить цветовые индексы call DrawCube;Нарисовать куб call DrawPlace; Нарисовать платформу mov ah,00h; Функция чтения счётчика тиков int 1ah; Выполнить прерывание mov bx, dx; Сохранить младшие рязряды количества тиков в bx ;Game Game: mov ah, 1; функция прерывания int 16h для чтения символа с клавиатуры int 16h cmp ah,0 jne checkcursor;Функциональная клавиша не нажата cmp al, 27; Если нажата Escape je Q; то выход иначе продолжаем jmp endkeys; Конец проверок клавиш checkcursor: cmp AH, 75; Указатель курсора влево? jne checkcursor1 cmp xVal,0; Дальнейший сдвиг влево возможен? je endkeys; Конец проверок клавиш call clearplace;Стереть платформу sub xVal,1; Сдвинуть на 1 влево call DrawPlace; Нарисовать платформу jmp endkeys; Конец проверок клавиш checkcursor1: cmp AH, 77; Указатель курсора вправо? jne endkeys; Конец проверок клавиш cmp xVal, 303; Дальнейший сдвиг вправо возможен? (320-16-1=303) je endkeys; Конец проверок клавиш call clearplace;Стереть платформу add xVal,1; Сдвинуть на 1 вправо call DrawPlace; Нарисовать платформу endkeys: mov ah, 5 ;Функция записи символа в буфер клавиатуры прерывания Int 16h mov cx,0 ;Запись 0-го символа int 16h ;Выполнение прерывания CLI ;запрещаем прерывания push ES ;Сохранить содержимое сегментного регистра ES в стеке SUB AX,AX ;обнуляем регистр MOV ES,AX ;добавочный сегмент - с начала памяти MOV AL,ES:[41AH] ;берем указатель на голову буфера MOV ES:[41CH],AL ;посылаем его в указатель хвоста POP ES ; Восстанавливаем содержимое сегментного регистра ES STI ;разрешаем прерывания mov ah,00h; Функция чтения счётчика тиков int 1ah; Выполнить прерывание cmp bx, dx; Сравнить с предыдущим значением тиков je l5; Если совпадают - не перемещать куб mov bx,dx; Сохранить младшие рязряды количества тиков в bx cmp xc,0; Координата куба Х = 0 (касание левого края экрана)? jne l1; нет mov adxc,1; да - следующее перемещение куба по х в положительном направлении (Ось Х направлена вправо) l1: cmp xc,317; Координата куба Х = 317 (320-2-1) (касание правого края экрана)? jne l2; нет mov adxc,-1; да - следующее перемещение куба по х в орицательном направлении l2: cmp yc,0; Координата куба У = 0 (касание верхнего края экрана)? jne l3; нет mov adyc,1; да - следующее перемещение куба по У в положительном направлении (Ось У направлена вниз) l3: cmp yc, 187; Нижняя граница куба поравнялась с нижней границей платформы (187+2=189=yVal)? jae Q; Игра окончена cmp yc, 186; Нижняя граница куба поравнялась с верхней границей платформы ((186+2=188)<(189=yVal) на 1 - высота отбития)? jne l4; нет - куб не отбит mov ax, xVal; Куб по ширине 3 пиксела - если он хотябы половиной коснётся платформы - он отбит, sbb ax, 2; следовательно, допустимо смещение левого края куба на 2 влево от края платформы cmp xc, ax; Условие описанное выше соблюдается? jl l4; нет - куб не отбит adc ax, 18; Проверим правый край. Ширина платформы - 16 +2 вычтенная ранее = 18 cmp xc,ax; Куб попадает на платформу? jg l4; нет - куб не отбит mov adyc, -1; да - куб отбит следующее перемещение куба по У в отрицательном направлении ; Закрасить куб цветом фона ;Вычисление смещения первой точки буфера Куба l4: mov ax,320 ; 320 для режима 13h mul yc ; координата Y куба add ax,xc ; координата X куба ;Поступательное движение куба mov di,ax ; в регистре AX хранится смещение буфера mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры add di,1 mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры add di,1 mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры add di, 320; следующая строка mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры sub di,1 mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры sub di,1 mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры mov ax,0 mov al, adxc; add xc, ax; Переместить куб mov ax,0 mov al, adyc; add yc, ax; Переместить куб call DrawCube;Нарисовать куб
l5: jmp Game; новая итерация цикла Q: call RestoreVideoMode .exit;
main endp
;----------- SetVideoMode proc ;----------- ; Эта процедура сохраняет старый видео режим, переключается в новый и ; указывает регистр ES на видео сегмент
mov ah,0Fh ; получить видеорежим int 10h mov saveMode,al ; сохранить
mov ah,0 ; установить новый видео режим mov al,13h ; режим 13h int 10h
push 0A000h ; адрес видео сегмента pop es ; ES = 0A000h
ret SetVideoMode endp
;------------ RestoreVideoMode proc ;------------ ; Эта процедура ожидает нажатия клавиши, а затем восстанавливает ; прежний видео режим
mov ah, 10h ; ожидает нажатия int 16h
mov ah,0 ; установить видео режим mov al,saveMode ; который был при старте int 10h
ret RestoreVideoMode endp
;----------------- SetIndexes proc ;----------------- mov dx,3c8h ; порт видео палитры (3C8h) mov al,0 ; установить индекс палитры 0 в чёрный out dx,al
mov dx,3c9h ; порт записи 3C9h mov al,0 ; красный out dx,al mov al,0 ; зеленый out dx,al mov al,0 ; синий out dx,al ;------------------------------------------- mov dx,3c8h ; порт видео палитры (3C8h) mov al,1 ; установить индекс палитры 1 в белый out dx,al
mov dx,3c9h ; порт записи 3C9h mov al,63 ; красный out dx,al mov al,63 ; зеленый out dx,al mov al,63 ; синий out dx,al ;------------------------------------------- mov dx,3c8h ; порт видео палитры (3C8h) mov al,2 ; установить индекс палитры 2 в синий out dx,al
mov dx,3c9h ; порт записи 3C9h mov al, 0 ; красный out dx,al mov al, 0 ; зеленый out dx,al mov al,63 ; синий out dx,al
ret SetIndexes endp
;---------------- DrawPlace proc;----------------
; нарисовать платформу
;Вычисление смещения первой точки буфера платформы mov ax,320 ; 320 для режима 13h mul yVal ; координата Y платформы add ax,xVAl ; координата X платформы
mov cx,16 ; нарисовать 16 точек - ширина платформы mov di,ax ; в регистре AX хранится смещение буфера
Place: mov byte ptr es:[di],2 ; рисование точки, 2 - индекс палитры add di,1 loop Place
ret DrawPlace endp
clearplace proc ;Вычисление смещения первой точки буфера платформы mov ax,320 ; 320 для режима 13h mul yVal ; координата Y платформы add ax,xVAl ; координата X платформы
mov cx,16 ; нарисовать 16 точек - ширина платформы mov di,ax ; в регистре AX хранится смещение буфера
clearplace1: mov byte ptr es:[di],0 ; рисование точки, 0 - индекс палитры add di,1 loop clearplace1 ret clearplace endp
DrawCube proc ; Нарисовать куб
;Вычисление смещения первой точки буфера Куба mov ax,320 ; 320 для режима 13h mul yc ; координата Y куба add ax,xc ; координата X куба
mov di,ax ; в регистре AX хранится смещение буфера mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры add di,1 mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры add di,1 mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры add di, 320; следующая строка mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры sub di,1 mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры sub di,1 mov byte ptr es:[di],1 ; рисование точки, 1 - индекс палитры ret DrawCube endp
end
|
|