📄 1.asm
字号:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\include\gdi32.inc
include \masm32\include\shell32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
DrawMap proto
NewGame proto
LoadRes proto
Flip proto
FreeGame proto
MsgBox proto
FreeRes proto
Random proto Range:DWORD
TimeProc proto hWnd:HWND,uMsg:UINT,idEvent :UINT,dwTime:DWORD
TimeProc2 proto hWnd:HWND,uMsg:UINT,idEvent:UINT,dwTime:DWORD
GameOver proto
KeyDownProc proto dwKey :DWORD
.data
food dd 500
ClassName db 'DLGCLASS',0
MenuName db 'MyMenu',0
DlgName db 'MyDialog',0
AppName db 'Snake',0
success db 'You are successful!!!',0
g_Map db 50*50 dup(0)
g_sMsgGameOver db 'Game Over!!!',0
sbParts dd 3
sbWidths dd 100,200,405,0
TIMER1_INTERVAL dd 120
FmtStrNodeCount db 'Node Count = %d.',0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
g_hWnd dd ?
g_hDc dd ?
g_hBackDc dd ?
g_hBackBmp dd ?
g_hImgDc dd ?
g_hImgBmp dd ?
g_hImgwallDc dd ?
g_hImgwallBmp dd ?
g_hPen dd ?
g_hBrush dd ?
g_pHead dd ? ; Point to snake head
g_pHead1 dd ?
g_pTail dd ? ; Point to snake tail
g_pTail1 dd ?
g_Direct dd ? ; Left Right up down
g_Direct1 dd ? ; Left Right up down
g_NodeCount dd ?
g_NodeCount1 dd ?
g_GameState dd ? ; GS_PLAY
g_RandomSeed dd ?
g_szBuffer db 256 dup(?) ; String Buffer
.const
IDM_FILE_EXIT equ 10001
IDM_NEWGAME equ 10002
IDC_SBR1 equ 1001
BM_BMP equ 1000
BM_WALL equ 1002
ID_GAMESPEED_FAST equ 333
ID_GAMESPEED_MIDDLE equ 444
ID_GAMESPEED_SLOW equ 555
ID_NUM1 equ 11
ID_NUM2 equ 12
ID_NUM3 equ 13
ID_NUM4 equ 14
SNode struct
pPrev dd ? ; Base
x dd ? ; Base + 4
y dd ? ; Base + 8
pNext dd ? ; Base + 12
SNode ends
DR_LEFT equ 0
DR_RIGHT equ 1
DR_UP equ 2
DR_DOWN equ 3
GS_PLAY equ 1
GS_PAUSE equ 2
GS_STOP equ 3
TIMER1_ID equ 1000
TIMER2_ID equ 1001
TIMER2_INTERVAL equ 3000
MAP_NONE equ 0
MAP_WOOD equ 2
MAP_NODE equ 3
MAP_WALL equ 4
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke InitCommonControls
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,OFFSET MenuName
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,addr DlgName,NULL,addr WndProc,NULL
invoke ShowWindow,g_hWnd,SW_SHOWNORMAL
invoke UpdateWindow,g_hWnd
.while TRUE ;消息循环
invoke GetMessage,addr msg,NULL,0,0
.BREAK .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==WM_INITDIALOG
push hWin
pop g_hWnd ;存窗口句柄
invoke SendDlgItemMessage,hWin,IDC_SBR1,SB_SETPARTS,sbParts,addr sbWidths
invoke LoadRes ;装载资源
.elseif eax==WM_PAINT ;窗口刷新,注意(由于程序没有使窗口失效的函数,所以不是用的这种方法制造动画)
invoke DefWindowProc,hWin,uMsg,wParam,lParam
invoke Flip
ret
.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0FFFFh
.if eax==IDM_FILE_EXIT ;退出
invoke SendMessage,hWin,WM_CLOSE,0,0
.elseif eax==IDM_NEWGAME ;开始新游戏
invoke NewGame
.elseif eax==ID_GAMESPEED_FAST
mov TIMER1_INTERVAL ,50
.elseif eax==ID_GAMESPEED_MIDDLE
mov TIMER1_INTERVAL , 120
.elseif eax==ID_GAMESPEED_SLOW
mov TIMER1_INTERVAL , 300
.elseif eax==ID_NUM1
mov food,10
.elseif eax==ID_NUM2
mov food,20
.elseif eax==ID_NUM3
mov food,50
.elseif eax==ID_NUM4
mov food,100
.endif
.elseif eax == WM_KEYDOWN ;按下键盘
invoke KeyDownProc,wParam
.elseif eax==WM_CLOSE ;退出
invoke FreeGame ;释放
invoke FreeRes ;释放资源
invoke DestroyWindow,hWin ;销毁窗口
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
;*****************************************************
LoadRes proc ;装载资源
invoke GetDC,g_hWnd
mov g_hDc , eax
invoke CreateCompatibleDC,g_hDc
mov g_hImgDc,eax
invoke LoadBitmap,hInstance ,BM_BMP
mov g_hImgBmp,eax
invoke SelectObject,g_hImgDc,g_hImgBmp
invoke CreateCompatibleDC,g_hDc
mov g_hImgwallDc,eax
invoke LoadBitmap,hInstance ,BM_WALL
mov g_hImgwallBmp,eax
invoke SelectObject,g_hImgwallDc,g_hImgwallBmp
invoke CreateCompatibleDC,g_hDc
mov g_hBackDc,eax
invoke CreateCompatibleBitmap,g_hDc,400,400
mov g_hBackBmp,eax
invoke SelectObject,g_hBackDc,eax
invoke CreatePen,PS_SOLID,1,00808000h
mov g_hPen ,eax
invoke CreateSolidBrush,00808000h
mov g_hBrush ,eax
invoke SelectObject,g_hBackDc,g_hPen
invoke SelectObject,g_hBackDc,g_hBrush
invoke Rectangle,g_hBackDc,0,0,400,400
invoke RtlZeroMemory,addr g_Map,50*50
push NULL
pop g_pHead
push NULL
pop g_pTail
push 0
pop g_NodeCount
push GS_STOP
pop g_GameState
invoke GetTickCount
mov g_RandomSeed,eax
ret
LoadRes endp
Flip proc ;以绿色图填充背景,400=8*50,正好是背景的大小
invoke BitBlt,g_hDc,0,0,400,400,g_hBackDc,0,0,SRCCOPY
; invoke BitBlt,g_hBackDc,20,20,8,8,g_hImgDc,0,0,SRCCOPY
; invoke MsgBox
ret
Flip endp
GameOver proc
push GS_STOP
pop g_GameState
invoke KillTimer,g_hWnd,TIMER2_ID ;关定时器2
invoke KillTimer,g_hWnd,TIMER1_ID ;关定时器1
invoke MessageBox,g_hWnd,addr g_sMsgGameOver,addr AppName,MB_ICONINFORMATION
ret
GameOver endp
FreeRes proc ;释放资源
invoke ReleaseDC,g_hWnd,g_hDc
invoke DeleteObject,g_hImgBmp
invoke DeleteObject,g_hBackBmp
invoke DeleteObject,g_hPen
invoke DeleteObject,g_hBrush
invoke DeleteDC,g_hBackDc
invoke DeleteObject,g_hImgDc
ret
FreeRes endp
NewGame proc
LOCAL pNode:DWORD ; the last node
Local x2:DWORD
Local y2:DWORD
; -- Init 5 node
invoke FreeGame
;***************************************************************
; init head
invoke LocalAlloc,LPTR,sizeof(SNode) ;这个API是不是建立一个数据结构,用来存放蛇头的位置
.if eax == NULL
invoke MsgBox
.endif
mov g_pHead , eax
mov pNode ,eax
mov ebx ,eax
mov eax , NULL
mov [ebx],eax ; g_pHead.pPrev = null
mov eax, 5
mov [ebx+4],eax ; g_pHead.x = 5
mov eax,0
mov [ebx+8],eax ; g_pHead.y = 0
mov edi,OFFSET g_Map
add edi,5
mov BYTE PTR[edi],MAP_NODE
; init 2 node
invoke LocalAlloc,LPTR,sizeof(SNode)
mov [ebx+12],eax
mov ebx , eax
mov eax , pNode
mov [ebx],eax ; NextNode.pPrev = pNode
mov eax , 4
mov [ebx+4],eax ; x = 4
mov eax , 0
mov [ebx+8],eax ; y = 0
mov pNode , ebx
mov edi,OFFSET g_Map
add edi,4
mov BYTE PTR[edi],MAP_NODE
; init 3 node
invoke LocalAlloc ,LPTR,sizeof(SNode)
mov [ebx+12],eax
mov ebx,eax
mov eax,pNode
mov [ebx],eax
mov eax,3
mov [ebx+4],eax
mov eax,0
mov [ebx+8],eax
mov pNode,ebx
mov edi,OFFSET g_Map
add edi,3
mov BYTE PTR[edi],MAP_NODE
; init 4 node
invoke LocalAlloc ,LPTR,sizeof(SNode)
mov [ebx+12],eax
mov ebx,eax
mov eax,pNode
mov [ebx],eax
mov eax,2
mov [ebx+4],eax
mov eax,0
mov [ebx+8],eax
mov pNode,ebx
mov edi,OFFSET g_Map
add edi,2
mov BYTE PTR[edi],MAP_NODE
; Init 5 node
invoke LocalAlloc ,LPTR,sizeof(SNode)
mov [ebx+12],eax
mov ebx,eax
mov eax,pNode
mov [ebx],eax
mov eax,1
mov [ebx+4],eax
mov eax,0
mov [ebx+8],eax
mov eax,NULL
mov [ebx+12],eax
mov edi,OFFSET g_Map
add edi,1
mov BYTE PTR[edi],MAP_NODE
push ebx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -