汇编语言动画程序的设计报告.docx
《汇编语言动画程序的设计报告.docx》由会员分享,可在线阅读,更多相关《汇编语言动画程序的设计报告.docx(44页珍藏版)》请在冰豆网上搜索。
汇编语言动画程序的设计报告
?
一、游戏背景介绍
随着信息时代的发展,计算机已经变为我们生活中不可缺少的一部分,它作为我们了解世界的一个窗口的同时还可以让我们从中以最快的速度查找学习资源,休闲之余,更多的人选择玩小型的益智游戏来放松,因为它不仅达到了娱乐的目的,而且对自己的思维有一定的帮助作用,根据大多数人的娱乐放松需求,我做出了一款动画游戏——可控的汽车与机器人。
上了一学期的汇编语言课,让我对汇编语言有了一定的认识。
这次课程作业我决定亲自动手用汇编语言编写一个型小程序,熟悉计算机体系结构,加深对汇编语言的了解。
DOS操作系统的功能调用及BIOS的功能调用。
进一步了解汇编语言控制计算机硬件的方法,以及如何用汇编语言来实现算法,提高应用汇编语言编程的能力,也加深了自己对一些算法的理解,提高了自己的编程能力。
利用汇编语言编写程序,在屏幕上显示动画,还可以通过键盘上的输入来改变图片的位置,实现动画的运动。
动画游戏程序设计的开始屏幕上会出现一辆小车和一个机器人,操作者可自由选择至少两个运动物体(机器人和汽车)在屏幕上运动,一开始汽车与人分别从左向右、从右向左运动,操作者可以通过屏幕上方现实的提示对机器人和小车进行控制。
可以通过键盘上的W、A、S、D和上下左右的方向键来分别控制运动机器人和小车通过W,A,S,D控制方向,同时整个程序包括人机界面控制台和运动中动画的暂停(空格键控制),开始(ENTER键控制),退出键则由ESC键控制,运动加减速动作(“+”控制逐级加速、“—”控制逐级减速)。
程序插图如图1:
图1动画界面示意图
屏幕上方是操作提示,用户可与根据提示对汽车和小人进行操控,来改变他俩的运动轨迹。
起先车和小人都是各自运动的一个向左另一个向右,操作者可以通过键盘来改变这两物体的运动轨迹,同时在按键盘上的加号会看见物体的运动速率明显加快,减号则反之。
#
二、核心算法思想
本程序定义了两个图分别表示(汽车和机器人),八个坐标变量(汽车清图坐标car_row0car_col0汽车画图坐标car_row1car_col1机器人清图坐标man_row0man_col0机器人画图坐标man_row1man_col1),用于控制汽车和机器人清图和画图的坐标。
首先在屏幕上显示两个物体,让他们按照从左到右和从右到左方式分别运动。
他们的运动是通过不断的修改图片的坐标,并清屏,然后根据新的坐标重新绘制画面来实现的。
通过一大个循环对上面个两个坐标进行改变,每次横坐标加上一个固定的值,或减去一个固定的值。
再通过清图然后重绘实现物体的移动。
为人实现物体能根据操作者的要求上下左右运动,程序实现设定好了几个可以上下左右操控图片位置的键。
每当操作者按下这几个键,系统自动的,将图片位置的横纵坐标进行加上或减去某个固定的值,加的多少还取决于操作者按键次数得多少。
确定图片的位置是通过检测用户的输入和外层大循环不断自加某个数,综合来改变下次重绘的坐标来实现的。
总之要想物体动起来就是通过不断地清屏来清除上次图片的位置,然后获取图片坐标,这个坐标是不断地被用户和系统修改的,并重回新的图片画面,于是用户可以看见物体在屏幕上不断的移动。
以下是让运动起来运动的逻辑图:
图2动画运动算法示意图
首先是清理屏幕上的物体将屏幕刷成黑色,然后获得机器人和小车新的位置坐标,根据这根位置坐标绘制出小车的位置。
从而实现小车的运动。
同时通过操控设定好的上下左右键可以修改坐标,形同会自动根据你按键的次数以及方向键物体的横纵坐标加上或减去一个先前设定好的固定值。
从而实现了,操作者对物体运动东方向的控制。
三、核心算法流程图
主程序:
程序开始,设置显示方式为80X2516色图形方式和提示信息如下:
、
(SPACE--PAUSE,ENTER--BEGAIN,ESC--EXIT,SPEEDUP-+,SLOWDOWN--)
(CAR:
UP--W,DOWN--S,LEFT--A,RIGHT--DMAN:
UP--8,DOWN--2,LEFT--4,RIGHT--6)
调用car_disp和man_disp子程序设置开始图形,起始坐标在数据定义时已给出,然后调用绘图子程序控制汽车和机器人的运动,空格暂停,回车开始,ESC退出,实现动画的主程序算法图如图3。
程序运行后除了绘制移动的人和车外,还要看是否有暂停,开始,和退出的操作。
根据输入对程序运行进行调整。
MOVE子程序:
MOVE子程序是整个程序的核心,通过键盘操作控制汽车和机器人的运动,首先检测键盘,若无键盘操作,运行主程序。
控制物体移动算法图如图4:
$
图4操控物体算法示意图
【
加号和减号分别控制加速和减速,原本主程序会每隔一段时间自动把汽车横坐标加一,人的横坐标减一重复操作,若有键盘响应,则实现自动运动,则通过比较键盘扫描码来确定执行何种操作,“+”按一次速度加快一级,“—”按一次速度减慢一级,WASD控制汽车的上左下右移动,方向键和8、6、2、4都能控制机器人的运动方向,
DISP绘图程序:
DISP输出图形子程序该程序的主要功能是根据定义的图形表画出图形,过程如下:
图5根据自定义图形绘图算法示意图
·
首先获得存放自定义图形字符串数组,进行初始化,再根据坐标获得物体的酒气体坐标然后绘制物体。
汽车和机器人画图子程序:
当汽车和小人运动到边界时就会消失,于是我另外写了两个子程序让运动到边界的物体自此回到界面,这里我让从左边出去的物体从右边出现,从右边出去的的物体从左边出现,这样就像地球是圆的一样,当让当你控制物体从上方或者下方出去时,也会出现在相反反向。
car_disp,man_disp子程序分别用于用于处理汽车和小人运动到屏幕边界的情况,显示图形以及设置坐标。
以汽车为例:
si指向汽车图形表的第一个字符,当行数(car_row1)大于20,跳到第4行,行数(car_row1)小于4,跳到第20行列数(car_col1)小于3,跳到第70列,列数car_col1)大于70,跳到第3列,实现边界设置,再将row1赋给row0,col1赋给col0,即把现在的坐标保留,作为下次清屏的坐标,然后把car_row1赋给dh,car_col1赋给dl,然后在调用DISP画出汽车图形,这样汽车就会从另一个方向冒出来。
总之,这里也是通过修改物体的左边来实现这样的效果的。
清图子程序:
这部分程序主要负责清理上一次绘图留下来的画面为下一步的重绘做准备,实现物体的移动效果,否则会出现物体在上次基础上重绘,变成物体推着尾巴。
影响动画效果。
这部分的代码样式为:
car_clearprocnear;汽车清图子程序
,
clear_carcar_row0,car_col0;调用汽车清图宏
ret;返回
car_clearendp
该程序的主要功能就是调用宏来清图。
因为子程序不能传递参数,所以选择用宏定义来实现参数(坐标)的传递,但是宏展开使得代码很长,而且该子程序调用频繁,以致超过条件转移的范围,系统报错,用子程序就可以解决。
延时子程序DLY:
主要功能使控制延时,通过这个子程序就那个能够控制物体运动的速度。
延时的时间越长,物体运动的速度就越慢,相反延时时间越短,就相当于物体运动的频率加快这样物体运动就加快了。
我采用的是控制延时时间的的长短,从而实现加速和减速。
通过宏定义来实现参数(dlay1)的传递,用“+”“—”来改变dlay1的值,控制延时,因为我给时间设定了几个值于是当用户按加号是就不断自加加到最大之时再自加就变成最小值,减号则反之,所以会看到很快的物体瞬间变慢。
四、源代码
整个程序实现的源代码如下:
~
datasegment;定义数据段
CAR0DB7;汽车的字符图形表
DB0DBH,1,0,0
DB0DBH,1,0,1
DB0DBH,7,0,1
DB0DBH,7,0,1
DB4FH,6,1,0
DB4FH,6,0,-3
—
DB2,6,-2,1
;-----------------------------------------------------------------------------
MANUDB11;机器人的图形表
DB0DBH,09H,0,0
DB0DBH,09H,0,1
DB0DBH,09H,0,1
DB0DBH,09H,0,1
DB0DBH,09H,0,1
】
DB02H,09H,-1,-2
DB03H,0CH,2,0
DB0DBH,09H,1,-1
DB0DBH,09H,0,2
DB0DBH,09H,1,-3
DB0DBH,09H,0,4
;------------------------------画图与清图坐标----------------------------
car_row0db10;汽车清图坐标
(
car_col0db10
car_row1db10;汽车画图坐标
car_col1db10
man_row0db15;机器人清图坐标
man_col0db60
man_row1db15;机器人画图坐标
man_col1db60
~
;延时时间间隔
dlay1dw10000;控制延时变量,即控制速度的变量
;-----------------------------输出提示--------------------------------------
INFO1DB0DH,0AH,'
(SPACE--PAUSE,ENTER--BEGAIN,ESC--EXIT,SPEEDUP--+,SLOWDOWN---)$'
;动画控制提示信息,空格暂停,回车开始,ESC退出,
;“+”按一次速度加快一级,“—”按一次速度减慢一级
'
INFO2DB0DH,0AH,'
(CAR:
UP--W,DOWN--S,LEFT--A,RIGHT--DMAN:
UP--8,DOWN--2,LEFT--4,RIGHT--6)$'
;动画控制提示信息,WASD控制汽车的上左下右移动,方向键控制机器人的运动方向
;---------------------------汽车宏定义--------------------------------
clear_carmacrorow,col;宏定义汽车清图
pushbx
movax,0600H
movch,row
~
decch,1
movcl,col
movdh,ch
movdl,cl
adddh,3;坐标加3
adddl,4;坐标加4
movbh,7
int10h
*
popbx
endm
;----------------------------宏定义机器人-----------------------------
clear_manmacrorow,col;宏定义机器人清图
pushbx
movax,0600H
movch,row
decch,1
\
movcl,col
deccl,0
movdh,ch
movdl,cl
adddh,5;坐标加5
adddl,5;坐标加5
movbh,7
int10H
~
popbx
endm
;----------------------------------------------------------------------------
;主要功能使控制延时,我采用的是控制空制令执行的条数来
;控制延时的长短,从而实现加速和减速。
通过宏定义来实现
;参数(dlay1)的传递,用“+”“—”来改变dlay1的值,控制延时。
;------------------------------延时程序-------------------------------
dmacrodlay1;宏定义延时程序
;
pushcx
pushdx
movdx,dlay1
dl1:
movcx,6801
dl2:
loopdl2
decdx
:
jnzdl1
popdx
popcx
endm
;----------------------------------------------------------------------------
codesegment;定义代码段
mainprocfar;主函数
assumecs:
code,ds:
data
:
start:
pushds
movax,0
pushax
movax,data
movds,ax
moval,3;设置显示方式为80*2516色图形方式
movah,0
)
int10H
leadx,info1;在显示器上显示字符串提示信息
movah,9
int21h
leadx,info2;在显示器上显示字符串提示信息
movah,9
int21h
callcar_disp;初始汽车的位置
@
callman_disp;初始机器人的位置
callMOVE
ret
mainendp
;----------------------------------------------------------------------------
dispprocnear;输出图形子程序
pushax
pushbx
【
pushcx
pushdx
pushsi
subch,ch
movcl,[si]
incsi
next:
adddh,[si+2];改变行列坐标
adddl,[si+3]
【
movah,2;置光标位置DH为行、DL为列
int10h
moval,[si];取字符值
movbl,[si+1];取字符属性
pushcx
movcx,1
movAH,9;显示字符
int10H
"
popcx
addsi,4;SI指向下一个字符
loopnext
popsi
popdx
popcx
popbx
popax
-
ret
dispendp
;----------------------------------------------------------------------------
car_dispprocnear;汽车画图子程序
pushsi
leasi,CAR0;取汽车的图
cmpcar_row1,20;设置汽车运动的边界
jac0;行数大于20,跳到第4行
~
cmpcar_row1,4;行数小于4,跳到第20行
jbc1
cmpcar_col1,3;列数小于3,跳到第70列
jbc2
cmpcar_col1,70;列数大于70,跳到第3列
jac3
jmpcn
c0:
/
movcar_row1,4
jmpcn
c1:
movcar_row1,20
jmpcn
c2:
movcar_col1,70
jmpcn
`
c3:
movcar_col0,3
movcar_col1,3
jmpcn
cn:
movbh,0
;row1赋给row0,col1赋给col0,即把现在的坐标保留,作为下次清屏的坐标
movbl,car_row1
"
movcar_row0,bl
movbl,car_col1
movcar_col0,bl
movdh,car_row1
movdl,car_col1
calldisp;调用DISP画出汽车图形
popsi
ret
%
car_dispendp
;----------------------------------------------------------------------------
car_clearprocnear;汽车清图子程序
clear_carcar_row0,car_col0;调用汽车清图宏
ret;返回
car_clearendp
;----------------------------------------------------------------------------
man_dispprocnear;机器人画图子程序
`
pushsi
leasi,MANU;取机器人的图
cmpman_row1,20;设置机器人运动的边界
jan0;行数大于20,跳到第4行
cmpman_row1,4;行数小于4,跳到第20行
jbn1
cmpman_col1,3;列数小于3,跳到第70列
jbn2
}
cmpman_col1,70;列数大于70,跳到第3列
jan3
jmpnn
n0:
movman_row1,4
jmpnn
n1:
movman_row1,20
~
jmpnn
n2:
movman_col1,70
jmpnn
n3:
movman_col0,3
movman_col1,3
jmpnn
:
nn:
pushbx
;row1赋给row0,col1赋给col0,即把现在的坐标保留,作为下次清屏的坐标
movbh,0
movbl,man_row1
movman_row0,bl
movbl,man_col1
movman_col0,bl
¥
popbx
movdh,man_row1
movdl,man_col1
calldisp;调用DISP画出机器人图形
popsi
ret
man_dispendp
;----------------------------------------------------------------------------
*
man_clearprocnear;机器人清图子程序
clear_manman_row0,man_col0;调用机器人清图宏
ret;返回
man_clearendp
;----------------------------------------------------------------------------
moveprocnear;控制汽车和机器人的运动
pushax
pushbx
{
;-----------------------------取键盘操作-------------------------------
next1:
movah,01H;取键盘缓冲区状态
int16h
jnznext2;缓冲区无按键,等待
DLYdlay1
callcar_clear;汽车一直向右运动
inccar_col1
*
callcar_disp
callman_clear;机器人一直向左运动
decman_col1
callman_disp
jmpnext1
next2:
movah,0;从键盘读字符
int16h
—
;----------------------------------------------------------------------------
DISPprocnear;输出图形子程序
pushax
pushbx
pushcx
pushdx
pushsi
subch,ch
,
movcl,[si]
incsi
next:
adddh,[si+2];改变行列坐标
adddl,[si+3]
movah,2;置光标位置DH为行、DL为列
int10h
moval,[si];取字符值
movbl,[si+1];取字符属性
@
pushcx
movcx,1
movAH,9;显示字符
int10H
popcx
addsi,4;SI指向下一个字符
loopnext
popsi
*
popdx
popcx
popbx
popax
ret
dispendp
;--------------------根据键盘输入判断选择--------------------------
up:
;W汽车向上运动
~
cmpah,11h
jnzdown
callcar_clear
deccar_row1
callcar_disp
jmpnext1
down:
;S汽车向下运动
cmpah,1Fh
|
jnzleft
callcar_clear
inccar_row1
callcar_disp
jmpnext1
left:
;A汽车向左运动
cmpah,1Eh
jnzright
【
callcar_clear
deccar_col1
callcar_disp
jmpnext1
right:
;D汽车向右运动
cmpah,20h
jnzup1
callcar_clear
、
inccar_col1
callcar_disp
jmpnext1
up1:
;机器人向上运动
cmpah,48h
jnzdown1
callman_clear
decman_row1
|
callman_disp
jmpnext1
down1:
;机器人向下运动
cmpah,50h
jnzleft1
callman_clear
incman_row1
callman_disp
|
jmpnext1
left1:
;机器人向左运动
cmpah,4bh
jnzright1
callman_clear
decman_col1
callman_disp
jmpnext1
!
right1:
;机器人向右运动
cmpah,4dh
jnzspeedup1
callman_clear
incman_col1
callman_disp
jmpnext1
speedup1:
;主键盘加号
`
cmpah,0dh;"+"加速运动
jnzspeedup2
subdlay1,1000
jmpnext1
speedup2:
;;小键盘加号
cmpah,4Eh;"+"(小键盘)加速运动
jnzspeeddown1
subdlay1,1000
)
jmpnext1
speeddown1:
;主键盘减