ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
УФИМСКИЙ ГОСУДАРСТВЕННЫЙ АВИАЦИОННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра Вычислительной математики и кибернетики
Курсовая работа
по дисциплине «Основы микропрограммирования»
«Игра Змейка»
Выполнил студент(ка) гр. MO-326_________ |
Асфандиярова Р.Д. |
__.___._______ |
|
Проверила ___________________ |
Нургаянова О.С. |
__.___._______ |
|
Уфа 2011
Содержание
-
Постановка задачи
-
Алгоритм решения
-
Листинг программы
-
Экранные формы
-
Заключение
-
Список использованных источников
-
Постановка задачи
Требуется написать игровую программу «Змейка»: игрок управляет прямоугольной фигурой (“змейкой”) с помощью клавиш. Цель игры – собрать как можно больше объектов (“еда”). При прохождении “змейки” по “еде”, длина “змейки” увеличивается. Игра прекращается, если игрок выходит за игровое поле или допускает самопересечение “змейки”.
-
Алгоритм решения
Словесное описание алгоритма:
-
Инициализируем текстовый режим
-
Выбираем уровень игры(скорость движения змейки)
-
Инициализируем графический режим
-
Инициализируем змею
-
Рисуем поле для змеи
-
Рисуем еду в случайном месте
-
Считываем клавишу
-
Меняем направление движения змейки
-
Если змея живая
-
Рисуем новую змейку на новом месте
-
Решаем съела ли змея еду
-
Если змея съела еду, то рисуем еду в случайном месте и увеличиваем длину змеи
-
Выводим счет
-
Нажимаем какую-нибудь клавишу и выходим из программы
начало
Вводим
уровень игры
Рисуем
змейку
Рисуем
игровое поле
Рисуем
еду
конец
-
Листинг программы
escape equ 01h ;scan code
up equ 48h
down equ 50h
right equ 4dh
left equ 4bh
data segment
speed db 70,55,40,25,10 ;скорость игры
level db 0
color db 0
msg db 'Snake',0ah,0dh
db ' 1.Easier',0ah,0dh
db ' 2.Easy',0ah,0dh
db ' 3.Normal',0ah,0dh
db ' 4.Hard',0ah,0dh
db ' 5.Harder',0ah,0dh
db 'Choose your level:','$'
sx db 200 dup(0) ;позиция змеи
sy db 200 dup(0)
fx db 0 ;позиция еды
fy db 0
x db 20 ;временная позиция головы змеи
y db 20
d db right ;направление
dtemp db right ;временное направление
ls db 4 ;длина змеи
lord db 1 ;жива или нет
N1 DB 29
N2 DB 217
N3 DB 40
SEED DB 0 ;рандомное число
data ends
code segment
assume cs:code,ds:data
go:
mov ax,data ;загрузка сегмента данных
mov ds,ax
mov ah,0 ;очистка экрана
mov al,4
int 10h
mov ah,0
mov al,3
int 10h
mov ah,9 ;вывод сообщения
mov dx,offset msg
int 21h
mov ah,1 ;вводим уровень игры
int 21h
mov level,al
sub level,30h
mov ah,0 ;графический режим
mov al,4
int 10h
mov ah,0bh
mov bh,1
mov bl,0
int 10h
mov bh,0 ;черный фон
int 10h
;инициализируем змею из 4 звеньев
mov sx[1],20
mov sy[1],17
mov sx[2],20
mov sy[2],18
mov sx[3],20
mov sy[3],19
mov sx[4],20
mov sy[4],20
mov dx,4
mov cx,4
ground: ;рисуем красное поле
mov ah,0ch ;(4,4)->(163,163)
mov al,2
int 10h
inc cx
cmp cx,164
jne ground
mov cx,4
inc dx
cmp dx,164
jne ground
newfood:
mov ah,0 ;считываем время системы
int 1ah
mov seed,dl ;записываем время системы для рандома
call food ;рисуем еду в рандомном месте
call score ;показываем счет текущий
direct:
call direction ;получаем новое направление
call liveordie ;решить змея мертвая или живая
cmp lord,0 ;если 0, то мертва и выходим из проги
je quit
draw:
mov bl,4 ;помещаем новую позицию головы змеи в стек
mov al,x
mul bl
push ax
mov al,y
mul bl
push ax
mov color,1 ;зеленый цвет
call pix ;рисуем новую головы змеи
mov ah,0 ;решаем съела ли змея еду
mov al,fx
cmp x,al
jne tail ;нет, то стираем хвост
mov al,fy
cmp y,al
je inclength ;да, то увеличиваем длину змеи
tail:
call newsnake ;рисуем новую змею
call delay ;задержка экрана
jmp direct ;задать следующее направление
inclength:
inc ls ;увеличить длину змеи
lea si,sx ;
lea di,sy
mov ah,0
mov al,ls
add si,ax
add di,ax
;передать новое положение головы змеи
mov al,x
mov [si],al
mov al,y
mov [di],al
call delay ;задержка экрана
;создаем еду
jmp newfood
quit:
;нажать чегог-нибудь для выхода
mov ah,1
int 21h
mov ah,0 ;текстовый режим
mov al,3
int 10h
mov ah,4ch
int 21h
pix proc near ;два параметра
push bp ;сохраняем bp,ax,bx,cx,dx
push ax
push bx
push cx
push dx
mov bp,sp ;получить параметр из стека
mov dx,[bp+14]
mov cx,[bp+12]
line: ;рисуем
mov ah,0ch
mov al,color ;цвет
int 10h
inc cx
mov ax,[bp+12]
add ax,4
cmp cx,ax
jne line
mov cx,[bp+12]
inc dx
mov ax,[bp+14]
add ax,4
cmp dx,ax
jne line
pop dx
pop cx
pop bx
pop ax
pop bp
ret 4 ;2 параметра=4 байта
pix endp
foodpix proc near ;процедура рисования еды
push bp
push ax
push cx
push dx
mov bp,sp
mov dx,[bp+12]
mov cx,[bp+10]
inc cx
mov ah,0ch
mov al,color
int 10h
inc cx
int 10h
inc cx
inc dx
int 10h
inc dx
int 10h
inc dx
dec cx
int 10h
dec cx
int 10h
dec cx
dec dx
int 10h
dec dx
int 10h
pop dx
pop cx
pop ax
pop bp
ret 4
foodpix endp
delay proc near ;процедура задержки экрана
push ax
push bx
push si
push dx
mov ah,2ch ;время чтения, в сотых долях секунды
int 21h
mov bx,dx
lea si,speed ;загрузка адреса для скорости
mov al,level
mov ah,0
add si,ax ;конкретная скорость выбранная пользователем
dec si
time:mov ah,2ch ;время чтения
int 21h
sub dl,bl ;вычитаем старое время
jns compare
add dl,100 ;если получился отрицательный результат, то делаем его положительным
compare:
cmp dl,[si] ;сравнить со скоростью
jl time ;если меньше, то время не увеличиваем
pop dx
pop si
pop bx
pop ax
ret
delay endp
;процедура - принимает время, возвращает рандомное число
rand proc near
push ax
push bx
push cx ;сид=(сид*N1+N2) mod N3
MOV CX,10
MOV AL,SEED
MOV BL,N1
MUL BL
MOV BL,N2
MOV BH,0
ADD AX,BX
DIV N3
MOV SEED,AH
pop cx0
pop bx
pop ax
ret
rand endp
food proc near
push ax
push bx
push cx
push si
push di
food1:
call rand ;получаем новую позицию еды
mov al,seed
mov fx,al
inc fx
call rand
mov al,seed
mov fy,al
inc fy
mov bx,1
lea si,sx
lea di,sy
effect:
mov al,[si+bx]
cmp al,fx
jne next1
mov al,[di+bx]
cmp al,fy
je food1 ;если новая еда на змее, ишем новую позицию
next1:
inc bl
cmp bl,ls
jle effect
drawfood:
mov bl,4
mov al,fx
mul bl
push ax
mov al,fy
mul bl
push ax
mov color,1
call foodpix
pop di
pop si
pop cx
pop bx
pop ax
ret
food endp
;процедура - возвращает новое направление и новую голову
direction proc near
push ax
push si
push di
lea si,sx
lea di,sy
mov ah,0
mov al,ls
add si,ax
add di,ax
mov al,[si]
mov x,al ;сместить старую голову на х и у
mov al,[di]
mov y,al
mov ah,1 ;считываем с клавиатуры
int 16h
jz kup ; если ничего не ввели - направление не меняем
mov al,d ;сохраним старое направление в dtemp
mov dtemp,al
mov d,ah
cmp d,escape ;хотим выйти?
je nodirection ;да - выходим
cmp dtemp,up ;если новое направление обратно старому - идем назад
jne ndown
cmp d,down
je back
ndown:
cmp dtemp,down
jne nleft
cmp d,up
je back
nleft:
cmp dtemp,left
jne nright
cmp d,right
je back
nright:
cmp dtemp,right
jne kup
cmp d,left
jne kup
;используем старое направление
back:mov al,dtemp
mov d,al
; делаем новую голову по новому направлению
kup: cmp d,up
jne kdown
dec x
jmp dend
kdown:
cmp d,down
jne kleft
inc x
jmp dend
kleft:
cmp d,left
jne kright
dec y
jmp dend
kright:
cmp d,right
jne back
inc y
jmp dend
nodirection: ;если ввели выход - то выходим
mov d,0
dend:
mov ah,0ch ;очищаем буффер клавиатуры
mov al,6
mov dl,0ffh
int 21h
pop di
pop si
pop ax
ret
direction endp
newsnake proc near ;процедура создания новой змеи
push ax
push bx
push si
push di
mov bl,4
mov al,sx[1]
mul bl
push ax
mov al,sy[1]
mul bl
push ax
mov color,2 ;красный, такой же как фон
call pix ;стираем хвост
mov bl,1
lea si,sx
lea di,sy
inc si
inc di
news: ;сохранить предыдущий узел следующим
cmp bl,ls
je newhead
mov al,[si+1]
mov [si],al
mov al,[di+1]
mov [di],al
inc bl
inc si
inc di
jmp news
newhead: ;сохраняем временную голову в голову
mov al,x
mov [si],al
mov al,y
mov [di],al
pop di
pop si
pop bx
pop ax
ret
newsnake endp
;процедура проверки жива ли змея или нет
liveordie proc near
push ax
push bx
push si
push di
cmp d,0 ;если нажали на ескейп - выходим
je die
cmp x,0 ;если(x==0||y==0||x==41||y==41)
je die ;вне границ
cmp x,41 ;game over
je die
cmp y,0
je die
cmp y,41
je die
mov bx,1
lea si,sx
lea di,sy
;если новая голова на месте старой, то тоже гейм овер
itself:
mov al,[si+bx]
cmp al,x
jne next2
mov al,[di+bx]
cmp al,y
je die
next2:
inc bl
cmp bl,ls
jl itself
jmp ldend
die:
mov lord,0
ldend:
pop di
pop si
pop bx
pop ax
ret
liveordie endp
score proc near ;процедура вывода очков
push ax
push bx
push cx
push dx
mov ah,2
mov dh,5
mov dl,22
mov bh,0
int 10h
mov al,ls
sub al,4
mul level
mov cx,ax
mov dl,0
L1: cmp cx,100
jnae L2
inc dl
sub cx,100
jmp L1
L2: add dl,30h
mov ah,2
int 21h
mov dl,0
L3: cmp cx,10
jnae L4
inc dl
sub cx,10
jmp L3
L4: add dl,30h
mov ah,2
int 21h
mov dl,cl
add dl,30h
mov ah,2
int 21h
pop dx
pop cx
pop bx
pop ax
ret
score endp
code ends
end go
-
Экранные формы
Меню ввода уровня игры:
Окно игры:
-
Заключение
В результате была написана программа, которая использует два режима: текстовый и графический, также осуществляет вызов и обработку различных прерываний, производит считывание введенных символов с клавиатуры и вывод информации на экран, отрисовку изображения.
-
Список использованных источников
Калашников О. А. Ассемблер? Это просто! Учимся программировать — БХВ-Петербург, 2005. — С. 374. — ISBN 978-5-94157-709-5.
Нортон П., Соухэ Д. Язык ассемблера для IBM PC. М.: Компьютер, 1992.
Юров В. И. Assembler. Специальный справочник. СПб.: Питер, 2000.
http://kalashnikoff.ru
http://assmbler.ru