1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
| name "snake"
; създай snake.com
org 100h;
jmp start
; ------ константи ------
; клавишни кодове на bios
KEY_LEFT equ 4bh
KEY_RIGHT equ 4dh
KEY_UP equ 48h
KEY_DOWN equ 50h
KEY_ESC equ 1bh
KEY_SPC equ 39h
; константи отнасящи се до змията
SNAKE_BODY_COLOR equ 0eh
SNAKE_BODY_CHAR equ '*'
SNAKE_BODY_SIZE equ 7
; координати на змията, посока от главата към опашката
snake dw SNAKE_BODY_SIZE dup(0)
; последен елемент от змията
tail dw ?
; накъде е насочена змията при начално стартиране
cur_dir db KEY_RIGHT
wait_time dw 0
; начално съощение към потребителя, първият ред е празен, защото през него минава змията
; $ се обозначава края на съобщението
msg db "======================", 0dh, 0ah
db "=========Snake=========", 0dh, 0ah
db " Правила на играта:", 0dх, 0ah
db " Змията се управлява от клавишите за посока", 0dh, 0ah
db " ESC спира играта", 0dh, 0ah
db "======================", 0dh, 0ah
db "======================$", 0dh, 0ah
; ------ КОД ------
start:
; Изписване на начално съощение с координати (DS:DX)
mov dx, offset msg
mov ah, 9
int 21h
; скриване на курсора
mov ah, 1
mov ch, 2bh
mov cl, 0bh
int 10h
game_loop:
; Избиране на страница, VIDEO MODE
mov al, 00h
mov ah, 05h
int 10h
; хващане на новата глава на змията
mov dx, snake[0]
; преместване на курсора на позиция (dl, dh);
; DH - red
; DL - kolona
mov ah, 02h
int 10h
; Принтиране върху екрана на SNAKE_BODY_CHAR, на позицията на курсора:
; AL - char - a, знака който ще отпечатва
; BL - cvqt
; CX - колко пъти да повтори знака
mov al, SNAKE_BODY_CHAR
mov ah, 09h
mov bl, SNAKE_BODY_COLOR
mov cx, 1
int 10h
; хващаме опашката
mov ax, snake[SNAKE_BODY_SIZE * 2 - 2]
mov tail, ax
; извикване на процедурата move_snake
call move_snake
; премества курсора на позиция (dl, dh) -> позицията на опашката (tail)
; DH - red
; DL - kolona
mov ah, 02h
mov dx, tail
int 10h
; слага ' ' на позицията на курсора (сриваме старата опашка)
; DH - red
; DL - kolona
mov al, ' '
mov ah, 09h
mov cx, 1
int 10h
check_for_key:
; проверява дали има клавишен код в буфера на клавиетурата
mov ah, 01h
int 16h
jz no_key
; приверява дали е натиснат клавиетурен клавиш
; AH - BIOS kod
; AL - ASCII char
mov ah, 00h
int 16h
; проверява дали последно хванатия клавиш е бил ESC, ако да, се препраща към stop_game
cmp al, KEY_ESC
je stop_game
; хваща се последният натиснат клавиш, като посока
mov cur_dir, ah
no_key:
; ако няма хванат клавиш изчаква малко време преди да провери отново
mov ah, 00h
int 1ah
cmp dx, wait_time
jb check_for_key
add dx, 4
mov wait_time, dx
; вечен интервал
jmp game_loop
stop_game:
; показва курсора черен
mov ah, 1
mov ch, 0bh
mov cl, 0bh
int 10h
ret
; --------------------
; Процедури
; --------------------
; move_snake, създава анимация, като премества
; всяка част от тялото на змията една позиция напред,
; като изтрива опашката после <- това става в главната програма.
; Идеята е последната част се изтрива, а другите части се преместват:
; част0[ i ] -> част[ i + 1 ]
move_snake proc near
mov ax, 40h
mov es, ax
; DI, взема позицията на опашката
mov di, SNAKE_BODY_SIZE * 2 - 2
; премества всички части на змията
mov cx, SNAKE_BODY_SIZE - 1
move_array:
mov ax, snake[di - 2]
mov snake[di], ax
sub di, 2
; върти докато di = 0
loop move_array
cmp cur_dir, KEY_LEFT
je move_left
cmp cur_dir, KEY_RIGHT
je move_right
cmp cur_dir, KEY_UP
je move_up
cmp cur_dir, KEY_DOWN
je move_down
jmp end_move
move_left:
mov al, b.snake[0]
dec al
mov b.snake[0], al
cmp al, -1
jne end_move
mov al, es:[4ah]
dec al
mov b.snake[0], al
jmp end_move
move_right:
mov al, b.snake[0]
inc al
mov b.snake[0], al
cmp al, es:[4ah]
jb end_move
mov b.snake[0], 0
jmp end_move
move_up:
mov al, b.snake[1]
dec al
mov b.snake[1], al
cmp al, -1
jne end_move
mov al, es:[84h]
mov b.snake[1], al
jmp end_move
move_down:
mov al, b.snake[1]
inc al
mov b.snake[1], al
cmp al, es:[84h]
jbe end_move
mov b.snake[1], 0
jmp end_move
end_move:
ret
move_snake endp |