📄 snoke.asm
字号:
.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 + -