欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

以下是具體實(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

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

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

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中實(shí)現(xiàn)具體的移動過程。

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

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

之后是檢測碰撞,我是用二重循環(huán)遍歷了MISSILE 和 ENEMY兩個數(shù)組。一開始我寫的是嚴(yán)格相等才算碰撞,后來玩的時候發(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)結(jié)束了。

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

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)用的是顯示分?jǐn)?shù)的例程(比較容易我沒放上來),然后先檢測是否碰撞。這里設(shè)置了一個DIFFICULTY變量,是適應(yīng)不同難度(DIFFICULTY)。TIMER是用來定時的。每次都+1,加到DIFFICLUTY的值才執(zhí)行敵人下降的例程。

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

附上一些效果圖。

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

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

相關(guān)文章

  • os_object_release Crash 排查記錄分析

    os_object_release Crash 排查記錄分析

    這篇文章主要為大家介紹了os_object_release Crash 排查記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 匯編語言指令集學(xué)習(xí)CMPXCHG比較并交換操作指令詳解

    匯編語言指令集學(xué)習(xí)CMPXCHG比較并交換操作指令詳解

    這篇文章主要為大家介紹了匯編語言指令集學(xué)習(xí)CMPXCHG比較并交換操作的指令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • UEFI開發(fā)基礎(chǔ)匯編代碼的使用

    UEFI開發(fā)基礎(chǔ)匯編代碼的使用

    這篇文章主要為大家介紹了UEFI開發(fā)基礎(chǔ)匯編代碼使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 匯編實(shí)現(xiàn)直接插入排序的方法示例

    匯編實(shí)現(xiàn)直接插入排序的方法示例

    這篇文章主要介紹了匯編實(shí)現(xiàn)直接插入排序的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • X86匯編調(diào)試環(huán)境搭建的過程

    X86匯編調(diào)試環(huán)境搭建的過程

    本次使用vscode搭建的,需要的插件有X86 and X86_64 Assembly(也可以使用masm插件),還有一個hexdump for VSCode。 安裝NASM,并添加到環(huán)境變量,下面看下X86匯編調(diào)試環(huán)境搭建的過程吧
    2021-11-11
  • 匯編語言XOR指令:對兩個操作數(shù)進(jìn)行邏輯(按位)異或操作(推薦)

    匯編語言XOR指令:對兩個操作數(shù)進(jìn)行邏輯(按位)異或操作(推薦)

    匯編語言(assembly language)是一種用于電子計算機(jī)、微處理器、微控制器或其他可編程器件的低級語言,亦稱為符號語言。這篇文章主要介紹了匯編語言XOR指令:對兩個操作數(shù)進(jìn)行邏輯(按位)異或操作,需要的朋友可以參考下
    2020-01-01
  • 用匯編語言實(shí)現(xiàn)從1加到100的方法(1+2+...+100)

    用匯編語言實(shí)現(xiàn)從1加到100的方法(1+2+...+100)

    這篇文章主要介紹了用匯編語言實(shí)現(xiàn)從1加到100的方法(1+2+...+100),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 匯編語言 and和or邏輯運(yùn)算指令的實(shí)現(xiàn)

    匯編語言 and和or邏輯運(yùn)算指令的實(shí)現(xiàn)

    這篇文章主要介紹了匯編語言 and,or邏輯運(yùn)算指令的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 匯編程序成績排序的實(shí)現(xiàn)

    匯編程序成績排序的實(shí)現(xiàn)

    這篇文章主要介紹了匯編程序成績排序的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 匯編語言中的segment

    匯編語言中的segment

    segment是段的意思,是段定義偽指令,一個正常的應(yīng)用程序被由若干個 segment組成,接下來通過本文給大家介紹匯編語言中的segment,需要的朋友可以參考下
    2020-01-01

最新評論