;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;宏*初始化*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;write a letter to (y,x) with num times
;如果deta=dl,则横向打印字符,如果deta=dh则竖向打印字符
Init_game macro x,y,letter,deta,num,sign
mov cx,00h
mov dh,x
mov dl,y
sign:
mov ah,02h
mov bh,00h
int 10h
;INT 10h / AH = 0Ah - write character only at cursor position.
;input:
;AL = character to display.
;BH = page number.
;CX = number of times to write character.
push cx
mov ah,0ah
mov al,letter
mov bh,00h
mov cx,01h
int 10h
pop cx
inc cx
inc deta
cmp cx,num
jne sign
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;
;;宏清屏
;;;;;;;;;;;;;;;;;;;;;;;;;;
;int 10h\ah=06h scroll up window
;AL = number of lines by which to scroll (00h = clear entire window).
;BH = attribute used to write blank lines at bottom of window.7h=0111b light gray
;CH, CL = row, column of window's upper left corner.
;DH, DL = row, column of window's lower right corner.
;
clear_screen macro x1,y1,x2,y2
mov ah,06h
mov al,00h
mov bh,07h
mov ch,x1
mov cl,y1
mov dh,x2
mov dl,y2
int 10h
;int 10h\ah=02h set cursor position at (dh,dl)
;DH = row.
;DL = column.
;BH = page number (0..7).
mov ah,02h
mov bh,00h
mov dh,00h
mov dl,00h
int 10h
endm
;;;;;;;;;;;;;;;;;;;;
SHOW macro p1,p2,p3
local Next
mov ch,0
mov cl,p1
mov bx,7
mov si,offset p1
inc si
mov dh,p2
mov dl,p3
Next:
mov ah,2
int 10h
push cx
mov cx,1
mov al,[si]
mov ah,9
int 10h
pop cx
inc dl
inc si
loop Next
endm
DATASEG segment
Mesg1 db 15," BY xiejian "
Mesg2 db 15," No.20032252 "
Mesg4 db 11," Select: "
Menu1 db 11," 1.Easy "
Menu2 db 11," 2.Hard "
hotkey1 db 11,"ESC to Menu"
hotkey2 db 14,"SPACE to pause"
hotkey3 db 18,"Any key to start!!"
let_base db 'a';
letter db 2 dup (?)
speed dw ?,800d,400d
scoremsg db 6,"SCORE:"
hit_sum db ?,0
exitmeg db 21,"Thank you for playing"
DATASEG ENDS
STACK SEGMENT PARA STACK 'STACK'
db 64 dup(0)
STACK ENDS
CODESEG SEGMENT
ASSUME DS:DATASEG, CS:CODESEG
START:
MOV AX, DATASEG
MOV DS,ax
clear_screen 00d,00d,24d,79d
;隐藏光标
mov cx,0
mov ah,1
or ch,00010000b
int 10h
SHOW Mesg1,11d,33d
SHOW Mesg2,13d,33d
mov ah,7
int 21h
Menu:
clear_screen 00d,00d,24d,79d
SHOW Menu1,12d,29d
SHOW Menu2,13d,29d
SHOW Mesg4,16d,29d
Input:
mov ah,2 ;选择难度
mov dh,16d
mov dl,40d
int 10h
mov bl,7
mov ah,1
int 21h
cmp al,1bh
je Exit
push ax
mov ah,1
int 21h
cmp al,0dh
pop ax
jne Error
cmp al,'1'
je eazy
cmp al,'2'
je hard
jmp Error
eazy:
mov ax,speed+2
mov speed,ax
jmp Game_start
hard:
mov ax,speed+4
mov speed,ax
jmp Game_start
Error:
mov ah,2
mov dh,16d
mov dl,29d
int 10h
mov ah,0ah
mov al,' '
mov bl,0
mov cx,2
int 10h
jmp Input
Game_start:
clear_screen 00d,00d,24d,79d
SHOW hotkey1,11,30
SHOW hotkey2,13,30
SHOW hotkey3,15,30
mov ah,7;向下滚屏
int 21h
clear_screen 00d,00d,24d,79d
;画墙壁
;上面用字符0ah填充 y++
;Init_game 00d,00d,0ah,dl,80d,nextsign1
;下面,用字符0ah填充 y++
Init_game 24d,24d,0ah,dl,31d,nextsign2
;左边用字符1ah填充 x++
Init_game 00d,24d,0ah,dh,25d,nextsign3
;右边用字符1ah填充 x++
Init_game 00d,55d,0ah,dh,25d,nextsign4
SHOW scoremsg,10,60
mov al,hit_sum+1
mov hit_sum,al
call print_score
Fall:
call Random
mov dl,ah;获得随机数,保存至dl中 dl 为字母下落的y坐标
add dl,26;基数为26,使其在范围之内
mov al,let_base;把let_base 的字母传给letter
mov letter,al;let_tab=letter
;mov al,let_tab+1
;mov letter+1,al
add letter,ah;然后加上随机数值
;add letter+1,ah
mov dh,0
again:
cmp dh,24; dh计数
je Onfloor
mov ah,2
mov bh,0
int 10h;curser
mov ah,9
mov al,letter
mov bl,7
mov cx,1
int 10h;print letter
delay: mov cx,0
dl1: push cx
mov cx,50000
dl2: loop dl2
;dl=0ffh 表示输入,al=输入字符,否则无输入al=0
push dx
mov ah,6
mov dl,0ffh
int 21h
pop dx
jz pass;无输入则直接下落
cmp al,letter
jz to_hit
cmp al,1bh;=ESC to quit
jz Menu
cmp al,' '
jz pause
pass:
pop cx
inc cx
cmp cx,speed;循环speed次,所以speed越大速度越慢
jne dl1 ;若输入不正确,则继续循环,继续下落,等待击建
jmp erase;正确则清楚下落的字母
;暂停,一直循环,再次输入为空格则解除暂停
pause:
push dx
mov ah,6
mov dl,0ffh
int 21h
pop dx
cmp al,' '
jne pause
jmp pass
;使上面一行的字符消失,其Y值增加,第二次循环的时候在下一行显示
erase:
mov ah,2
int 10h
mov ah,9
mov al,' '
mov cx,1
mov bl,0
int 10h
inc dh;y++
jmp again
;;;;到达地板之后响铃
Onfloor:
call bell
jmp Fall
;击中后处理
to_hit:
;用黄色高亮显示击中的字符
push bx
push cx
mov bh,00h
mov bl,0eh;0eh黄色
mov cx,01h
mov ah,09h
int 10h
pop cx
pop bx
;延时以能看到高亮显示
call sleep
call bell
mov ah,2
int 10h
mov ah,9
mov al,' '
mov cx,1
mov bl,0
int 10h
inc hit_sum;hit_sum++
call print_score;print score
jmp Fall;重新产生字母下落
Exit:
clear_screen 00d,00d,24d,79d
SHOW exitmeg,12,29
mov ah,7
int 21h
MOV AH,4CH
INT 21H
;;;;;;;;;;;;;;;;;functions;;;;;;;;;;;;;;;;;;
print_score proc
push ax
push dx
push cx
cmp hit_sum,10
jae two
mov ah,2
mov dh,12
mov dl,63
int 10h
mov ah,9
mov bl,7
mov al,hit_sum
add al,'0'
mov cx,1
int 10h
jmp A
;;大于十有两位数,要区别对待
two:
mov al,hit_sum
mov ah,0
mov dl,10
div dl
push ax
mov ah,2
mov dh,12
mov dl,62
int 10h ;打印十位
mov ah,9
mov bl,7
add al,'0'
mov cx,1
int 10h
pop ax
mov al,ah
mov ah,2
mov dh,12
mov dl,63
int 10h
mov ah,9
mov bl,7
add al,'0'
mov cx,1
int 10h ;打印个位
A:
pop cx
pop dx
pop ax
ret
print_score endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;将获得的随机数存在ah中
;获得系统时间 dh=秒 dl=百分秒
Random proc
push cx
push dx
mov ah,2ch
int 21h
add dh,dl
mov al,dh
mov ah,0
mov dl,26 ;26个字母 故模26
div dl
pop dx
pop cx
ret
Random endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;延时程序,用了三个嵌套循环
sleep proc
push cx
mov cx,300d
lop1:
push cx
mov cx, 300d
lop2:
push cx
mov cx,300d
lop3:
nop
nop
loop lop3
pop cx
loop lop2
pop cx
loop lop1
pop cx
ret
sleep endp
;;;;;;;;;;;;;;;;;;;
;响铃
bell proc
push dx
push ax
push cx
mov dx,30000d ;turn on/of 30000d times
in al,61h
and al,11111100b
sound: xor al,2
out 61h,al
mov cx,50h ;value of wait
wait1:
loop wait1
dec dx
jne sound
pop cx
pop ax
pop dx
ret
bell endp
CODESEG ENDS
END START