汇编语言纯汇编语言编写打飞机小游戏

Posted jiange_zh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言纯汇编语言编写打飞机小游戏相关的知识,希望对你有一定的参考价值。

    上学期汇编语言的期末考核可选的一项是用纯汇编语言编写一个小游戏,喜欢动手的我当然首选这个了。小游戏当中用来练手的,一般有贪吃蛇、俄罗斯方块、打飞机之类的咯,于是我选择了其中一个——打飞机!咳咳,选择它可并不是因为个人某种特殊喜好,我想大多数男同胞都会倾向于玩这款游戏@。@

    接下来我就跟大家分享一下如何一步步的完成这项工作,当然,我并不打算把源代码都贴上来,我主要是为大家提供一个思路,必要时提供部分代码~

    首先说明下,本例子的运行环境是windows 32位系统,编译工具是masm6.15。

    先上个效果图镇楼!

    



    写这个游戏,我大概用了半天的时间查找、学习相关资料,一天的时间进行编码和完善,半天的时间进行调试。

    俗话说,万事开头难,想要开始写,却真的不知道从何下手!既然是打飞机游戏,首先要有飞机吧!所以,我们的第一步就是画出一架飞机!

    为获得比较好的画质,本次主游戏页面显示采用了320*200彩色图形显示模式,通过像素点来绘画飞机。

mov ah,00H		;设置显示方式为320*200彩色图形方式
mov al,04H
int 10H

    接下来,我们就画出一架飞机来,由于我用的事图形模式,飞机实际上是由一个点一个点画出来的,为简化程序,我们先写一个画水平线的函数:

;画水平直线
;入口参数 CX相当于X0 DX相当于Y0,Y1 si图像长度 BL像素

sp_line proc
         pusH ax
         pusH bx
         MOV BL,2    ;飞机的颜色
         MOV AH,0cH
         MOV AL,BL
lop:   	 INT 10H
         inc CX
         dec si
         
         jnz lop
         pop bx
         pop ax
         ret
sp_line endp

    由点及线之后,便可以由线及面了,通过长短不同的线条的叠加,即可画出一架飞机来:

;//
;//画玩家飞机子程序 传入参数bx设置飞机的水平位置 BP设置飞机的垂直位置   BX,BP记录飞机的位置
play_plane proc    
	push cx
	push dx
	push es
	push si
	push di
	push ax
	jmp sk

play_plane_1: dw 6,1,1,5,2,3,5,3,3,5,4,3,4,5,5,3,6,7,1,7,11,1,8,11,4,9,5,5,10,3,4,11,5,3,12,7,4,13,2,7,13,2 ;X0,Y,长度

sk: 
	mov cx,ax
	mov ax,cs
	mov es,ax
	mov di,0
         
lop2: 
	mov cx,word ptr es:[play_plane_1+di]    ;x0
        add cx,bx
        mov dx,word ptr es:[play_plane_1+di+2]   ;y
        add dx,bp
        mov si,word ptr es:[play_plane_1+di+4]    ;长度
        
     	call sp_line
     	add di,6
     	cmp di,84
     	jne lop2
     	
	;plane_pos用于记录飞机的位置,此处更新飞机位置
	mov ds:[plane_pos],bx
        mov ds:[plane_pos+2],bp 

     	pop ax 
     	pop di
     	pop si
     	pop es
     	pop dx
     	pop cx
   
     	ret
play_plane endp
    至此,飞机就画出来啦!那下一步要做什么呢?有了一架飞机,最好的体验当然是坐到驾驶座上把它开走咯~

    什么?不会开飞机?没关系,接下来我就教你怎么开飞机!不过,没有驾驶证的小朋友,不要随便试哦~

    首先,当然是坐到驾驶座上咯~然后呢,绑好安全带……

    哈哈,接下来要启动引擎啦~想让飞机移动,先想想移动是什么概念,比如你现在向前走一步,是不是在原来位置的你不见了,而在当前位置出现了一个一模一样的你~

    同样的,要让飞机移动,我们要做的事情是:把原来位置的飞机擦除,然后在新位置画上一架一模一样的飞机!由于我们的游戏背景是黑色的,所以实际上擦除飞机,等于在该位置画一架黑色的飞机将其覆盖掉即可:

;画水平直线
;入口参数 CX相当于X0 DX相当于Y0,Y1 si图像长度 BL像素
sp_line1 proc
         pusH ax
         pusH bx
         pusH bp
         pusH di
     	 MOV bp,CX
      
         MOV di,11
         MOV BL,0    ;飞机的颜色 用来擦除原来的飞机
         MOV AH,0cH
         MOV AL,BL
lop1: 	 INT 10H
         inc CX
         dec di
         
         jnz lop1
         MOV CX,bp
         
         pop di
         pop bp
         pop bx
         pop ax
         ret
sp_line1 endp


play_plane1 proc ;擦除飞机轨迹子程序 传入参数CX,DX
     
      push si
      push di
   
      inc cx
      mov si,13
      
      mov di,0
lop5: inc di
      inc dx
      call sp_line1
      cmp di,14
      jne lop5
      pop di
      pop si

      ret
play_plane1 endp
    有了上面的程序之后,你只需要在测试程序中加入控制语句,当键盘输入←时,调用play_plane1函数擦除飞机,然后飞机的横坐标减1,再调用play_plane画上新的飞机,就能看到飞机移动的效果啦~

    怎么样,这飞机开起来是不是很爽?但是有些朋友不乐意了,咱们可是想要打造一架飞机中的战斗机,你这飞机算什么?

    这还不简单,给我们的飞机装上个大炮不就得了~子弹的移动跟飞机的移动是同样的道理,擦除,新位置画,再擦除,再画……

;//发射子弹子程序
;入口参数 玩家飞机发射口的坐标bx+5,bp
shoot_plane proc
	push ax
	push bx
	push cx
	push dx
	push si
	push bp
	mov cx,bx
 	add cx,5	;x坐标BX+5
	mov dx,bp	;y坐标	
	dec	dx
	;擦除炮弹轨迹,移动炮弹
a0:	MOV BX,2	;宽度
	INC DX
a1:	MOV AH,0CH	;在绘图模式显示一点
	MOV AL,0	;颜色(黑色),用于擦除上一个子弹	
	INT 10H
	INC CX
	DEC BX
	JNZ a1		;擦除炮弹宽度
 	SUB CX,2
	MOV BX,2
	DEC DX
	
a2:	MOV AH,0CH	;在绘图模式显示一点
	MOV AL,11	;颜色(白色),用于画新子弹	
	INT 10H
	INC CX
	DEC BX
	JNZ a2		;画出炮弹宽度
 	SUB CX,2
	CALL delay<span style="white-space:pre">	</span>;时延,可用来调整子弹的移动速度
	DEC DX
	CMP DX,6	;循环画炮弹,到顶端才停止
	JA a0
notdes:	
	;最后一次擦除
	mov bp,sp
	mov cx,word ptr ss:[bp+8]
	add cx,5
	mov dx,7
	MOV AH,0CH	;在绘图模式显示一点
	MOV AL,0	;颜色	
	INT 10H
	inc cx
	MOV AH,0CH	;在绘图模式显示一点
	MOV AL,0	;颜色	
	INT 10H
	pop bp
	pop si
	pop dx
	pop cx
	pop bx
	pop ax
	ret
shoot_plane endp

    这下子好咯,我们的飞机简直就是战斗机了!可是有再大的能耐,没有敌人也只能孤独求败~

    这个时候,总得制造写麻烦出来才好玩。现在很多东西都是一通百通了,敌人的绘画与移动跟飞机如出一辙,此部分我不再赘述。

    tips:我写这个游戏的时候,所有敌人都是统一移动的,这样子比较方便,当然如果你想让游戏更高级一点,可以尝试让敌人异步移动。

    现在问题来了:一方面,敌人会以一定的速度往下移动,而在此同时,我们需要读取键盘的状态来移动我们的飞机,也就是说,我们要做到敌人、我们的飞机同时都能够移动。一开始,我的方案是进行轮询,敌人移动--监测键盘--敌人移动--监测键盘,但是这样子做的效率是十分低下的,飞机移动的响应实在不敢恭维。

    这个时候,系统的时钟中断就派上用场了。我们可以这样设计:主程序中不断查询有无键盘输入,然后当时钟中断来临的时候,进入敌人的移动程序,使得敌人移动。如此一来,键盘的控制得以实时响应,然后每隔一段时间的中断使得敌人移动——这一段程序的执行时间是如此的短,以致于我们几乎感觉不到,所以看上去我们键盘的控制和敌人的移动是同时进行的——这也是我们在单核计算机中得以同时聊着QQ、听着音乐、浏览网页的原理。

        mov al,34h   ; 设控制字值 
    	out 43h,al   ; 写控制字到控制字寄存器 
    	mov ax,0ffffh ; 中断时间设置
    	out 40h,al   ; 写计数器 0 的低字节 
    	mov al,ah    ; AL=AH 
    	out 40h,al   ; 写计数器 0 的高字节 


	xor ax,ax			; AX = 0
	mov ds,ax			; DS = 0
	mov word ptr ds:[20h],offset Timer	; 设置时钟中断向量的偏移地址
	mov ax,cs 
	mov word ptr ds:[22h],ax		; 设置时钟中断向量的段地址=CS

lop3: 
      	call play_plane1	;擦除飞机轨迹
      	call play_plane		;画飞机		
      	mov cx,bx
      	mov dx,bp
again:		
	mov ah,01      ;检测是否有按键,没有的话循环检测
	int 16h
	jz again		;没有按键,显示移动,再次检测
        ;从键盘读入字符          
      	mov ah,0H	
      	int 16H
	 	  
        ;判断字符
      	cmp ah,72
      	je up
      	cmp ah,80
      	je down
      	cmp ah,75
      	je left
      	cmp ah,77
      	je right
	cmp ah,57	;空格
	je shoot
      	cmp ah,16	;Q退出
      	je quite
      	jmp lop3

up: 	sub bp,3
      	jmp lop3
down: 	add bp,3
      	jmp lop3
left: 	sub bx,3 
       	jmp lop3
right: 	add bx,3
        jmp lop3   

shoot:
	call shoot_plane
	jmp lop3

;退出程序
quite:   
	mov ah,4ch
	int 21h
    


Timer:
	push ax
	mov al,byte ptr ds:[timecontrol]   ;timecontrol为设定的敌人移动速度
	cmp byte ptr ds:[delay_timer],al   ;delay_timer等于timecontrol时才移动敌人,否则本次中断不做任何事
	pop ax
	jnz	goout
	mov byte ptr ds:[delay_timer],0
	call move_smile
	call play_smile		;画笑脸
goout:
	inc byte ptr [delay_timer]
	push ax
	mov al,20h			; AL = EOI
	out 20h,al			; 发送EOI到主8529A
	out 0A0h,al			; 发送EOI到从8529A
	pop ax
	iret			; 从中断返回

    好啦~程序的主要部分我都在上面提及了,其他部分,比如如何检测炮弹是否打到了敌人等等,都是体力活,就不在这里介绍了,大家可以自行添加到代码当中,以完善功能。另外,大家可以根据自己的需要和兴趣添加一些相关功能,比如我的程序可以设定敌人的数量、移动速度,可以计算得分等等。

    最后,给大家展示下我的游戏成品:








    Over,thanks!

以上是关于汇编语言纯汇编语言编写打飞机小游戏的主要内容,如果未能解决你的问题,请参考以下文章

双手奉上!一个好玩的小游戏(纯C语言编写)!

C语言零基础项目:打飞机游戏,300行源码分享+详细思路

C语言零基础项目:打飞机游戏,300行源码分享+详细思路

飞机游戏在C语言程序的基本语句能完成功能的体会

飞机游戏在C语言程序的基本语句能完成功能的体会

飞机游戏在C语言程序的基本语句能完成功能的体会