用汇编写个字符型的flappy bird

来源:互联网 发布:mysql select into 表 编辑:程序博客网 时间:2024/04/29 23:41

虽然以前很少用汇编编写程序,但却感觉到了汇编的强大,以前有些8086的汇编基础,所以准备在8086的环境下试探着写个简单的字符型flappy bird。

写游戏首先得解决的问题就是输出问题,我所知道的方法有两种:一种直接向显存写数据,一种调用中断。在这里使用中断的办法,把输出写成一个函数:

首先调用10号中断2号子程序设置光标坐标:

   mov ah,2   mov bh,0   mov dh,byte ptr ss:[bp+8];y   mov dl,byte ptr ss:[bp+10];x   int 10h;set position

再调用int10  9号显示字符

   mov ah,9   mov al,byte ptr ss:[bp+6];char   mov bl,byte ptr ss:[bp+4];color   mov bh,0   mov cx,ss:[bp+2];repeat   int 10h;draw char


其中颜色用一个字节表示,其定义如下:

twk equ 80h;闪烁bred equ 40h;前景红色bgreen equ 20hbblue equ 10hhlight equ 8h;高亮fred equ 4h;背景红色fgreen equ 2hfblue equ 1h
在绘图之前还得清屏才行,笔者曾试图用int10h 3号中断清屏,但发现速度十分慢,于是采用填充空白的办法把整个屏幕填充掉。

接下来绘图就方便多了,绘制地板直接调用绘图函数就行,绘制水管的过程中需要进行比较,也是十分容易的。

能够绘图了,但怎么才能动起来呢?很简单,循环地执行  清屏-绘制-延时,问题来了,8086怎么延时呢?用中断1ah就能实现,以下引用的其他资料:

时钟服务(Clock Service——INT 1AH) 00H —读取时钟“滴答”计数06H —设置闹钟01H —设置时钟“滴答”计数07H —闹钟复位02H —读取时间0AH —读取天数计数03H —设置时间0BH —设置天数计数04H —读取日期 80H —设置声音源信息 05H —设置日期(1)、功能00H功能描述:读取时钟“滴答”计数入口参数:AH=00H出口参数:AL=00H——未过午夜,否则,表示已过午夜CX:DX=时钟“滴答”计数(2)、功能01H功能描述:设置时钟“滴答”计数入口参数:AH=01HCX:DX=时钟“滴答”计数出口参数:无
来源:汇编时钟服务

注意,CX:DX指的是用CX,DX共同储存一个16位的数,CX为高八位,DX为低八位。我们可以通过循环检测及时的方法实现类似于C语言的sleep函数,以下是我写的延时函数:

 sleept:;Sleep(time)    push bp   mov bp,sp   add bp,2 push ax push cx push dx mov cx,0 mov dx,0mov ah,1mov al,0int 1ah  sloop:mov ax,0  int 1ah  cmp dx,ss:[bp+2]  jb sloop  pop dx  pop cxpop axpop bpret 2

延时程序写好后就能控制管子的移动啦!

既然是游戏,那么获取键盘输入是必不可少的了,这个有点麻烦,在Windows系统下不能直接安装中断,所以如果要通过中断的方式必须得到纯DOS下,可以用DosBox来运行。至于具体的中断安装方法许多书籍给出了实例,这里不再赘述。

游戏运行模式采用通常的实时模式,每一帧都获取输出更新游戏状态并重画游戏界面。

游戏的最终运行效果如下:





参考书籍:《汇编语言》王爽 著


附:

程序源码:

assume cs:codetwk equ 80hbred equ 40hbgreen equ 20hbblue equ 10hhlight equ 8hfred equ 4hfgreen equ 2hfblue equ 1hgroundy equ 20stack segmentdb 1024 dup(0)stack endsdata segmentintaddr dw 0,0 pippos db 10 dup(0) piphdb 10 dup(0) pipgldb 10 dup(0) newpippos dw 0  scrchar db 4 dup(0) score dw 0 pihseri db7,5,4,6,3,4,2,3,6,8,5,5,7,5,4,5,3,5,3,5db6,8,4,3,8,5,6,2,6,8,4,3,8,4,4,7,5,3,4,7db6,8,8,9,5,9,6,8,4,2,3,4,6,7,7,7,6,2,8,4db7,9,9,3,7,7,4,0,7,5,3,8,2,1,9,8,8,2,5,2db5,4,6,4,3,7,2,9,7,4,6,9,6,9,6,6,5,2,2,7 piseripos dw 0  locus  dw -2,-1,0,-1,-1,0,-1,0,0,-1,0,0,0,1,0,1,0,1,2,1,2,2,2,3,2,2,3,2 curlcp dw 0 tick dw 0curpippos dw 0birdpos dw 0data endscode segment  start:mov ax,stackmov ss,axmov sp,0mov ax,datamov ds,ax;install input intmov ax,0mov es,axpush es:[9*4]pop ds:[intaddr]push es:[9*4+2]pop ds:[intaddr+2]mov word ptr es:[9*4],offset inputprocmov es:[9*4+2],csinitdata:mov ds:[birdpos],10 mov ds:[birdpos],10 mov ds:[curpippos],0 mov ds:[tick],0 mov ds:[curlcp],0 mov ds:[piseripos],0 mov ds:[newpippos],0 mov ds:[score],0mov cx,10   cls: mov bx,cx   dec bx   mov byte ptr ds:[pipgl+bx],0   mov byte ptr ds:[pippos+bx],0   mov byte ptr ds:[piph+bx],0loop cls loops:;generate pipe;push cx;;mov cx,10 genpip:;cmp ds:[pipgl],0 mov ax,ds:[tick] mov bl,20 div bl cmp ah,0 jne genlp  mov bx,ds:[newpippos] inc ds:[newpippos] cmp ds:[newpippos],10 jne setpr mov ds:[newpippos],0  setpr:mov si,ds:[piseripos] inc ds:[piseripos] cmp ds:[piseripos],100 jne set2 mov ds:[piseripos],0   set2:   mov ds:[pippos+bx],80   mov al,ds:[pihseri+si] mov ds:[piph+bx],al mov ds:[pipgl+bx],4  genlp:;loop genpip  ;pop cx;  ;gameproc ;move pipe push cx mov cx,10   mvpip:mov bx,cx   dec bx;   cmp ds:[pippos+bx],0   jne de   mov ds:[pipgl+bx],0   de:dec ds:[pippos+bx] loop mvpip pop cx ;move bird mov bx,ds:[curlcp] mov ax,ds:[locus+bx] add ds:[birdpos],ax add ds:[curlcp],2;chkbump:mov ax,ds:[birdpos]cmp ax,groundyjnb gameoverpush cxmov cx,10   ckpip:mov bx,cx   dec bx;   cmp ds:[pippos+bx],41   jne noton   inc ds:[score]      mov ax,ds:[birdpos]   cmp al,ds:[piph+bx]   jna gameover   mov dl,ds:[piph+bx]   add dl,ds:[pipgl+bx]   cmp al,dl   jnb gameover noton:loop ckpippop cx;clear the screenmov ax,0push axpush axpush axpush axmov ax,2000push axcall draw;draw birdmov ax,40push axmov ax,ds:[birdpos]push axmov ax,17push axmov ax,fblue or hlightpush axmov ax,1push axcall drawmov ax,41push axmov ax,ds:[birdpos]push axmov ax,2push axmov ax,fred or hlightpush axmov ax,1push axcall draw;draw scoremov dx,0mov ax,ds:[score]mov dl,100div dladd al,'0'mov ds:[scrchar+1],almov al,ahmov ah,0mov dl,10div dladd al,'0'mov ds:[scrchar+2],aladd ah,'0'mov ds:[scrchar+3],ahmov ds:[scrchar],3mov cx,4scrout:mov ax,3add ax,cxpush axmov ax,3push axmov bx,cxdec bxmov al,ds:[scrchar+bx]mov ah,0push axmov ax,fred or fgreen or hlightpush axmov ax,1push axcall drawloop scrout; draw outline:mov ax,0push axmov ax,groundypush axmov ax,30push axmov ax,fred or fbluepush axmov ax,80push axcall drawmov ax,0push axmov ax,groundy+1push axmov ax,5push axmov ax,fbluepush axmov ax,400push axcall draw; draw pip:push cxmov cx,10drallpip:mov bx,cxdec bxcmp ds:[pipgl+bx],0je dapiendmov ax,0mov al,ds:[pippos+bx]push axmov al,ds:[piph+bx]push axmov al,ds:[pipgl+bx]push axcall drwpipdapiend:loop drallpippop cxmov ax,1push axcall sleeptinc ds:[tick]jmp loopsjmp quitgameover:;gameover  ;sound mov dx,100in al,61h        and al,11111100b sound: xor al, 2out 61h, almov cx, 540h wait1: loop wait1dec dx        jne soundmov ax,0b800hmov es,axmov cx,8anitimes:push cxmov cx,80*25*2overani:mov di,cxdec dixor es:[di],11111111bsub cx,2jnz overanimov ax,1push axcall sleeptpop cxloop anitimesmov ax,10push axcall sleeptjmp initdatainputproc:push axpush bxpush esin al,60hpushfpushfpop bxand bh,11111100bpush bxpopfcall dword ptr ds:[intaddr]cmp al,39hjne ipendmov ds:[curlcp],0  ipend:  pop es   pop bx  pop ax  iret sleept:;Sleep(time)    push bp   mov bp,sp   add bp,2 push ax push cx push dx mov cx,0 mov dx,0mov ah,1mov al,0int 1ah  sloop:mov ax,0  int 1ah  cmp dx,ss:[bp+2]  jb sloop  pop dx  pop cxpop axpop bpret 2 drwpip:;drwpip(pos,hight,gaplength)   push bp   mov bp,sp   add bp,2   push ax   push bx   push cx      mov cx,groundydploop1:mov ax,groundysub ax,cxmov bx,ss:[bp+4]cmp ax,bxjb dpprtadd bx,ss:[bp+2]cmp ax,bxjb dplpend  dpprt:  mov ax,ss:[bp+6] ;call draw  push axmov ax,groundysub ax,cx  push ax;  mov ax,15  push ax  mov ax,fgreen or fblue or  hlight  push ax  mov ax,1  push ax  call drawdplpend:loop dploop1      pop cx   pop bx   pop ax   pop bpret 6   draw:;draw(x,y,char,color,repeat)   push bp   mov bp,sp   add bp,2   push ax   push bx   push cx   push dx      mov ah,2   mov bh,0   mov dh,byte ptr ss:[bp+8];y   mov dl,byte ptr ss:[bp+10];x   int 10h;set position      mov ah,9   mov al,byte ptr ss:[bp+6];char   mov bl,byte ptr ss:[bp+4];color   mov bh,0   mov cx,ss:[bp+2];repeat   int 10h;draw char      pop dx   pop cx   pop bx   pop ax   pop bpret 10   quit:   mov ah,2   mov bh,0   mov dh,0;y   mov dl,26;x   int 10h;set position      mov  ah,4chint 21hcode endsend start


0 0
原创粉丝点击