win32 asm 贪食蛇

最近<<windows环境下32位汇编语言程序设计>> 这本书看了一些章节了.

自从讲完GDI那章,往下就是通用对话框了.

通用对话框那章看起来很没意思,就跳着看了看.下一章是讲控件的,也没啥兴趣.

但是控件那章的窗口子类化,和窗口超类化倒是非常重要,给了我不少启发,

才知道原来各种各样的的漂亮的控件,窗口,无非也就是子类化,超类化,再加上资源作出来的.

 

再后面,讲的是内存和文件,再再后面,是DLL和HOOK.

各个章节都扫了一些,总感觉应该做点什么自己的东西,有点自己Debug的经验,心里才踏实.

于是,为了巩固以下,就做个贪食蛇吧.

 

以前用J2ME作过贪食蛇,也用C语言 WIN32  SDK 作过贪食蛇.

算法和思想都很简单.WIN32 API上也没有什么难点.

本来想做一个界面复杂的,但是发现手头没有好看的位图资源,也就懒得弄了.

本来还想用上一些控件,但是自己就是这样虎头蛇尾,做到后来就懒得往上加控件了.

 

由于对WIN32  SDK比以前用C语言作这个东西的时候理解深刻了一些,

程序模块化比以前好一点了.

解决了以前那个贪食蛇按键的一个BUG.

 

刚做的时候,其实是想先做个链表的,然后想把这个链表封装到 DLL里.

可是一想到这个链表的节点也没有啥通用性,又不会弄成CPP里面那种范型,也是弄一半旧懒得弄了.

就在.asm文件里巴,dll懒得弄了...

 

本以为学习了以前的东西,做一个贪食蛇已经没有任何技术难点了.

但是一想到如何动态分配内存空间,我就发现自己还有个重大的问题不会解决.

C语言里可以malloc,free.C++里可以new delete,Java也可以new ,汇编用什么呢?

 

最后发现,汇编没有这种直接的东西可以分配内存,只能用API .

这里用的是VirtualAlloc和VirtualFree。这样,总算可以给链表动态加节点了。

 

过程中还发现不知道在汇编中如何操作结构体,而这个程序当然要频繁地操作结构体的节点。

后来看了一眼术上前面介绍的,assume esi:ptr XXXX,配合 assume esi:nothing

就可以[esi].XXXX这样操作结构体了。通过这个程序,算是把这块熟悉了一遍。

 

在学习16位汇编的时候,就发现jmp的标签不好起名字,尤其做王爽<<汇编语言>>课程设计2的时候,

一个标签的名字真的让自己较劲脑汁想啊想。

还记得在大一的时候,程序设计的思想还不成熟,总觉得有些地方循环不好实现,就非要用个goto.

这次好了,WIN32 汇编里面  @@和 @B  @F  很好地解决了问题。

时隔N年,倒不是觉得不goto就没办法,只是觉得 jmp这东西简化了我不少代码。用起来很爽的感觉。

 

对了,还有一点很重要

在单位的win7上调试程序,遇到用了不该用的内存,P反映都没有

在XP上就会蹦出来个震撼的对话框。

怎么也不明白到底哪里弄错了,无奈之下,用自己的XP笔记本的VC6.0,搭配了个DEBUG环境,

才找到了问题所在------堆栈不平衡,导致 ret语句 跳转的地方不正确。

这种问题在高级语言里是不可能出现的。

 

DEBUG 还是没有用OllyDbg,这个东西以后再学习吧!WIN7 这东西,把错误提示都给屏蔽掉了,

给用户了一个“更好”的体验,却给我调试程序增加了麻烦。。。

VC6.0 调试汇编还是很好用的,IDE也熟悉,快捷键也熟悉,KUAKUA两下,就找到问题所在了。

还是那句话,WIN32  ASM 没有个 好的IDE,真坑人!

 

以前用C语言,WIN32  SDK,VC6.0 作出来的贪食蛇,exe文件大小200K

这次用WIN32汇编语言,WIN32  SDK作出来的贪食蛇,exe文件大小只有17K,嘿嘿

 

废话了一大堆,上个代码,贴个图吧。

没啥技术含量,就是纪念自己第一次用win32 汇编写了个几百行的小东西

 

		.386
		.model	flat,stdcall
		option	casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include		windows.inc
include		kernel32.inc
includelib	kernel32.lib
include		user32.inc
includelib	user32.lib
include		gdi32.inc
includelib	gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;IDB_TOOLBAR		equ		100

ID_TIMER		equ		1

SIZE_WND_WIDTH		equ		800
SIZE_WND_HEIGHT		equ		600

POS_CANVAS_X		equ		100
POS_CANVAS_Y		equ		100
SIZE_CANVAS_WIDTH	equ		400
SIZE_CANVAS_HEIGHT	equ		300

SIZE_UNIT_WIDTH		equ		20
SIZE_UNIT_HEIGHT	equ		20

DIR_MOVE_UP		equ		3
DIR_MOVE_DOWN		equ		1
DIR_MOVE_LEFT		equ		2
DIR_MOVE_RIGHT		equ		0			;	default direction


WM_GAME_START		equ		WM_USER+1		;	OWNER DEFINE
WM_GAME_OVER		equ		WM_USER+2


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.data
		
;**********************************************************************************
		.data?
MIAOSTRUCT	struct			;	struct def
	xPos		dd		?
	yPos		dd		?		
	pNext		dd		?
MIAOSTRUCT	ends	


pHead		dd			?
stHead		MIAOSTRUCT		<>
pCur		dd			?
szTemp		db			256 dup(?)

dwDirection		dd			?
wHasFood		dw			?
wTickHasChangeDir	dw			?
dwFoodPosX		dd			?
dwFoodPosY		dd			?

hInstance	dd			?
hWinMain	dd			?

hDcBuffer	dd			?
hBmpBuffer	dd			?
;hBmpTest	dd			?

wGameScore	dw			?

;**********************************************************************************	
		.const
szDebug1	db		'szDebug1',0
szDebug2	db		'szDebug2',0	
szLinkNull	db		'Null linklist',0
szShowNode	db		'sn (%d,%d)',0
szFreeNode	db		'delete node (%d,%d)',0
szFreeFinish	db		'Finish free,total %d node(s)',0
szKeyDir	db		'Current key dir is %d',0


szMainClassName	db		'miaoclass',0
szMainCaption	db		'gj1111myl',0

szGameOver	db		'GameOver',0
szGameStart	db		'GameStart',0
szGameScore	db		'score: %d',0
	
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Insert value to link list.Link list will create a node and add it.
_InsertMiao	proc	uses ebx esi,xPos,yPos

		LOCAL	@pStNode
		
		mov	eax,pHead
		.if	eax==NULL							;	insert head
			;invoke	MessageBox,NULL,addr szDebug1,addr szDebug1,MB_OK
			
			invoke	RtlZeroMemory,addr stHead,sizeof stHead
			mov	eax,xPos
			mov	stHead.xPos,eax
			mov	eax,yPos
			mov	stHead.yPos,eax
			mov	eax,0
			mov	stHead.pNext,eax
			
			mov	eax,offset stHead
			mov	pHead,eax	
		.else									; 	insert normal
			;nvoke	MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK
			
			;	Creat a new node
			invoke	VirtualAlloc,NULL,sizeof MIAOSTRUCT,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE
			.if	eax
				mov	@pStNode,eax
			.endif
			invoke	RtlZeroMemory,@pStNode,sizeof MIAOSTRUCT
			mov	esi,@pStNode
			assume	esi:ptr MIAOSTRUCT
			mov	eax,xPos
			mov	[esi].xPos,eax
			mov	eax,yPos
			mov	[esi].yPos,eax
			mov	eax,0
			mov	[esi].pNext,eax
			assume	esi:nothing
			
			
			;	find tail of linklist
			mov	eax,pHead
			mov	pCur,eax
			.while	TRUE
				mov	esi,pCur
				assume	esi:ptr MIAOSTRUCT				
				.break .if	[esi].pNext==NULL
				mov	eax,[esi].pNext
				mov	pCur,eax
				assume	esi:nothing
			.endw
			assume	esi:nothing
			
			;	attach new node to tail
			mov	esi,pCur
			assume	esi:ptr MIAOSTRUCT
			mov	eax,@pStNode
			mov	[esi].pNext,eax
			assume	esi:nothing
		.endif
		
		ret
_InsertMiao 	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Show each node of link list.Test if link list is correct.
_ShowMiao	proc	uses esi
		
		mov	eax,pHead
		mov	pCur,eax
		
		.if	eax==NULL					;	head is NULL			
			invoke	MessageBox,NULL,addr szLinkNull,addr szLinkNull,MB_OK
			ret
		.endif
		
		;	Show each node
		.while	TRUE
			
			.break .if 	pCur==NULL
			
			mov	esi,pCur
			assume esi:ptr MIAOSTRUCT
			
			;	szTemp can't local,it will not stead stack!
			invoke	wsprintf,addr szTemp,addr szShowNode,[esi].xPos,[esi].yPos
			invoke	MessageBox,NULL,addr szTemp,addr szTemp,MB_OK			
			
			mov	eax,[esi].pNext
			mov	pCur,eax
			assume esi:nothing
		.endw
		ret
_ShowMiao	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Get tail node of Linklist
_GetTailNodeMiao	proc	uses ebx esi edi
			.if	pHead==NULL				;	if pHead==NULL,means linklist is NULL 	
				xor	eax,eax
				ret
			.endif
			
			mov	eax,pHead
			mov	pCur,eax
			
			.while	TRUE
				mov	esi,pCur
				assume esi:ptr MIAOSTRUCT
				.break	.if	[esi].pNext==NULL
				mov	eax,[esi].pNext
				mov	pCur,eax
				assume esi:nothing				
			.endw
			assume esi:nothing			
			mov	eax,pCur
			ret
_GetTailNodeMiao 	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Destroy linklist
_DestroyMiao	proc	uses ebx ecx edx esi edi

		LOCAL	@pCur2
		mov	edx,0
		
		.while	TRUE
			invoke	_GetTailNodeMiao
			mov	pCur,eax
			.break	.if	pCur==NULL
			
			;	free head
			mov	eax,pHead
			.if	pCur==eax
				invoke	VirtualFree,pCur,sizeof MIAOSTRUCT,MEM_DECOMMIT
				mov	pHead,NULL
				ret
			.endif
			
			;	Get the node before tail node
			push	pHead
			pop	@pCur2
			.while	TRUE
				mov	esi,@pCur2
				assume	esi:ptr MIAOSTRUCT
				mov	eax,pCur
				.break	.if	[esi].pNext==eax
				push	[esi].pNext
				pop	@pCur2
				assume	esi:nothing
			.endw
			
			
			;	Free normal node
			invoke	VirtualFree,pCur,sizeof MIAOSTRUCT,MEM_DECOMMIT
			
			;	Set the node before tail's pNext = NULL
			mov	esi,@pCur2
			assume	esi:ptr MIAOSTRUCT
			mov	[esi].pNext,NULL
			assume	esi:nothing
		.endw
		
		ret
_DestroyMiao	endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Check if (xPos,yPos) is member of linklist
_CheckPosOnLink	proc	uses ebx ecx,xPos,yPos
		push	pHead
		pop	pCur
		.while	TRUE
			.break .if pCur==NULL
			
			mov	esi,pCur
			assume	esi:ptr MIAOSTRUCT
			mov	ebx,[esi].xPos
			mov	ecx,[esi].yPos
			.if	ebx==xPos
				.if	ecx==yPos
					mov	eax,1
					ret
				.endif
			.endif
			mov	eax,[esi].pNext
			mov	pCur,eax
			assume	esi:nothing
		.endw	
		
		xor	eax,eax				;	not found
		ret
_CheckPosOnLink endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		add new node to pHead
_GrowUpOnLinkHead	proc	xPos,yPos
			
			.if	pHead==NULL
				ret
			.endif
			
			invoke	VirtualAlloc,NULL,sizeof MIAOSTRUCT,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE
			.if	eax
				mov	pCur,eax
				Invoke	RtlZeroMemory,pCur,sizeof MIAOSTRUCT
				
				
				mov	esi,pCur
				assume	esi:ptr MIAOSTRUCT
				push	xPos
				pop	[esi].xPos
				push	yPos
				pop	[esi].yPos
				push	pHead
				pop	[esi].pNext
				push	pCur
				pop	pHead
				assume	esi:nothing
			.endif
			ret
_GrowUpOnLinkHead	endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;	calc mod
_Mod	proc	uses	ecx edx _dwNumber1,_dwNumber2
		
		xor	edx,edx
		mov	eax,_dwNumber1
		mov	ecx,_dwNumber2
		.if	ecx
			div	ecx
			mov	eax,edx
		.endif
		ret
_Mod	endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		WinMain	message proc
_ProcWinMain	proc	uses ebx ecx esi edi,hWnd,uMsg,wParam,lParam
		LOCAL	@hDc
		LOCAL	@stPs:PAINTSTRUCT
		LOCAL	@stRect:RECT
		
		LOCAL	@BufX,@BufY,@DestX,@DestY
		
		LOCAL	@dwFoodX,@dwFoodY
		LOCAL	@stTime:SYSTEMTIME
		LOCAL	@wTimeBit:WORD
		
		mov	eax,uMsg
		.if	eax==WM_TIMER
			
			;*********************************************************
			;	If no food,generate one
			;************************************************************
			.if	wHasFood==0			;	has no food on screen,generate one
			
			@@:
				;	random a num
				mov	eax,0
				invoke	GetLocalTime,addr @stTime
				mov	ax,@stTime.wSecond
				mov	@wTimeBit,ax
				mov	@BufX,eax
				
				mov	eax,0
				invoke	GetLocalTime,addr @stTime
				mov	ax,@stTime.wSecond
				mov	@wTimeBit,ax
				mov	@BufY,eax
				
				;	set real pos
				invoke	_Mod,@BufX,20
				mov	@BufX,eax
				invoke	_Mod,@BufY,15
				mov	@BufY,eax
				
				invoke	_CheckPosOnLink,@BufX,@BufY		;	make sure food not on snake
				.if	eax!=0
					jmp	@B
				.endif

				push	@BufX
				pop	dwFoodPosX
				push	@BufY
				pop	dwFoodPosY
				
				;	fill food rect
				mov	eax,SIZE_UNIT_WIDTH
				mul	@BufX
				mov	@stRect.left,eax
				mov	@stRect.right,eax
				add	@stRect.right,SIZE_UNIT_WIDTH
				
				mov	eax,SIZE_UNIT_HEIGHT
				mul	@BufY
				mov	@stRect.top,eax
				mov	@stRect.bottom,eax
				add	@stRect.bottom,SIZE_UNIT_HEIGHT
				invoke	GetStockObject,LTGRAY_BRUSH
				invoke	FillRect,hDcBuffer,addr @stRect,eax
				
				mov	ax,1
				mov	wHasFood,ax
			.endif
		
			;*********************************************************
			;	Update node's value by DIR_MOVE
			;************************************************************
			mov	wTickHasChangeDir,0			;	set flag of control per frame
			
			.if	pHead!=NULL
				mov	esi,pHead
				assume	esi:ptr MIAOSTRUCT
				mov	ebx,[esi].xPos
				mov	@DestX,ebx
				mov	ebx,[esi].yPos
				mov	@DestY,ebx
				assume	esi:nothing
				
				.if	dwDirection==DIR_MOVE_UP
					mov	eax,@DestY
					dec	eax
					mov	@DestY,eax
				.elseif	dwDirection==DIR_MOVE_DOWN
					mov	eax,@DestY
					inc	eax
					mov	@DestY,eax
				.elseif	dwDirection==DIR_MOVE_LEFT
					mov	eax,@DestX
					dec	eax
					mov	@DestX,eax
				.elseif dwDirection==DIR_MOVE_RIGHT
					mov	eax,@DestX
					inc	eax
					mov	@DestX,eax
				.endif
				
			.else
				invoke	MessageBox,NULL,addr szLinkNull,addr szLinkNull,MB_OK
				invoke	SendMessage,hWnd,WM_CLOSE,0,0
				ret
			.endif	
			
			;*********************************************************
			;	Check collision
			;************************************************************
			;	check border
			.if	@DestX>=20					
				invoke	SendMessage,hWnd,WM_GAME_OVER,0,0
				ret
			.elseif	@DestX<0
				invoke	SendMessage,hWnd,WM_GAME_OVER,0,0
				ret
			.elseif	@DestY>=15	
				invoke	SendMessage,hWnd,WM_GAME_OVER,0,0
				ret			
			.elseif	@DestY<0
				invoke	SendMessage,hWnd,WM_GAME_OVER,0,0
				ret
			.endif
			
			;	check self
			invoke	_CheckPosOnLink,@DestX,@DestY
			.if	eax!=0
				invoke	SendMessage,hWnd,WM_GAME_OVER,0,0
			.endif
			
			;	check food
			mov	eax,dwFoodPosX
			.if	@DestX==eax
					mov	eax,dwFoodPosY
				.if	@DestY==eax
					;invoke	MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK
					
					;	set generate food flag
					mov	wHasFood,0
					
					;	inc	wGameScore
					inc	wGameScore
					
					;	snake grows up
					invoke	_GrowUpOnLinkHead,dwFoodPosX,dwFoodPosY
					jmp	@F
				.endif
			.endif
			
			
			;*********************************************************
			;	Snake move
			;************************************************************
			
			push	pHead
			pop	pCur
			.while	TRUE
				.break .if pCur==NULL
				mov	esi,pCur
				assume	esi:ptr MIAOSTRUCT
				push	[esi].xPos
				pop	@BufX
				push	[esi].yPos
				pop	@BufY
				
				mov	eax,SIZE_UNIT_WIDTH		;	erase history
				mul	@BufX
				mov	@stRect.left,eax
				mov	@stRect.right,eax
				add	@stRect.right,SIZE_UNIT_WIDTH
				
				mov	eax,SIZE_UNIT_HEIGHT
				mul	@BufY
				mov	@stRect.top,eax
				mov	@stRect.bottom,eax
				add	@stRect.bottom,SIZE_UNIT_HEIGHT
				
				invoke	GetStockObject,BLACK_BRUSH
				invoke	FillRect,hDcBuffer,addr @stRect,eax
				
				
				push	@DestX				;	real move
				pop	[esi].xPos
				push	@DestY
				pop	[esi].yPos
				
				push	@BufX				;	record pos for next node move
				pop	@DestX
				push	@BufY
				pop	@DestY
				
				push	[esi].pNext
				pop	pCur
				assume	esi:nothing
			.endw
			
			@@:
			;*********************************************************
			;	Draw each node of linklist
			;************************************************************
			mov	eax,pHead
			mov	pCur,eax
			.while	TRUE
				.break	.if	pCur==NULL
				mov	esi,pCur
				assume	esi:ptr MIAOSTRUCT
				;	ebx=real xPos of current node
				mov	eax,SIZE_UNIT_WIDTH
				mul	[esi].xPos
				mov	ebx,eax
				
				;	ecx=real yPos of current node
				mov	eax,SIZE_UNIT_HEIGHT
				mul	[esi].yPos
				mov	ecx,eax
				assume	esi:nothing
				
				;	current rect
				mov	@stRect.left,ebx
				mov	@stRect.right,SIZE_UNIT_WIDTH
				add	@stRect.right,ebx
				mov	@stRect.top,ecx
				mov	@stRect.bottom,SIZE_UNIT_HEIGHT
				add	@stRect.bottom,ecx
				
				invoke	GetStockObject,WHITE_BRUSH
				invoke	FillRect,hDcBuffer,addr @stRect,eax
				
				assume esi:ptr MIAOSTRUCT
				mov	eax,[esi].pNext
				mov	pCur,eax
				assume esi:nothing
			.endw
						
			invoke	InvalidateRect,hWnd,NULL,FALSE
			
		.elseif	eax==WM_PAINT
			
			mov	@stRect.left,0
			mov	@stRect.right,100
			mov	@stRect.top,0
			mov	@stRect.bottom,100
			
			invoke	BeginPaint,hWnd,addr @stPs
			mov	@hDc,eax
			
			;	Draw game canvas
			invoke	BitBlt,@hDc,POS_CANVAS_X,POS_CANVAS_Y,SIZE_WND_WIDTH,SIZE_WND_HEIGHT,hDcBuffer,0,0,SRCCOPY
			
			;	Draw score
			mov	eax,0
			mov	ax,wGameScore
			invoke	wsprintf,addr szTemp,addr szGameScore,eax
			invoke	DrawText,@hDc,addr szTemp,-1,addr @stRect,DT_LEFT	
			
			invoke	EndPaint,hWnd,addr @stPs
		.elseif	eax==WM_KEYDOWN
			mov	eax,wParam
			.if	eax==VK_UP && wTickHasChangeDir==0
				.if	dwDirection!=DIR_MOVE_DOWN && dwDirection!=DIR_MOVE_UP
					mov	eax,DIR_MOVE_UP
					mov	dwDirection,eax
					mov	wTickHasChangeDir,1		;	set flag ,could only change dir once per frame
				.endif
				
			.elseif	eax==VK_DOWN && wTickHasChangeDir==0
				.if	dwDirection!=DIR_MOVE_DOWN && dwDirection!=DIR_MOVE_UP
					mov	eax,DIR_MOVE_DOWN
					mov	dwDirection,eax
					mov	wTickHasChangeDir,1
				.endif				
				
			.elseif	eax==VK_LEFT && wTickHasChangeDir==0
				.if	dwDirection!=DIR_MOVE_LEFT && dwDirection!=DIR_MOVE_RIGHT
					mov	eax,DIR_MOVE_LEFT
					mov	dwDirection,eax
					mov	wTickHasChangeDir,1
				.endif
				
			.elseif	eax==VK_RIGHT && wTickHasChangeDir==0
				.if	dwDirection!=DIR_MOVE_LEFT && dwDirection!=DIR_MOVE_RIGHT
					mov	eax,DIR_MOVE_RIGHT
					mov	dwDirection,eax
					mov	wTickHasChangeDir,1
				.endif
				
			.endif
			
		.elseif	eax==WM_GAME_START
			invoke	MessageBox,NULL,addr szGameStart,addr szGameStart,MB_OK
			
			.if	pHead!=NULL
				invoke	_DestroyMiao
			.endif
			
			;************************************************************
			;	Init linklist
			;************************************************************
			invoke	_InsertMiao,10,6
			invoke	_InsertMiao,9,6
			invoke	_InsertMiao,8,6
			invoke	_InsertMiao,7,6
			invoke	_InsertMiao,6,6
			invoke	_InsertMiao,5,6
			
			;	Set proc timer
			invoke	SetTimer,hWnd,ID_TIMER,200,NULL
			
		.elseif	eax==WM_GAME_OVER
			
			
			;************************************************************
			;	Destroy linklist
			;************************************************************
			invoke	_DestroyMiao
			
			invoke	KillTimer,hWnd,ID_TIMER
			;invoke	InvalidateRect,hWnd,NULL,TRUE
			
			;	set 0 to wGameScore
			mov	wGameScore,0
			
			invoke	MessageBox,NULL,addr szGameOver,addr szGameOver,MB_OK
			

		.elseif	eax==WM_CLOSE
			;************************************************************
			;	delete buffer dc & bitmap
			;************************************************************		
			invoke	DeleteObject,hBmpBuffer
			invoke	DeleteDC,hDcBuffer

			invoke	SendMessage,NULL,WM_GAME_OVER,0,0
			
			invoke	DestroyWindow,hWnd
			invoke	PostQuitMessage,NULL
		.elseif	eax==WM_CREATE
			;************************************************************
			;	Create buffer dc & bitmap
			;************************************************************
			invoke	GetDC,hWnd
			mov	@hDc,eax

			invoke	CreateCompatibleDC,@hDc
			mov	hDcBuffer,eax
			invoke	CreateCompatibleBitmap,hDcBuffer,SIZE_CANVAS_WIDTH,SIZE_CANVAS_HEIGHT
			mov	hBmpBuffer,eax
			invoke	SelectObject,hDcBuffer,hBmpBuffer
			
			invoke	ReleaseDC,hWnd,@hDc
			
			;	for game start
			invoke	SendMessage,hWnd,WM_GAME_START,0,0
		.else
			invoke	DefWindowProc,hWnd,uMsg,wParam,lParam
			ret
		.endif
		
		xor	eax,eax
		ret
_ProcWinMain	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;		Create	window
_WinMain	proc
		
		LOCAL	@stWndClass:WNDCLASSEX
		LOCAL	@stMsg:MSG
		
		invoke	GetModuleHandle,NULL
		mov	hInstance,eax
		invoke	RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

		invoke	LoadCursor,NULL,IDC_ARROW
		mov	@stWndClass.hCursor,eax
		push	hInstance
		pop	@stWndClass.hInstance
		mov	@stWndClass.cbSize,sizeof WNDCLASSEX
		mov	@stWndClass.style,CS_HREDRAW or CS_VREDRAW
		mov	@stWndClass.lpfnWndProc,offset _ProcWinMain
		mov	@stWndClass.hbrBackground,COLOR_WINDOW+1
		mov	@stWndClass.lpszClassName,offset szMainClassName
		invoke	RegisterClassEx,addr @stWndClass
		
		invoke	CreateWindowEx,WS_EX_CLIENTEDGE,\
					offset szMainClassName,offset szMainCaption,\
					WS_OVERLAPPEDWINDOW,\
					100,100,SIZE_WND_WIDTH,SIZE_WND_HEIGHT,\
					NULL,NULL,hInstance,NULL
		mov	hWinMain,eax
		invoke	ShowWindow,hWinMain,SW_SHOWNORMAL
		invoke	UpdateWindow,hWinMain
		
		.while	TRUE
			invoke	GetMessage,addr @stMsg,NULL,0,0
			.break	.if	eax==0	
			invoke	TranslateMessage,addr @stMsg
			invoke	DispatchMessage,addr @stMsg
		.endw
					
		ret
_WinMain	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
	;invoke	_InsertMiao,0,0
	;invoke	_InsertMiao,1,1
	;invoke	_CheckPosOnLink,1,2
	;.if	eax==0
	;	invoke	MessageBox,NULL,addr szDebug1,addr szDebug1,MB_OK
	;.else	
	;	invoke	MessageBox,NULL,addr szDebug2,addr szDebug2,MB_OK		
	;.endif
	;invoke	_InsertMiao,2,2
	;invoke	_ShowMiao
	;invoke	_DestroyMiao
	
	invoke	_WinMain
	invoke	ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>	
end	start

 

图:

 

PS :

最近小静静一直在加班,通常要到12点多,这个周末也一天都没有休息。

镇是辛苦 小静静了!

我呢,作为陪加班的,就踏踏实实调试了几天程序。

小静静现在胃也不舒服,脖子也不舒服,后背也难受,整了一身的职业病。

我应该尽我的义务,监督小静静注意身体,不能乱吃,不能休息不好了。

小静静呢,也应该配合我,听话,千万别累坏了~

 

等小静静的游戏GOLD了,我一定拷贝一个,只玩小静静设计的任务,一天玩10遍,嘿嘿~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值