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

📄 snoke.asm

📁 贪食蛇汇编源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

	.elseif uMsg == WM_INITDIALOG
		.if lParam == IS_SPEED
			invoke SetDlgItemInt, hWnd, IDC_INPUT_EDT1, dwTimeStop, FALSE
			invoke SetDlgItemText, hWnd, IDC_INPUT_STC1, addr szSpeed
		.elseif lParam == IS_FOOD
			invoke SetDlgItemInt, hWnd, IDC_INPUT_EDT1, dwFoodCount, FALSE
			invoke SetDlgItemText, hWnd, IDC_INPUT_STC1, addr szFood
		.endif
		invoke GetDlgItem, hWnd, IDC_INPUT_EDT1
		invoke SetFocus, eax
	.endif
	xor eax, eax
	ret
_InputDlgProc endp

;********************************************************************************
;初始化游戏, 开始新游戏
;********************************************************************************
_InitGame proc uses ecx
	.if pHead
		invoke MessageBox, hWndMain, addr szPlaying, addr szWindowsName, MB_OK
		ret
	.endif
	;初始化节点
	mov ecx, INITCOUNT
@@:
	push ecx
	shl ecx, 3
	invoke _AddHead, ecx, SNKSIZE
	pop ecx
	loop @B
	;初始化食物, 定时器, 暂停标识
	invoke _NewFoods, dwFoodCount
	invoke InvalidateRect, hWndMain, NULL, TRUE
	invoke SetTimer, hWndMain, ID_TIMER1, dwTimeStop, offset _TimerProc
	mov bPause, 2
	ret
_InitGame endp

;********************************************************************************
;主窗口消息处理函数
;********************************************************************************
_WndMainProc proc uses ebx ecx esi hWnd, uMsg, wParam, lParam
	local @hdc
	local @stps:PAINTSTRUCT

	;*********************************************
	;命令消息
	;*********************************************
	.if uMsg == WM_COMMAND
		mov eax, wParam
		;开始新游戏
		.if ax == IDM_FILE_NEW
			invoke _InitGame
		;结束游戏
		.elseif ax == IDM_FILE_CLOSE
			invoke _GameOver
		;暂停
		.elseif ax == IDM_FILE_STOP
			.if bPause
				invoke GetMenuState, hMenu, eax, MF_BYCOMMAND
				.if eax == MF_CHECKED
					invoke SetTimer, hWnd, ID_TIMER1, dwTimeStop, offset _TimerProc
					invoke SetWindowText, hWnd, addr szWindowsName
					mov bPause, 2
					mov eax, MF_UNCHECKED
				.elseif eax == MF_UNCHECKED
					invoke KillTimer, hWnd, ID_TIMER1
					invoke SetWindowText, hWnd, addr szPause
					mov bPause, 1
					mov eax, MF_CHECKED
				.endif
				invoke CheckMenuItem, hMenu, IDM_FILE_STOP, eax
			.endif
		;退出
		.elseif ax == IDM_FILE_EXIT
			invoke PostQuitMessage, NULL
		;速度
		.elseif ax >= IDM_SPEED_SLOWEST && ax <= IDM_SPEED_FASTEST
			.if ax == IDM_SPEED_SLOWEST
				mov dwTimeStop, 1000
			.elseif ax == IDM_SPEED_SLOW
				mov dwTimeStop, 500
			.elseif ax == IDM_SPEED_NORMAL
				mov dwTimeStop, 100
			.elseif ax == IDM_SPEED_FAST
				mov dwTimeStop, 50
			.elseif ax == IDM_SPEED_FASTEST
				mov dwTimeStop, 25
			.endif
			invoke CheckMenuRadioItem, hMenu,IDM_SPEED_SLOWEST, IDM_SPEED_USER, eax, MF_BYCOMMAND
			invoke SendMessage, hWnd, WM_ACTIVATE, NULL, NULL
		;自定义数度
		.elseif ax == IDM_SPEED_USER
			not bPause
			invoke DialogBoxParam, hInstance, IDD_INPUT, hWnd, offset _InputDlgProc, IS_SPEED
			.if eax >= 1 && eax <= 1000
				mov dwTimeStop, eax
				invoke CheckMenuRadioItem, hMenu,IDM_SPEED_SLOWEST, IDM_SPEED_USER, IDM_SPEED_USER, MF_BYCOMMAND
			.endif
			not bPause
			invoke SendMessage, hWnd, WM_ACTIVATE, NULL, NULL
		;食物
		.elseif ax >= IDM_FOOD_ONE && ax <= IDM_FOOD_32
			.if ax == IDM_FOOD_ONE
				mov dwFoodCount, 1
			.elseif ax == IDM_FOOD_TWO
				mov dwFoodCount, 2
			.elseif ax == IDM_FOOD_FOUR
				mov dwFoodCount, 4
			.elseif ax == IDM_FOOD_16
				mov dwFoodCount, 16
			.elseif ax == IDM_FOOD_32
				mov dwFoodCount, 32
			.endif
			invoke CheckMenuRadioItem, hMenu, IDM_FOOD_ONE, IDM_FOOD_USER, eax, MF_BYCOMMAND
			invoke _NewFoods, dwFoodCount
			invoke InvalidateRect, hWnd, NULL, TRUE
		;自定义食物
		.elseif ax == IDM_FOOD_USER
			not bPause
			invoke DialogBoxParam, hInstance, IDD_INPUT, hWnd, offset _InputDlgProc, IS_FOOD
			.if eax >= 1 && eax <= 256
				mov dwFoodCount, eax
				invoke CheckMenuRadioItem, hMenu, IDM_FOOD_ONE, IDM_FOOD_USER, IDM_FOOD_USER, MF_BYCOMMAND
				invoke _NewFoods, dwFoodCount
				invoke InvalidateRect, hWnd, NULL, TRUE
			.endif
			not bPause
			invoke SendMessage, hWnd, WM_ACTIVATE, NULL, NULL
		.elseif ax == IDM_OPTION_ENVIRONMENT
			
		.elseif ax == IDM_HELP_ABOUT
			
		.endif
	;*********************************************
	;绘制窗口
	;*********************************************
	.elseif uMsg == WM_PAINT
		invoke BeginPaint, hWnd, addr @stps
		mov @hdc, eax
		;绘制矩形区域
		invoke MoveToEx, @hdc, SNKSIZE-1, SNKSIZE-1, NULL
		invoke LineTo, @hdc, SNKSIZE-1, WNDCY+SNKSIZE
		invoke LineTo, @hdc, WNDCX+SNKSIZE, WNDCY+SNKSIZE
		invoke LineTo, @hdc, WNDCX+SNKSIZE, SNKSIZE-1
		invoke LineTo, @hdc, SNKSIZE-1, SNKSIZE-1
		.if pHead
			;绘制蛇
			invoke SelectObject, @hdc, hBrushSnoke
			mov esi, pHead
			assume esi:ptr SNOKENODE
			.while esi
				mov eax, [esi].x
				add eax, SNKSIZE-1
				mov ebx, [esi].y
				add ebx, SNKSIZE-1
				invoke Rectangle, @hdc, [esi].x, [esi].y, eax, ebx
				mov esi, [esi].pNext
			.endw
			;绘制食物
			invoke SelectObject, @hdc, hBrushFood
			lea esi, stFood
			assume esi:ptr POINT
			sub esi, 8
			mov ecx, dwFoodCount
LOP:
			add esi, 8
			mov eax, [esi].x
			cmp eax, 0
			je @F
			add eax, SNKSIZE-1
			mov ebx, [esi].y
			add ebx, SNKSIZE-1
			push ecx
			invoke Rectangle, @hdc, [esi].x, [esi].y, eax, ebx
			pop ecx
@@:
			loop LOP
		.endif
		invoke EndPaint, hWnd, addr @stps
	;*********************************************
	;键盘按下
	;*********************************************
	.elseif uMsg == WM_KEYDOWN
		.if wParam == VK_LEFT
			.if dwKeyPrev != VK_RIGHT
				mov dwKeyFlag, VK_LEFT
			.endif
		.elseif wParam == VK_RIGHT
			.if dwKeyPrev != VK_LEFT
				mov dwKeyFlag, VK_RIGHT
			.endif
		.elseif wParam == VK_UP
			.if dwKeyPrev != VK_DOWN
				mov dwKeyFlag, VK_UP
			.endif
		.elseif wParam == VK_DOWN
			.if dwKeyPrev != VK_UP
				mov dwKeyFlag, VK_DOWN
			.endif
		.elseif wParam == VK_RETURN
			invoke SendMessage, hWnd, WM_COMMAND, IDM_FILE_STOP, NULL
		.endif
	;*********************************************
	;失去焦点
	;*********************************************
	.elseif uMsg == WM_KILLFOCUS || uMsg == WM_ENTERMENULOOP
		invoke KillTimer, hWnd, ID_TIMER1
	;*********************************************
	;取得焦点
	;*********************************************
	.elseif uMsg == WM_ACTIVATE || uMsg == WM_EXITMENULOOP
		.if bPause == 2
			invoke SetTimer, hWnd, ID_TIMER1, dwTimeStop, offset _TimerProc
		.endif
	;*********************************************
	;摧毁窗口消息
	;*********************************************
	.elseif uMsg == WM_DESTROY
		invoke PostQuitMessage, NULL
	;*********************************************
	;其他
	;*********************************************
	.else
		invoke DefWindowProc, hWnd, uMsg, wParam, lParam
		ret
	.endif
	xor eax, eax
	ret
_WndMainProc endp

;********************************************************************************
;主窗口函数
;********************************************************************************
_WndMain proc hInst, hPrevInst, CmdLine, CmdShow
	local @stWndClass:WNDCLASSEX
	local @stMsg:MSG

	;*********************************************
	;初始化并填充 @stWndClass 窗口类
	;*********************************************
	invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass
	mov @stWndClass.cbSize, sizeof WNDCLASSEX
	mov @stWndClass.style, CS_HREDRAW or CS_VREDRAW
	mov @stWndClass.lpfnWndProc, offset _WndMainProc
	push hInst
	pop @stWndClass.hInstance
	;背景色
	invoke CreateSolidBrush, 0eeffeeh
	mov @stWndClass.hbrBackground, eax
	mov @stWndClass.lpszClassName, offset szClassName
	;取图标
	invoke LoadIcon, hInst, IDI_ICON1
	mov @stWndClass.hIcon, eax
	mov @stWndClass.hIconSm, eax
	;取光标
	invoke LoadCursor, NULL, IDC_ARROW
	mov @stWndClass.hCursor, eax

	;*********************************************
	;注册 @stWndClass 窗口类
	;*********************************************
	invoke RegisterClassEx, addr @stWndClass
	;屏幕宽
	invoke GetSystemMetrics, SM_CXSCREEN
	shr eax, 1
	sub eax, (WNDCX+25)/2
	mov ebx, eax
	;屏幕高
	invoke GetSystemMetrics, SM_CYSCREEN
	shr eax, 1
	sub eax, (WNDCY+70)/2

	;*********************************************
	;创建并显示窗口
	;*********************************************
	invoke CreateWindowEx, WS_EX_CLIENTEDGE, addr szClassName, addr szWindowsName, \
		WS_CAPTION or WS_SYSMENU, ebx, eax, WNDCX+25, WNDCY+70, NULL, NULL, hInstance, NULL
	mov hWndMain, eax
	;初始化菜单
	invoke LoadMenu, hInst, IDM_MAINMENU
	mov hMenu, eax
	invoke SetMenu, hWndMain, eax
	invoke CheckMenuRadioItem, hMenu, IDM_SPEED_SLOWEST, IDM_SPEED_FASTEST, IDM_SPEED_NORMAL, MF_BYCOMMAND
	invoke CheckMenuRadioItem, hMenu, IDM_FOOD_ONE, IDM_FOOD_32, IDM_FOOD_FOUR, MF_BYCOMMAND
	;创建刷子
	invoke CreateSolidBrush, 000ff00h
	mov hBrushSnoke, eax
	invoke CreateSolidBrush, 00000ffh
	mov hBrushFood, eax
	;随即数种子
	invoke GetTickCount
	invoke nseed, eax
	;显示窗口
	invoke ShowWindow, hWndMain, CmdShow
	;更新窗口
	invoke UpdateWindow, hWndMain

	;*********************************************
	;消息循环
	;*********************************************
	.while TRUE
		;取得消息
		invoke GetMessage,addr @stMsg,NULL,0,0
		.break .if !eax
		;解释翻译消息
		invoke TranslateMessage,addr @stMsg
		;分派消息
		invoke DispatchMessage,addr @stMsg
	.endw
	ret
_WndMain endp

;********************************************************************************
;代码入口点
;********************************************************************************
start:
	invoke GetModuleHandle, NULL
	mov hInstance, eax
	invoke InitCommonControls
	invoke GetCommandLine
	invoke _WndMain, hInstance, NULL, eax, SW_SHOWNORMAL
	invoke ExitProcess, eax

end start

⌨️ 快捷键说明

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