打字游戏程序设计报告.docx
《打字游戏程序设计报告.docx》由会员分享,可在线阅读,更多相关《打字游戏程序设计报告.docx(32页珍藏版)》请在冰豆网上搜索。
打字游戏程序设计报告
第二章打字游戏程序设计内容要求和设计思想
2.1设计内容要求
要求设计的程序需包括:
在游戏开始后,按回车键进入打字游戏;按ESC键返回主界面;按空格暂停;按大写字母E程序结束。
26个字母中的任意一字母从屏幕落下,在下落的过程中键入落下的字母,如果正确,字母消失,分数增加;如果不正确,字母继续下落。
接着继续下落其他字母,如果不正确的字母数大于10个,则游戏结束并返回到成绩界面。
进入成绩界面后显示所得游戏分数,
暂停大概2秒后返回到主菜单。
2.2整体设计思想
程序首先通过宏的定义以及调用宏来画出游戏边框,再通过定义一个函数并调用MOVAH,09INT21H来显示字符串,DS:
DX定义字符串位置。
游戏主程序调用BIOSINT10的9号功能实现对目标文本的颜色和定位。
游戏主程序可以用MOVAH,00INT16H从键盘读取输入的字符再调用MOVAH,01INT21H让键盘输入显示在屏幕中AL=输入的字符,用CMP指令对输入的文本和目标文本进行比较,再利用选择语句在打错字符后对wrong的基数加1,在打对字符后对right的基数加1,并调用清屏函数clear将该字符消除。
对于要求柱形图实时显示正确和错误的数目,可以通过利用“*”在竖向上叠加来实现,字符串结束后直接退到dos环境。
2.3整体设计方案流程图
第三章软件设计
3.1程序流程详细说明
首先运行程序,进入主界面,通过键盘输入字符,先判断是否是“E”,是则直接退出,如果不是“E”,则进入下一步判断是否为数字1,是就按速度1
下落字母,否就进入下一步判断,是否为数字2,是就按速度2下落字母,否就进入下一步判断,是否为数字3,是就按速度3下落字母,否就返回重新输入。
字母随机下落的过程中,检查键盘是否输入ESC,是就返回到主界面,否就继续下落,接着判断玩家输入的字母跟下落的字母是否一样,是就清除该字母,并使RIGHT的基数加1,否就使WRONG的基数加1,接着判断WRONG是否大于10,否就又重新随机下落一字母,是游戏就结束并显示最终成绩,接着就返回到主界面等待新的指令。
3.2程序流程图
3.3重点子程序分析
3.3.1随机产生字母
先初始定义一个由61个无序字母组成的字母列STRD,此字母列包含从A-Z26个字母,将STRD的偏移地址存在DI中,又将字母列的备份存在SI中,定义一个计数寄存器CX,首先置CX为0,程序每产生一个随机字母后CX自动加1,并且比较每次循环时CX是否已经大于61,如果大于61则对屏幕初始化置0,如果大于则继续随机下落字母。
3.3.2字母的下落
字母的下落是整个程序的核心部分,实现该功能的原理是让字母在规定的时间间隔内多次显示,字母每次下移1位,同时上一位自动以空格代替,这样在视觉上就起到了字母自动下落的效果,下落的速度由我们自己决定,本程序中设置了三种速度。
3.4程序中使用的部分重要指令
3.4.1通用数据转送指令MOV
它表示把操作数(SRC),转送给目的操作数(DIST),源操作数不变,目的操作数被源操作数所替代。
转送指令每次可以转送一个字节或一个字,可以实现CPU的内部寄存器之间的数据转送、寄存器和内存之间的数据转送,还可以将立即数送给CPU内部的寄存器。
本设计中大量的用到了MOV指令,如MOVAH,0AHMOVAL,OP3MOVCX,01HMOVBH,00H等等,以实现起数据的传送。
3.4.2无条件转移指令JMP、CALL、RET
(1)当程序中出现JMP指令时,无条件的跳至JMP后所跟的变量处。
其主要有段内短转移、段内直接转移、段间直接转移、段内间接转移、段间间接转移、段内间接转移等操作。
(2)CALL指令为调用子程序,其功能为保护程序断点后,转到子程序处执行。
主要包括段内调用和段间调用。
(3)RET返回指令,通常与CALL指令连用,从子程序返回主程序,通常放在子程序之后。
也包括段内返回和段间返回。
3.4.3条件转移指令
条件转移指令是根据执行该指令时CPU标志的状态而决定是否发生控制转移的指令。
如果满足条件则程序转移到指定的目标地址;如果不满足则继续执行该条件下的下一条指令。
一般与比较指令CMP连用。
在本程序设计中主要用到“JE(相等转移)”、“JA(大于转移)”、“JNE(不相等转移)”等。
3.4.4堆栈操作指令PUSH、POP
PUSH进栈指令的功能是将操作数推入堆栈。
它的源操作数可以是16为通用寄存器、段寄存器或存储器中的数据字,打不能是立即数。
堆栈是以“先进后出”的方式工作的一个存储区,栈区的段址由SS寄存器的内容确定。
堆栈的最大容量可为64K,即一个段的最大容量。
堆栈指针SP始终指向栈顶,其值可以从FFFEH(偶地址)开始,向低地址方向发展,最小为0。
每次执行PUSH操作时,先修改SP的值,使SPSP-2后,然后把操作数压入堆栈种SP指示的位置上,低位字节放在较低地址单元,高位字节放在交高地址单元中。
POP出栈指令的功能是把当前的SP所指向的堆栈顶部的一个字送到指定的目的操作数中。
它的目的操作数可以是16位通用寄存器,段寄存器或存储单元,但CS不能做目的操作数。
每执行一次出栈操作,SPSP+2,即SP向高地址方向移动,指向新的栈顶。
3.4.5算数运算指令ADD、SUB、DIV、INC
ADD加法指令,它的功能是将源操作数相加,结果送到目的操作数中,即
目的源+目的。
SUB减法指令,它的功能是将目的操作数减去源操作数,结果送回目的操作数,即目的目的–源。
DIV无符号数除法指令,它的功能是对两个无符号二进制数进行除法操作。
INC增量指令,它的功能是对目的操作数加1,结果送回目的操作数,即目的目的+1。
ADD,SUB这两条指令的原操作数可以是寄存器、存储器或立即数,目的操作数只能是用寄存器和存储单元。
使用时需注意源和目的操作数不能同时为存储器,而且他们的类型必须一致,即都是字节或字。
DIV指令的原操作数可以是字节或字,如果源操作数为字节,16位被除数必须放在AX中,8位除数为原操作数,他可以是寄存器或存储单元,相除之后,8位商在AL中,余数在AH中。
要是操作数为字,32位被除数在DX,AX中,其中DX为高位字,16位除数作源操作数,他可以是寄存器或存储单元。
相除之后,AX中存16位商,DX存16位余数。
要是被除数只有16位,除数也是16位,则必须将16位被除数送到AX中,再将DX寄存器清0,然后相除。
INC指令的目的操作数可以在通用寄存器或内存种,这条指令主要用在循环程序中,对地址指针和循环计数器等进行修改。
指令执行后影响AF、OF、PF、SF和ZF,但进位标志CF不受影响。
3.5源程序及其说明
DISMACROSTRING,X
MOVAL,3
MOVAH,0
INT10H
MOVBP,SEGSTRING
MOVES,BP
MOVBP,OFFSETSTRING
MOVCX,15
MOVDH,X
MOVDL,29
MOVBL,74H
MOVAL,1
MOVAH,13H
INT10H
ENDM
DIS4MACROSTRING,X,Y;在指定位置以红底蓝字显示字符串
dis2
MOVAL,3
MOVAH,0
INT10H
MOVBP,SEGSTRING
MOVES,BP
MOVBP,OFFSETSTRING
MOVCX,Y;显示字符串的长度
MOVDH,X;行位置
MOVDL,29;列位置
MOVBL,74H;显示字符串的属性74h
MOVAL,1
MOVAH,13H
INT10H
DIS3
DIS5
ENDM
DIS1MACROSTRING1,Y,M;在指定位置处显示字符串
MOVAH,2;置光标位置
MOVBH,0
MOVDH,Y;行标
MOVDL,M;列标
INT10H
MOVAH,09H;显示str1
MOVDX,SEGSTRING1
MOVDS,DX
MOVDX,OFFSETSTRING1
INT21H
ENDM
DIS2MACRO;宏进栈
PUSHAX
PUSHBX
PUSHCX
PUSHDX
ENDM
DIS3MACRO;宏出栈
POPDX
POPCX
POPBX
POPAX
ENDM
DIS5MACROS1,S2
DIS2
MOVAH,6D
MOVAL,0
MOVAL,25D
MOVBH,10100100B;01111111b
MOVCH,0
MOVCL,0
MOVDH,0
MOVDL,80
INT10H
DIS3
ENDM
DIS6MACROZ1,Z2,Z3,Z4;画横向边框的宏
LOCALC5
DIS2
MOVCX,Z1;循环次数
MOVDL,Z2;列
C5:
MOVAH,2;置光标位置
MOVBH,Z3;页号
MOVDH,Z4;行
INT10H
PUSHDX
MOVDL,2AH
INT21H
POPDX
INCDL
LOOPC5
DIS3
ENDM
DIS7MACROQ1,Q2,Q3,Q4;画竖边框的宏
LOCALF1
DIS2
MOVCX,Q4
MOVDH,Q1
F1:
MOVAH,2;置光标位置
MOVBH,Q2
MOVDL,Q3
INT10H
MOVDL,2AH
INT21H
INCDH
LOOPF1
DIS3
ENDM
DATASSEGMENT
STR1DB'Welcometoplaychars',0AH,0DH,'$'
STR2DB'MadebyZhouLiangfeng',0AH,0DH,'$'
STR3DB'2010/1/8',0AH,0DH,'$'
STR4DB'Pleasechoosespeeding',0AH,0DH,'$'
STR5DB'PleasepressEntertocintinue...',0AH,0DH,'$'
STR7DB'speed1',0AH,0DH,'$'
STR8DB'speed2',0AH,0DH,'$'
STR9DB'speed3',0AH,0DH,'$'
STR0DB'Selectthenumberamong1-3',0AH,0DH,'$'
STRADB'<------Pleasechoose----->',0AH,0DH,'$'
STRBDB'score:
','i',0AH,0DH,'$'
STRCDB'Youchoose:
',0AH,0DH,'$'
STRDDB'hqfuvodepfdjygnhtrwgaerjrklubgsnyrsbntrsbngtrdjykuahtrgregfytjgfjytjktru','$'
STREDB'RIGHT:
','$'
ST1DB'RIGHT:
Pause',0AH,0DH,'$'
ST2DB'E:
Quit',0AH,0DH,'$'
ST8DB'Esc:
Back',0AH,0DH,'$'
ST3DB'FunctionMeun',0AH,0DH,'$'
ST4DB'pleaseinput...',0AH,0DH,'$'
ST5DB'SPACE:
Continue',0AH,0DH,'$'
ST6DB'Quitting...',0AH,0DH,'$'
ST7DB'Pressanykeytocontinue',0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,'$'
LENTHEQU$-STRD;STRD的长度
RDB1
MDB0
NDB?
ADB0;速度1选择标志
BDB0;速度2选择标志
VDB0;速度3选择标志
DATASENDS
STACK1SEGMENT
DB100DUP(?
)
STACK1ENDS
CODESSEGMENT
MAINPROCFAR
ASSUMECS:
CODES,DS:
DATAS,SS:
STACK1
START:
MOVAX,DATAS
MOVDS,AX
CALLCLEAR;调用清屏函数,清除dos界面
CALLDISPLAY1;显示主欢迎界面
AG:
MOVA,0;只相应的速度标志为0
MOVB,0
MOVV,0
TH2:
MOVAH,7;无回显输入字符
INT21H
CMPAL,0DH;如果是回车,则继续
JNETH2;否则继续输入
TH1:
CALLCLEAR;调用清屏函数
DIS680,0,0,0;宏调用画上边框
DIS70,0,79,24;宏调用画右3边框
DIS70,0,0,25;宏调用画左1边框
DIS679,0,0,24;宏调用画下边框
DIS1STR4,10,25;宏调用显示欢迎界面及速度选择项
DIS1STR7,12,30
DIS1STR8,14,30
DIS1STR9,16,30
DIS1STR0,20,16
THD:
MOVAH,7;键盘等待输入相应的速度选项
INT21H
CMPAL,31H;判断是否为1
JNEMODIFYA
JMPTHB;是则转,JMP实现间接跳转
MODIFYA:
CMPAL,32H;判断是否为2
JNEMODIFYB
JMPTHC;是则转
MODIFYB:
CMPAL,33H;判断是否为3
JNETHD;不是则转
DIS4STR9,12,10;速度3高亮度显示
DIS1STRC,12,14
MOVV,1;速度3被选中的标志
JMPTHA
THB:
DIS4STR7,12,10;速度1高亮度显示
DIS1STRC,12,14
MOVA,1;速度1被选中的标志
JMPTHA
THC:
DIS4STR8,12,10;速度2高亮度显示
DIS1STRC,12,14
MOVB,1;速度2被选中的标志
THA:
DIS680,0,0,0;宏调用画上边框
DIS70,0,79,24;宏调用画右3边框
DIS70,0,0,25;宏调用画左1边框
DIS679,0,0,24;宏调用画下边框
MOVAH,7;键盘等待确定输入
INT21H
CMPAL,0DH;判断是否是回车确定
JNETHA;不是则继续等待
CALLSLEEP2;屏幕暂停缓冲
CALLCLEAR;调用清屏函数
CALLPAINT;调用函数画游戏边框
CALLGOAL;调用函数显示得分
CALLFALL;调用下落函数
CMPN,1;是否确定退出
JETH9;是则转
JMPAG;不是继续
TH9:
MOVAH,4CH;返回dos界面
INT21H
MAINENDP
;显示功能菜单函数
DISPLAY1PROCNEAR
DIS1STR1,10,25
DIS1STR2,13,29
DIS1STR3,16,31
DIS1STR5,21,19
DIS680,0,0,0
DIS679,0,0,24
DIS70,0,0,25
DIS70,0,79,24
RET
DISPLAY1ENDP
;清屏函数,清除整个屏幕
CLEARPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
MOVAH,6
MOVAL,0
MOVBH,7
MOVCH,0
MOVCL,0
MOVDH,24
MOVDL,79
INT10H
MOVDX,0
MOVAH,2
INT10H
DIS525D,10100100B
DIS3
RET
CLEARENDP
;下落函数,核心子函数
FALLPROCNEAR
LEASI,STRD;传递将要下落的字母子串
T1:
INCSI;加1以便寻找下一个字母
DIS2
MOVAH,6D;置主游戏屏界面颜色
MOVAL,0
MOVAL,23D
MOVBH,01101110B
MOVCH,1;从左上第1行
MOVCL,26;从左上第26列
MOVDH,1;从右上第1行
MOVDL,54;从右上第54列
INT10H
DIS3
CALLRANDOM
MOVDL,AH;获得随机数,保存至dl中dl为字母下落的y坐标
ADDDL,26;基数为26,使其在范围之内
MOVDH,R
MOVCX,23
AGA:
MOVAH,2;置光标位置
MOVBH,0
INT10H
MOVAL,[SI];取下落字符
PUSHDX
MOVDL,AL
MOVAH,02H
INT21H
POPDX
PUSHAX;AX,CX进栈,以防干扰
PUSHCX
MOVCX,0;隐藏字母后面的光标
MOVAH,1
ORCH,00010000B
INT10H
POPCX
POPAX
CALLSP_ADJ
MOVAH,2;置光标位置
MOVBH,0
INT10H
PUSHDX
MOVDL,'';显示空格
MOVAH,02H
INT21H
INT10H
POPDX
SUBAL,AL
PUSHCX
MOVCX,50000
DL2:
LOOPDL2
POPCX
PUSHDX
MOVAH,6
MOVDL,0FFH
INT21H
POPDX
CMPAL,0;判断是否输入
JZT0;没有
CMPAL,[SI];判断是否等于下落的字母
JET7;等于下落的字母,则下落下一个字母
JNEX1
T7:
INCM
CALLPOINT
CALLBELL
JMPT1
X1:
CMPAL,20H
JETA
JNET3
TA:
CALLPAUSE
T3:
CMPAL,45H
JNET0
CALLEXIT
CMPN,1
JET4
T0:
CMPAL,1BH
JNET12
CALLCLEAR
CALLDISPLAY1
JMPT4
T12:
INCDH
SUBCX,1
JZMODIFYC
JMPAGA
MODIFYC:
JMPT1
T4:
RET
FALLENDP
;时间延迟函数及速度1函数
SLEEP1PROC
PUSHCX
MOVCX,550D
LOOP1:
PUSHCX
MOVCX,550D
LOOP2:
PUSHCX
MOVCX,550D
LOOP3:
NOP
NOP
LOOPLOOP3
POPCX
LOOPLOOP2
POPCX
LOOPLOOP1
POPCX
RET
SLEEP1ENDP
;时间延迟函数及速度2函数
SLEEP2PROC
PUSHCX
MOVCX,400D
LOOP4:
PUSHCX
MOVCX,400D
LOOP5:
PUSHCX
MOVCX,400D
LOOP6:
NOP
NOP
LOOPLOOP6
POPCX
LOOPLOOP5
POPCX
LOOPLOOP4
POPCX
RET
SLEEP2ENDP
;时间延迟函数及速度3函数
SLEEP3PROC
PUSHCX
MOVCX,280D
LOOP7:
PUSHCX
MOVCX,280D
LOOP8:
PUSHCX
MOVCX,280D
LOOP9:
NOP
NOP
LOOPLOOP9
POPCX
LOOPLOOP8
POPCX
LOOPLOOP7
POPCX
RET
SLEEP3ENDP
;时间延迟函数及速度3函数
SP_ADJPROC
CMPA,1
JES1
CMPB,1
JES2
CMPV,1
CALLSLEEP3
JMPS3
S1:
CALLSLEEP1
JMPS3
S2:
CALLSLEEP2
S3:
RET
SP_ADJENDP
;画游戏边框
PAINTPROCNEAR
DIS2
DIS680,0,0,0;宏调用画上边框
DIS70,0,55,25;宏调用画右1边框
DIS70,0,56,25;宏调用画右2边框
DIS70,0,79,24;宏调用画右3边框
DIS70,0,0,25;宏调用画左1边框
DIS70,0,24,25;宏调用画左2边框
DIS70,0,25,25;宏调用画左3边框
DIS679,0,0,24;宏调用画下边框
DIS1ST3,6,3
DIS1ST1,9,5
DIS1ST5,11,5
DIS1ST2,13,5
DIS1ST4,17,3
DIS1ST8,15,5
DIS3
RET
PAINTENDP
;分数字符串显示函数
GOALPROCNEAR
DIS2
MOVAH,2;置光标位置
MOVBH,0
MOVDH,11
MOVDL,60
INT10H
MOVAH,09H;显示str1
MOVDX,SEGSTRE
MOVDS,DX
MOVDX,OFFSETSTRE
INT21H
DIS3
RET
GOALENDP
;打印实际得分
POINTPROCNEAR
DIS2
MOVAH,2;置光标位置
MOVBH,0
MOVDH,11
MOVDL,67
INT10H
MOVAL,M
CMP