⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.asm

📁 编了个简单的游戏
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; Copyleft (c) 2007,God reserved all rights.
; 
; 文件名称:game.asm
; 
; 当前版本:0.13
; 作    者:邹伟
; 摘	要:各主要子程序都在此间
; 说	明:程序中用于输出字符的位置未加说明则默认为相对于游戏区域左上角即(GM_LEFT,GM_TOP)

public setDSAndES , GA_gameInit , GA_gameCircle , stackPoint
extern main_quit:far,restart_the_game:far
include game.h
;设置块坐标的宏
assignPos macro x,y
	mov (Brick ptr [si]).b_sPos.pos_bX,x
	mov (Brick ptr [si]).b_sPos.pos_bY,y
	add si,size Brick 
endm
assignBase macro x,y
	mov (ManyBrick ptr [di]).mb_sPos.pos_bX,x
	mov (ManyBrick ptr [di]).mb_sPos.pos_bY,y
endm

assume cs:GameCode,ds:MainData,ss:StackSpase
GameCode segment	
	;游戏循环---不断获取输入,根据与定义规则合理的转化为输出
	GA_gameCircle proc far
	    GA_gameCircle_again:
	    	mov dir,KEY_WRONG_DIR
	    	lea bx,levelFPS
	    	mov di,level
	    	add di,challenge
	    	cmp di,LEVEL_LIMITT
	    	jbe level_ok
	    	mov di,LEVEL_LIMITT
	    level_ok:
	      	shl di,1
	      	mov cx,[bx+di]
	    	   wast_time:
			call delay
			cmp dir,KEY_WRONG_DIR
			je may_be_life_is_long
			call Brick_goNext
			mov dir,KEY_WRONG_DIR
			call ManyBrick_drawSelf
		   may_be_life_is_long:
		   loop wast_time			   		   
		   	cmp dir,KEY_WRONG_DIR		   		   
		   	jz user_press_no_dir_key
			call Brick_goNext
		    user_press_no_dir_key:
			mov dir,DIR_DOWN
			call Brick_goNext
		cmp game.ga_state,GS_OVER
		jz GA_over		
		call ManyBrick_drawSelf		
	   jmp GA_gameCircle_again
	   GA_over:
	   	call doGameOver
		ret
	GA_gameCircle endp	
	;每次游戏开始时的初始化调用
	GA_gameInit proc far
		call clrScreen
		;hide the cursor
		mov ch,020h
		mov cl,020h
		mov ah,01h
		int 10h
		;初始化随机序列的第一个数,读取BIOS提供的当前秒
		xor al,al
		out 70h,al
		in ax,71h		
		mov seed,ax
		;初始化,如:得分,游戏状态,游戏地图
		mov challenge,0
		mov game.ga_score,0
		mov game.ga_state,GS_RUNNING
		lea di,game.ga_map
		mov cx,GM_HEIGHT		
		cld
		xor ax,ax
		rep stosw
		mov nextNO,0
		call MB_gernicNext
		call MB_gernicNext
		call drawNextBrick
		call moreBeautiful
		;show some strings
		mov si,offset scoreStr
		mov dl,X_SCORE_STR
		mov dh,Y_SCORE_STR
		mov cx,6
		call showStr

		mov si,offset levelStr
		mov dl,X_LEVEL_STR
		mov dh,Y_LEVEL_STR
		mov cx,6
		call showStr

		mov si,offset levelDeltStr
		mov dl,X_adjustLevelDelt_STR
		mov dh,Y_adjustLevelDelt_STR
		mov cx,10
		call showStr

		mov si,offset modeStr
		mov dl,X_MODE_STR
		mov dh,Y_MODE_STR
		mov cx,10
		call showStr
	
		mov si,offset usageStr
		mov dl,-GM_LEFT
		mov dh,-4
		mov cx,usageStrCNT
		call showStr
		mov si,offset usageStrEx
		mov dl,-GM_LEFT
		mov dh,-3
		mov cx,usageStrExCNT
		call showStr
		mov si,offset linkToCoderStr
		mov dl,-GM_LEFT
		mov dh,-2
		mov cx,linkToCoderCNT
		call showStr		

		;show some digitials
		call showScore
		call calcLevel
		call showadjustLevelDelt
		call showMode
		ret
	GA_gameInit endp
	;全局初始化,调用一次,设置DS,ES指向同一个数据段,程序运行过程中不再改变
	setDSAndES proc far
		mov ax,MainData
		mov ds,ax
		mov es,ax
		ret
	setDSAndES endp
	;判断游戏区域(dl,dh)位置是否为空
	;in  : dl-->x, dh-->y
	;out : flag register 
	isPosNotEmpty proc
		push dx
		push bx
		push ax
		push cx
		push di
		push si
		mov si,curMB
		mov si,(ManyBrick ptr [si]).mb_bCnt
		;ax--mask,第dl位置1
		mov ax,1
		mov cl,dl
		shl ax,cl		
		lea di,game.ga_map
		;map+2*dh 
		xor bh,bh
		mov bl,dh
		shl bl,1		
	   only_one_brick:
		and ax,[bx+di]
		je is_pos_empty_out
		cmp si,1
		jne is_pos_empty_out
		cmp bx,(2*GM_HEIGHT-2)
		je is_pos_empty_out_pre
		add bx,2
	   jmp only_one_brick
	   	;ensure the result is correct
	   is_pos_empty_out_pre:
	   	cmp bx,0
	   is_pos_empty_out:
	   	pop si
		pop di
		pop cx
		pop ax
		pop bx
		pop dx
		ret
	isPosNotEmpty endp
	;判断游戏是否结束
	isGameOver proc
		push bx
		mov bx,curMB
		cmp (ManyBrick ptr [bx]).mb_sPos.pos_bY,Y_START		
	    jne still_alive
		;游戏的确结束了
		mov game.ga_state,GS_OVER
		call doGameOver
	    still_alive:
		pop bx
		ret
	isGameOver endp
	;游戏结束后,调用此过程,显示一些提示信息,待等用户下一步指示,重玩或退出
	doGameOver proc	   
		call clrScreen	
		call moreBeautiful
		mov si,offset gameOverStr
		mov cx,45
		mov dl,X_GAME_OVER ;x
		mov dh,Y_GAME_OVER ;y
		call showStr		
		mov ax,game.ga_score		
		mov cx,43
		call AXModCX
		and ax,3
		mov di,ax
		shl di,1
		mov cx,judgeCnt[di]		
		mov si,judgeTable[di]
		mov dl,X_JUDGE_STR
		mov dh,Y_JUDGE_STR
		call showStr
		mov al,CHAR_BRICK
	    wait_for_restart:
	    	call randomDraw
	    	call delay
	    jmp wait_for_restart
		ret
	doGameOver endp
	;in : ax--ax0, cx--cx0
	;out: ax=ax0/cx0, cx=ax0%cx0
	AXModCX	proc
		push dx
		xor dx,dx
		div cx
		mov cx,dx
		pop dx
		ret
	AXModCX endp
	;信手涂鸦
	randomDraw proc
		push dx
		push bx
			push ax
			call getRand
			mov cx,GM_WIDTH
			call AXModCX
			mov dl,cl
			call getRand
			mov cx,GM_HEIGHT
			call AXModCX
			mov dh,cl
			call getRand
			and al,7
			or al,8
			mov bl,al
			pop ax
			call drawBrick
		pop bx
		pop dx
		ret
	randomDraw endp
	;游戏暂停时调用此过程,显示提示信息,按任意键继续
	doGamePaused proc	
		push si
		push cx
		push dx
		push ax		
		mov si,offset gamePausedStr
		mov cx,46 ;46 chars
		mov dl,0 ;x
		mov dh,GM_HEIGHT/2;y
		call showStr				
		call waitForKeyPress
	    	mov game.ga_state,GS_RUNNING 	
	    	mov dl,0
	    	mov dh,GM_HEIGHT/2
		mov al,CHAR_CLEAR
		mov cx,46 ;46 chars
	    erase_paused_words:
		mov bl,COLOR_CLEAR
	    	call drawBrick
	    	inc dl
	    loop erase_paused_words
	    	call moreBeautiful
	    	call drawMap
	    	call ManyBrick_drawSelf
	    	pop ax
	    	pop dx
	    	pop cx
	    	pop si
		ret
	doGamePaused endp
	;clear the screen
	clrScreen proc
		push ax		
		mov ah,00h
		mov al,03h
		int 10h
		pop ax
		ret
	clrScreen endp
	;游戏完成时跳转到此,表示对极富耐心者的景仰^_^,并退出游戏
	doGameFinished:
		call clrScreen
		call moreBeautiful
		mov si,offset gameFinishedStr
		mov cx,58 ;58 chars
		mov dl,-GM_LEFT+5
		mov dh,-2
		call showStr
	   dGF_keybuf_empty:
	   	call getRand
	   	call randomDraw
	   	mov ah,1
	   	int 16h	   	
	   jz dGF_keybuf_empty
		jmp main_quit
	;等待直到有键被按下
	waitForKeyPress proc
		push ax
	    key_buf_empty:
		mov ah,1
		int 16h		
	    jz key_buf_empty
	    	;ignore the key just press
	    	mov ah,0
		int 16h
	    	pop ax
		ret
	waitForKeyPress endp
	;方块下落停止时,设置当前下落方块所占用的地图位置,并消除满行
	lastBattle proc
		call ManyBrick_setMap
		call checkFull
		ret
	lastBattle endp
	;若map数组相应为置位 则在相应位置显示一个方块
	drawMap proc
		push ax
		push dx
		push bx
		push cx
		push si
		push di
		lea si,game.ga_map
		mov cx,GM_HEIGHT
		xor dh,dh		
	   drawMap_outer:
	   		push cx
	   		mov cx,GM_WIDTH
	   		xor dl,dl
	   		mov di,1
	   		push si
	   		mov si,[si]
	   		mov ah,3
	   	   drawMap_inner:
			mov bl,3
			sub bl,ah
			mov ah,bl
	   	   	test si,di
	   	   	jz clear_it
	   	   	;draw a brick
			mov al,CHAR_BRICK
			mov bl,COLOR_DIED_BRICK	   	   	
	   	   	jmp draw_map_over	   	   	
	   	   clear_it:
	   	   	cmp mode,2
	   	   jne ignor_background
	   	   	mov al,'|'
	   	   	mov bl,ah
	   	   	jmp draw_map_over
	   	   ignor_background:
			mov al,CHAR_CLEAR
			mov bl,COLOR_CLEAR
	   	   draw_map_over:
	   	   	call drawBrick
	   	   	inc dl
	   	   	shl di,1
	   	   loop drawMap_inner
	   	   	pop si	   	   
	   	   	pop cx
	   	add si,2
	   	inc dh
	   loop drawMap_outer
	   	pop di
	   	pop si
	   	pop cx
		pop bx
		pop dx
		pop ax
		ret
	drawMap endp
	;检查是否有满行的情况,满则消除,并增加得分...
	checkFull proc
		push ax
		push bx
		push cx
		push dx
		xor dx,dx ;此次能消除的行数
		lea bx,game.ga_map
		add bx,2*(GM_HEIGHT-1)		
		mov cx,GM_HEIGHT
	   check_full_again:
	   	mov ax,[bx]
	   	cmp ax,GM_MASK
	   	jne brick_not_full
	   	inc dx
	   	call mapScrollDown
	   loop check_full_again
	   brick_not_full:
	   	sub bx,2
	   loop check_full_again
	   	test dx,dx
	   	jz get_zero_score
	   		;此次得分:2*行数-1
	   		shl dx,1
	   		dec dx
	   		add game.ga_score,dx
			call calcLevel	   	
	   		call showScore
	   get_zero_score:
	   	pop dx
	   	pop cx
	   	pop bx
	   	pop ax
		ret
	checkFull endp
	;根据得分计算当前关数
	calcLevel proc
		push ax
		push bx
		push cx
		mov bx,offset levelScoreLast		
		xor ah,ah
		mov cx,LEVEL_LIMITT
	   add_level_again:
	   	mov al,[bx]
	   	cmp game.ga_score,ax
	   	jae  calc_level_out
	   	dec bx
	   loop add_level_again
	   calc_level_out:	   				
		mov level,cx
		cmp level,LEVEL_LIMITT
		jb game_unfinished
		add sp,6
		jmp doGameFinished
	   game_unfinished:
	    	call showLevel
		pop cx
		pop bx
		pop ax
		ret
	calcLevel endp
	;显示当前关
	showLevel proc
		push dx
		push bx
		push ax
		mov bl,COLOR_NUMBER
		mov dl,X_LEVEL_POS
		mov dh,Y_LEVEL_POS
		mov ax,level
		call showInt
		pop ax
		pop bx
		pop dx
		ret
	showLevel endp
	;显示当前得分
	showScore proc
		push dx
		push bx
		push ax
		mov bl,COLOR_NUMBER
		mov dl,X_SCORE_POS
		mov dh,Y_SCORE_POS
		mov ax,game.ga_score
		call showInt
		pop ax
		pop bx
		pop dx
		ret
	showScore endp	
	;显示当前自动提升的关数
	showAdjustLevelDelt proc
		push dx
		push bx
		push ax
		mov bl,COLOR_NUMBER
		mov dl,X_adjustLevelDelt_POS
		mov dh,Y_adjustLevelDelt_POS
		mov ax,challenge
		call showInt
		pop ax
		pop bx
		pop dx
		ret
	showAdjustLevelDelt endp	
	showMode proc
		push dx
		push bx
		push ax
		mov bl,COLOR_NUMBER
		mov dl,X_MODE_POS
		mov dh,Y_MODE_POS
		mov ax,mode
		call showInt
		call drawMap
		pop ax
		pop bx
		pop dx
		ret		
		ret
	showMode endp
	;在(dl,dh)为起始的位置显示ax中的一个整数
	;in :	ax--the integer to be show
	;	dl--x , dh--y;
	showInt	proc
		push cx
		push si
		push di
		xor di,di
		mov cx,10
	    show_int_again:
	    	inc di
	    	push dx
	    	xor dx,dx
	    	;dx:ax /cx, ax  ,dx
	    	div cx
	    	mov si,ax
	    	mov al,dl
	    	pop dx
	    	add al,30h
		call drawBrick
		dec dl
		mov ax,si
		cmp ax,0		
	    jnz show_int_again
	    	cmp di,1
	    jne no_need_to_clear
		mov al,CHAR_CLEAR
		push bx
		mov bl,COLOR_CLEAR
	    	call drawBrick
	    	pop bx
	    no_need_to_clear:
	    	pop di
	    	pop si
	    	pop cx
		ret
	showInt endp
	;在(X_NEXT_BRICK,Y_NEXT_BRICK)处显示下一个将要下落的方块s
	drawNextBrick proc
		push bx
		push dx
		;first clear the last draw
		mov bx,curMB
		mov dx,WORD ptr (ManyBrick ptr [bx]).mb_sPos.pos_bX 
		mov (ManyBrick ptr [bx]).mb_sPos.pos_bX ,X_NEXT_BRICK
		mov (ManyBrick ptr [bx]).mb_sPos.pos_bY ,Y_NEXT_BRICK
		call ManyBrick_clearCur
		mov WORD ptr (ManyBrick ptr [bx]).mb_sPos.pos_bX,dx
		;second draw the next-brick
		mov bx,nextMB
		mov dx,WORD ptr (ManyBrick ptr [bx]).mb_sPos.pos_bX 
		mov (ManyBrick ptr [bx]).mb_sPos.pos_bX ,X_NEXT_BRICK
		mov (ManyBrick ptr [bx]).mb_sPos.pos_bY ,Y_NEXT_BRICK
		xchg bx,curMB
		call ManyBrick_drawSelf
		xchg curMB,bx
		mov WORD ptr (ManyBrick ptr [bx]).mb_sPos.pos_bX,dx
		pop dx
		pop bx
		ret
	drawNextBrick endp
	;游戏区域对应map数组在bx行处下卷,即清除bx所在行
	;in:	bx --the line to be clear
	mapScrollDown proc
		push bx
		push ax
		push cx
		dec cx
		je scroll_over
		push si
		push di
		mov di,bx
		lea si,[di-2]		
		std
	   	rep movsw
		pop di
		pop si
	   scroll_over:
	   	mov game.ga_map,0
	   	call drawMap
		pop cx
		pop ax
		pop bx
		ret
	mapScrollDown endp
	;根据当前下落的方块所在位置设置游戏区域所代表的map数组
	ManyBrick_setMap proc
		push ax
		push bx
		push cx
		push dx
		push si
		push di
		push bp
		lea di,game.ga_map		
		mov bx,curMB
		mov cx,(ManyBrick ptr [bx] ).mb_bCnt
		lea si,(ManyBrick ptr [bx] ).mb_sBrick
		lea bp,(ManyBrick ptr [bx]).mb_sPos
	   setMap_again:		
			mov dh,(Brick ptr [si]).b_sPos.pos_bY
			add dh,ds:(Pos ptr[bp]).pos_bY
			mov dl,(Brick ptr [si]).b_sPos.pos_bX
			add dl,ds:(Pos ptr[bp]).pos_bX
			call isPosLeagel
			js setMap_ignore
			cmp dh,0
			js setMap_ignore			
			;map[dh]
			mov bl,dh
			shl bl,1
			xor bh,bh			
			;bx--&map[dh]
			lea bx,[bx+di]
			mov ax,1
			push cx
			mov cl,dl
			shl ax,cl
			pop cx
			or [bx],ax
	   	   setMap_ignore:
	   	add si,size Brick
	   	loop setMap_again
	   	cmp mode,0
	   jz color_stay
	   	call drawMap
	   color_stay:	   	
	   	pop bp
	   	pop di	   	
	   	pop si
	   	pop dx
		pop cx
		pop bx
		pop ax	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -