最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

純匯編實現(xiàn)打飛機小游戲的示例代碼

 更新時間:2020年01月17日 10:44:32   作者:鐘子悅  
這篇文章主要介紹了純匯編實現(xiàn)打飛機小游戲的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

匯編暑假作業(yè)要求做一個大項目,題目可以自擬。我思來想去,還是覺得做一個小游戲比較有意思。最后選擇了做打飛機游戲。

這里采用的是VGA模式320x200 4色。

打飛機游戲的游戲邏輯比較簡單。首先,飛機可以移動,也可以發(fā)射炮彈;其次,會有敵人不斷地從前方飛過來,如果撞上飛機游戲結束;最后,飛機發(fā)射的炮彈可以擊落敵人。

既然是打飛機,我們就必須首先造一臺飛機,代碼如下:

Comment/***********
	 function:  draw a horizontal line
	 parameters: horizontal position
	       vertical position
	 			 length of the line
	 			 color
	 return:   void
	 description:draw some points horizontally.
	 			 color '0001h' represents drawing a line while
	 			 color '0000h' which is black means erase the line.
**********/
drawALine PROC NEAR 
    PUSH BP
    MOV BP, SP
    PUSH AX
    PUSH CX
    PUSH DX
    PUSH SI
    	
    MOV AH, 0Ch
    MOV CX, [BP+4]
    MOV DX, [BP+6]
    MOV SI, [BP+8]
    MOV AL, Byte Ptr [BP+10]
drawALineLoop:
	  INT 10h
	  INC CX
	  DEC SI
	  JNZ drawALineLoop
    
    POP SI
    POP DX
    POP CX
    POP AX
    MOV SP, BP
    POP BP
    RET
drawALine ENDP  


Comment/***********
	 function:  draw a plane or a missile 
	 parameters: horizontal position
	       vertical position
	       color
	       type (plane or missile or enemy)
	       map length 
	 return:   void
	 description:call "drawALine" function repeatedly.
**********/
drawCraft PROC NEAR
	  
	  PUSH BP
	  MOV BP, SP
	  SUB SP, 8
	  
	  PUSH AX
	  PUSH DX
	  PUSH SI
	  PUSH DI
	  MOV DI, 0
	  
	  MOV AX, [BP+12]
	  MOV [BP-8],AX
	  MOV SI, [BP+10]
	  MOV AX, [BP+8]
	  MOV [BP-6], AX
	  MOV AX, [BP+6]
	  MOV [BP-4], AX
	  MOV AX, [BP+4]
	  MOV [BP-2], AX
drawCraftLoop:
		PUSH Word Ptr [BP-6]
	  MOV DX, Word Ptr [SI]
	  PUSH DX	  
	  PUSH Word Ptr [BP-4]
	  MOV AX, [BP-2]
	  SHR DX, 1
	  SUB AX, DX
	  PUSH AX
	  CALL drawALine
	  ADD SP, 8
	  ADD Word Ptr [BP-4], 1
	  ADD SI, 2
	  INC DI
	  CMP DI, [BP-8]
	  JB drawCraftLoop
	  
	  POP DI
	  POP SI
	  POP DX
	  POP AX  
	  MOV SP, BP
	  POP BP
		RET
drawCraft ENDP

PLANEMAP DW 1,1,3,3,3,3,3,3,7,14,16,14,6,2,2,6,6
N1 EQU ($-PLANEMAP)/2

這里之所以做的這么復雜是出于代碼重用的考慮,相同的代碼只要輸入不同的參數(shù),就能制造出不一樣的東西。這是抽象的思想。

drawCraft 根據(jù)輸入的不同的數(shù)組,可以繪制出不同的東西,比如飛機,導彈,敵人。而不必畫飛機一個函數(shù),畫導彈又是另一個函數(shù)了。

drawCraft主要是一條線一條線地畫,就像3D打印一樣。不過這里是2D的版本。

光畫了飛機不行,我們還需要讓它動起來。動起來的方法很簡單,只需要用黑色覆蓋原圖,然后再在新的位置上建立一個新的即可:

Comment/***********
	 function:  move a plane 
	 parameters: original horizontal position
	       original vertical position
	 			 direction(left-a up-w right-d bottom-s)
	 return:   rectify POS_X, POS_Y
	 description:destory the original and then create a new one	 			 
**********/
movePlane PROC NEAR
		 PUSH BP
		 MOV BP, SP
		 
		 PUSH AX
		 PUSH BX
		 PUSH CX
		 
		 MOV AX,N1
		 PUSH AX
		 MOV AX, Offset PLANEMAP
		 PUSH AX
		 MOV AX, 0000h
		 PUSH AX ;black color
		 MOV AX, [BP+6]
		 PUSH AX
		 MOV AX, [BP+4]
		 PUSH AX
		 CALL drawCraft
		 ADD SP, 10
		 
		 MOV CX, CS:MoveItems
		 MOV AH, Byte Ptr [BP+9]
		 MOV BX, Offset MoveCase
movePlaneLoop1:		 
		 CMP AH, Byte Ptr CS:[BX]
		 JE ToCase
		 ADD BX, 4
		 LOOP movePlaneLoop1
		 
ToCase:	 JMP Word Ptr CS: [BX+2]
MoveItems DW 4
MoveCase DW 75,Case1,72,Case2,77,Case3,80,Case4, 0, Default
Default: JMP EndSwitch
Case1:  SUB POS_X, 5
		 JMP EndSwitch
Case2:	 SUB POS_Y, 5
		 JMP EndSwitch
Case3:	 ADD POS_X, 5
		 JMP EndSwitch
Case4:  ADD POS_Y, 5
	
EndSwitch:
;draw a new plan in new position
		 MOV CX, N1
		 PUSH CX
		 MOV CX, Offset PLANEMAP
		 PUSH CX
		 MOV CX, 0001h
		 PUSH CX
	   PUSH POS_Y
	   PUSH POS_X
	   CALL drawCraft
		 ADD SP, 10
EndMovePlane:

		 POP CX
		 POP BX
		 POP AX
		 MOV SP, BP 
		 POP BP
		 RET
movePlane ENDP

有了飛機,還要發(fā)射炮彈啊。我所期望的飛機,應該是可以多連發(fā)的,而且是無限發(fā)!那玩起來才爽。于是我設計了這樣的數(shù)組。

MISSILE  DW 512 DUP('$$')
MISSILESNUM DW 0 

這是什么意思呢?我們一步一步來看。首先這是存儲每次發(fā)射炮彈,炮彈所在的位置(橫坐標和縱坐標)。

每當玩家按下空格鍵,就向數(shù)組里添加位置信息。這是為了方便后面讓導彈一起上升。

在沒有鍵盤輸入的時候。我們想讓導彈自己上升。為了做到這點,我們需要遍歷這個MISSILE數(shù)組,每找到一個位置信息,就讀出來,刪除它,然后更新數(shù)組位置信息(只需要更新縱坐標),然后再在新的位置上畫一個導彈就行了。

以下是具體實現(xiàn)代碼

Comment/***********
	 function:  
	 parameters: horizontal position
	       vertical position
	 return:   rectify 'MISSILE' and 'MISSILESNUM'
	 description:When press the space key, this program will put 
	       the position into the 'MISSILE' array.
	       Then call 'drawMissile' to display it. 	 
**********/
fireMissile PROC NEAR	
		 PUSH BP
	   MOV BP, SP
	   
	   PUSH CX
	   PUSH DX
	   PUSH SI
	   PUSH DI
	   
	   MOV CX, [BP+4]
	   MOV DX, [BP+6]
	   SUB DX, 5
		 MOV SI, Offset MISSILE
fireMissileLoop:
		 CMP Word Ptr [SI], '$$'
		 JZ fireMissileIf
		 ADD SI, 4
		 JMP fireMissileLoop
fireMissileIf:
     MOV [SI], CX
     MOV [SI+2], DX
     
     MOV DI, N2
     PUSH DI
     MOV DI, Offset MISSILEMAP
     PUSH DI
     MOV DI, 0003h
     PUSH DI
     PUSH DX
     PUSH CX
     CALL drawCraft
     ADD SP, 10
		 
		 INC MISSILESNUM
		 POP DI
	   POP SI
	   POP DX
	   POP CX
	   MOV SP, BP
	   POP BP
	   RET
fireMissile ENDP


Comment/***********
	 function:  rise all the existing missiles 
	 parameters: void
	 return:   rectify MISSILE and MISSILESNUM
	 description:When there is no input event, this program will
	 			 rise all the existing missiles which stored in 
	 			 the 'MISSILE' array unless there is no missile.
**********/
riseMissile PROC NEAR
		 PUSH BP
		 MOV BP, SP
		 
		 PUSH SI
		 PUSH CX
		 PUSH DX
			  
		 MOV SI, Offset MISSILE
		 MOV CX, 256
riseMissileLoop:		 
		 CMP Word Ptr [SI], '$$'
		 JZ riseMissileIf
		 
		 MOV DX, N2
		 PUSH DX
		 MOV DX, Offset MISSILEMAP
		 PUSH DX 
		 MOV DX, 0000h
		 PUSH DX
		 MOV DX, Word Ptr [SI+2]
		 PUSH DX
		 MOV DX, Word Ptr [SI]
		 PUSH DX
		 CALL drawCraft
		 ADD SP, 10
		 
		 SUB Word Ptr [SI+2],2
		 JLE riseMissileIf2
		 
		 MOV DX, N2
		 PUSH DX
		 MOV DX, Offset MISSILEMAP
		 PUSH DX 
		 MOV DX, 0003h
		 PUSH DX
		 MOV DX, Word Ptr [SI+2]
		 PUSH DX
		 MOV DX, Word Ptr [SI]
		 PUSH DX
		 CALL drawCraft
		 ADD SP, 10
		 
		 JMP riseMissileIf
riseMissileIf2:
		 MOV Word Ptr [SI], '$$'
		 MOV Word Ptr [SI+2], '$$'
		 DEC MISSILESNUM	 
riseMissileIf:	
		 ADD SI, 4 
		 LOOP riseMissileLoop
		 
		 POP DX
		 POP CX
		 POP SI
		 POP AX	
		  
		 MOV SP, BP
		 POP BP
		 RET
riseMissile ENDP

以上做的都是具體的例程。做到這里,回過頭看一下我們主程序的實現(xiàn)。

整個游戲是依靠主程序調(diào)用一個個例程來運作的。

Start:
	  MOV AX, _DATA
	  MOV DS, AX
	  CLI
	  MOV AX, _STACK
	  MOV SS, AX
	  MOV SP, Offset TOS
	  STI
	  
	  CALL init
	  
	  MOV AH, 00h
	  MOV AL, 04h
	  INT 10h
	  MOV CX, N1
	  PUSH CX
	  MOV SI, Offset PLANEMAP
	  PUSH SI
	  MOV CX, 0001h
	  PUSH CX
	  PUSH POS_Y
	  PUSH POS_X
	  CALL drawCraft
	  ADD SP, 10
Again:	  
	  MOV AH,01h
	  INT 16h
Next: 
	  JZ Process
	  MOV AH, 00h
 	  INT 16h
	  CMP AL, 27
	  JZ EndMain
	  CMP AL, ' '
	  JZ Shoot
	  PUSH AX
	  PUSH POS_Y
	  PUSH POS_X
	  CALL movePlane
	  ADD SP, 6
	  JMP Again
Shoot: 
	  PUSH POS_Y
	  PUSH POS_X
	  CALL fireMissile
	  ADD SP, 4
	  JMP Again
Process:
	  CALL showScoreByDemical
	  CALL checkCollision
	  INC TIMER
	  MOV DX, DIFFICULTY
	  CMP TIMER, DX
	  JBE Loc1 
	  CALL dropEnemy 
	  MOV DX, MAX
	  SUB DX, TIMER
	  MOV TIMER, 0
	  CMP ENEMYNUM, DX
	  JA Loc1
	  CALL generateEnemy
Loc1:
	  CMP MISSILESNUM, 0
	  JZ Again
	  CALL riseMissile
	  JMP Again

解釋一下:Again開始是主程序。先判斷有沒有鍵盤輸入,如果有,判斷是不是ESC(退出),然后再判斷是不是空格(攻擊),如果都不是,就執(zhí)行 movePlane,在movePlane中實現(xiàn)具體的移動過程。

如果沒有鍵盤輸入,就執(zhí)行Process后面的代碼。這段代碼稍后解釋。

有了飛機,有了導彈,還需要有敵人啊。敵人的制作過程和導彈類似。也建立一個ENEMY數(shù)組來存儲每一個敵人的位置信息,并在沒有鍵盤輸入的時候進行更新。只要注意導彈是上升,敵人是下降。

之后是檢測碰撞,我是用二重循環(huán)遍歷了MISSILE 和 ENEMY兩個數(shù)組。一開始我寫的是嚴格相等才算碰撞,后來玩的時候發(fā)現(xiàn)這條件太苛刻了,于是改成了在一定范圍內(nèi)就行。

Comment/***********
	 function:  check if there is any collision
	 parameters: void
	 return:   void
	 description:check vertical pos and horizontal pos, if both are 
	       equel, delete one of them.
**********/
checkCollision PROC NEAR	
		 PUSH BP
		 MOV BP, SP	

		 PUSH AX
		 PUSH BX
		 PUSH CX
		 PUSH DX
		 PUSH SI
		 PUSH DI
		 
		 MOV SI, Offset ENEMY
		 MOV DI, Offset MISSILE
		 MOV AX, 0
		 MOV BX, 0
checkCollisionLoop1:
		 CMP Word Ptr [SI], '$$'
		 JZ checkCollisionIf
		 
		 MOV CX, POS_X
		 SUB CX, Word Ptr[SI]
		 JGE checkCollisionLoc1
		 NEG CX
checkCollisionLoc1:
		 CMP CX, 8
		 JA checkCollisionLoop2
		 	
		 MOV DX, POS_Y
		 SUB DX, Word Ptr[SI+2]
		 JGE checkCollisionLoc2
		 NEG DX
checkCollisionLoc2:
		 CMP DX, 1
		 JA checkCollisionLoop2
		 
		 ;game over
		 PUTS GAMEOVER
		 CALL delay
		 MOV AX, 4C00h
		 INT 21h 
		  
	checkCollisionLoop2:	 
		 CMP Word Ptr [DI], '$$'
		 JZ checkCollisionIf3
		 
		 MOV CX, Word Ptr[SI]
		 SUB CX, Word Ptr[DI]
		 JGE checkCollisionLoc3
		 NEG CX
	checkCollisionLoc3:
		 CMP CX, 5
		 JA checkCollisionIf3
		 
		 MOV DX, Word Ptr[SI+2]
		 SUB DX, Word Ptr[DI+2]
		 JGE checkCollisionLoc4
		 NEG DX
	checkCollisionLoc4:
		 CMP DX, 5
		 JA checkCollisionIf3
		 
		 JMP deleteEnemy
	checkCollisionIf3:	 
		 INC BX
		 ADD DI, 4
		 CMP BX, 256
		 JB checkCollisionLoop2
	
checkCollisionIf:
		 ADD SI, 4
		 MOV BX, 0
		 INC AX
		 CMP AX, 256
		 MOV DI, Offset MISSILE
		 JB checkCollisionLoop1 
		 JMP checkCollisionEnd
		 
deleteEnemy:		 
		 MOV DX, N3
		 PUSH DX
		 MOV DX, Offset ENEMYMAP
		 PUSH DX 
		 MOV DX, 0000h
		 PUSH DX
		 MOV DX, Word Ptr [SI+2]
		 PUSH DX
		 MOV DX, Word Ptr [SI]
		 PUSH DX
		 CALL drawCraft
		 ADD SP, 10
		 MOV Word Ptr [SI], '$$'
		 MOV Word Ptr [SI+2], '$$'
		 DEC ENEMYNUM
		 ADD SCORE, 2
	
		 JMP checkCollisionIf3
		 
checkCollisionEnd:
		  
		 POP DI
		 POP SI 
		 POP DX
		 POP CX
		 POP BX
		 POP AX
		 MOV SP, BP	
		 POP BP	
		 RET
checkCollision ENDP

到這里,主要的例程都已經(jīng)結束了。

再回過頭看一下主程序的代碼。

Again:	  
	  MOV AH,01h
	  INT 16h
Next: 
	  JZ Process
	  MOV AH, 00h
 	  INT 16h
	  CMP AL, 27
	  JZ EndMain
	  CMP AL, ' '
	  JZ Shoot
	  PUSH AX
	  PUSH POS_Y
	  PUSH POS_X
	  CALL movePlane
	  ADD SP, 6
	  JMP Again
Shoot: 
	  PUSH POS_Y
	  PUSH POS_X
	  CALL fireMissile
	  ADD SP, 4
	  JMP Again
Process:
	  CALL showScoreByDemical
	  CALL checkCollision
	  INC TIMER
	  MOV DX, DIFFICULTY
	  CMP TIMER, DX
	  JBE Loc1 
	  CALL dropEnemy 
	  MOV DX, MAX
	  SUB DX, TIMER
	  MOV TIMER, 0
	  CMP ENEMYNUM, DX
	  JA Loc1
	  CALL generateEnemy
Loc1:
	  CMP MISSILESNUM, 0
	  JZ Again
	  CALL riseMissile
	  JMP Again

從Process開始,首先調(diào)用的是顯示分數(shù)的例程(比較容易我沒放上來),然后先檢測是否碰撞。這里設置了一個DIFFICULTY變量,是適應不同難度(DIFFICULTY)。TIMER是用來定時的。每次都+1,加到DIFFICLUTY的值才執(zhí)行敵人下降的例程。

難度大的話,敵人移動速度快,只需要把DIFFICULTY的值設小一點,就可以更快的使敵人下降;反之亦然。

附上一些效果圖。

附上源碼:https://github.com/zhongyuchen/hitplanegame

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 匯編程序設計之DOSBox模擬環(huán)境配置

    匯編程序設計之DOSBox模擬環(huán)境配置

    最近在學習匯編語言設計,然后上網(wǎng)找關于匯編程序的編譯軟件,不負有心人,終于找到了我需要的軟件,值得慶幸
    2023-08-08
  • 匯編語言 寄存器內(nèi)存訪問原理解析

    匯編語言 寄存器內(nèi)存訪問原理解析

    這篇文章主要介紹了匯編語言 寄存器內(nèi)存訪問原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 匯編語言指令集之條件轉(zhuǎn)移指令實現(xiàn)

    匯編語言指令集之條件轉(zhuǎn)移指令實現(xiàn)

    這篇文章主要介紹了匯編語言指令集之條件轉(zhuǎn)移指令實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • 匯編語言學習assume的作用詳解

    匯編語言學習assume的作用詳解

    這篇文章主要為大家介紹了匯編語言學習assume的作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2021-11-11
  • 詳解如何在Mac上用匯編語言寫HelloWorld

    詳解如何在Mac上用匯編語言寫HelloWorld

    這篇文章主要介紹了詳解如何在Mac上用匯編語言寫HelloWorld,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • 匯編語言中的函數(shù)調(diào)用參數(shù)傳遞及全局與局部變量與“基址”

    匯編語言中的函數(shù)調(diào)用參數(shù)傳遞及全局與局部變量與“基址”

    這篇文章主要介紹了匯編眼中的函數(shù)調(diào)用參數(shù)傳遞以及全局與局部變量與“基址”,本文通過圖文并茂的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • 匯編語言顯示功能實現(xiàn)教程詳解

    匯編語言顯示功能實現(xiàn)教程詳解

    這篇文章主要為大家介紹了匯編語言顯示功能的實現(xiàn)過程,文中通過問題實例分析來為大家進行詳細的描述講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • 匯編:Debug的常用命令

    匯編:Debug的常用命令

    DEBUG是專門為匯編語言設計的一種調(diào)試工具,它通過步進,設置斷點等方式為匯編語言程序員提供了非常有效的調(diào)試手段
    2023-08-08
  • 匯編語言指令集之串處理指令講解

    匯編語言指令集之串處理指令講解

    這篇文章主要介紹了匯編語言指令集之串處理指令講解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-01-01
  • 匯編語言MUL指令無符號數(shù)乘法的使用

    匯編語言MUL指令無符號數(shù)乘法的使用

    這篇文章主要介紹了匯編語言MUL指令無符號數(shù)乘法的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02

最新評論

上林县| 六盘水市| 横峰县| 罗江县| 龙川县| 同德县| 达州市| 米泉市| 九龙城区| 师宗县| 江城| 大化| 河南省| 泽库县| 纳雍县| 视频| 德惠市| 越西县| 剑川县| 大荔县| 岐山县| 鹰潭市| 象山县| 青浦区| 阳原县| 中阳县| 颍上县| 栖霞市| 筠连县| 儋州市| 保德县| 黄浦区| 黔西| 察雅县| 仁寿县| 罗平县| 钦州市| 绥滨县| 伊吾县| 肥城市| 海林市|