?? mybox.asm
字號:
; 此時的( NewX1, NewY1 )的位圖已被角色位圖覆蓋,所以不必繪制
;-----------------------------------------------------------------------
invoke _PaintOneBitmap, ManXPos, ManYPos, xBmMan, 0
popad
ret
_ManMove endp
;************************************************************************
;************************************************************************
; 引爆炸彈
;------------------------------------------------------------------------
_UseBomb proc
local @nPos
pushad
mov eax, BombFlag
.if eax == 1
mov esi, offset Map
invoke _SearchMapLinePos, BombXPos, BombYPos
mov @nPos, eax
mov al, [esi][eax]
.if al == MAP_WALL
mov ebx, @nPos
mov al, MAP_ROAD
mov [esi][ebx], al
invoke _PaintOneBitmap, BombXPos, BombYPos, xBmRoad, 0
invoke MessageBeep, -1
invoke SendMessage, hWinStatus, SB_SETTEXT, 1, addr szNoBomb
xor eax, eax
mov BombCount, eax
mov BombFlag, eax
.endif
.endif
popad
ret
_UseBomb endp
;************************************************************************
;************************************************************************
; 顯示或隱藏炸彈
;------------------------------------------------------------------------
_ShowBomb proc
pushad
mov eax, BombFlag
.if eax == 0 ; 炸彈不存在
mov eax, BombCount
.if ( eax == 1 && BombXPos == 0 ) ; 第一次顯示炸彈
@Reset:
mov esi, offset Map
xor ebx, ebx
mov ecx, 14d * 12d
@@:
mov al, [esi][ebx]
inc ebx
cmp al, MAP_WALL
loopnz @B
dec ebx
mov eax, ebx ; ebx的值為man在Map中的邏輯線性地址
mov edx, 0
mov ebx, 14d
div ebx
mov BombXPos, edx ; 余數,注意坐標從0開始計算
mov BombYPos, eax ; 商, 注意坐標從0開始計算
mov eax, 1
mov BombFlag, eax
jmp @Exit
.elseif eax == 1
invoke _SearchMapLinePos, ManXPos, ManYPos
mov ebx, eax
invoke _SearchMapLinePos, BombXPos, BombYPos
.if ( ebx == eax || edx == xBmBox1 || edx == xBmBox2 )
jmp @Reset
.endif
mov eax, 1
mov BombFlag, eax
.endif
.else ; 炸彈已顯示,則隱藏炸彈
invoke _SearchMapLinePos, BombXPos, BombYPos
invoke _PaintOneBitmap, BombXPos, BombYPos, edx, 0
xor eax, eax
mov BombFlag, eax
.endif
@Exit:
popad
ret
_ShowBomb endp
;************************************************************************
;************************************************************************
; 檢測玩家是否已將全部的箱子推到正確的位置上
;------------------------------------------------------------------------
_Check proc
.if ObjectLeft == 0
mov eax, TRUE
.else
mov eax, FALSE
.endif
ret
_Check endp
;************************************************************************
;************************************************************************
; 處理按鍵消息
;------------------------------------------------------------------------
_KeyDownProc proc @KeyDown
mov eax, @KeyDown
.if ( eax == VK_UP || eax == VK_DOWN || eax == VK_LEFT || eax == VK_RIGHT )
mov eax, BombFlag
.if eax == 1
invoke _BombMove, @KeyDown
jmp @F
.else
invoke _ManMove, @KeyDown
.endif
.elseif eax == VK_BACK
invoke _LoadStep
jmp @F
.elseif eax == VK_B
invoke _ShowBomb
jmp @F
.elseif eax == VK_RETURN
invoke _UseBomb
jmp @F
.else
jmp @F
.endif
invoke _Check ; 檢查man是否已把所有箱子都推到了正確的位置上
.if eax == TRUE
xor eax, eax
mov TimeFlag, eax ; 停止計時
invoke MessageBox, hWinMain, addr szSuccessMsg, addr szCaption, \
MB_ICONINFORMATION or MB_OKCANCEL
.if eax == IDOK
mov eax, CurrentGate
.if eax == MAX_GATES
invoke MessageBox, hWinMain, addr szGameOver, \
addr szCaption, MB_ICONINFORMATION
jmp @F
.endif
inc eax
invoke _SelectGate, eax
invoke _Repaint
.endif
.endif
@@:
ret
_KeyDownProc endp
;************************************************************************
;************************************************************************
; "關于"消息對話框窗口過程
;------------------------------------------------------------------------
_ProcDlgMain proc uses ebx edi esi hWnd, wMsg, wParam, lParam
mov eax, wMsg
.if eax == WM_CLOSE
invoke EndDialog, hWnd, NULL
.elseif eax == WM_INITDIALOG
invoke LoadIcon, hInstance, ICO_MSG
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
.elseif eax == WM_COMMAND
mov eax, wParam
.if ax == IDOK
invoke EndDialog, hWnd, NULL
.endif
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
_ProcDlgMain endp
;************************************************************************
;************************************************************************
; 主窗口過程
;------------------------------------------------------------------------
_ProcWinMain proc uses ebx edi esi, hWnd, uMsg, wParam, lParam
local @szTimerBuffer[20] : byte
local @PS : PAINTSTRUCT
mov eax, uMsg
;------------------------------------------------------------------------
.if eax == WM_TIMER
mov eax, wParam
.if eax == ID_SHOWBOMB
mov eax, BombFlag
.if eax == 1
invoke _SearchMapLinePos, BombXPos, BombYPos
.if edx == xBmWall
inc dwCount
mov eax, dwCount
and eax, 1
inc eax
.if eax == 1
invoke _PaintOneBitmap, BombXPos, BombYPos, xBmBomb, 0
.else
invoke _PaintOneBitmap, BombXPos, BombYPos, edx, 0
.endif
.else
invoke _PaintOneBitmap, BombXPos, BombYPos, xBmBomb, 0
.endif
.endif
.elseif eax == ID_GAMETIMER
invoke _SetGameTime
mov eax, GameHour
mov ebx, GameMinute
mov ecx, GameSecond
invoke wsprintf, addr @szTimerBuffer, addr szGameTime, \
eax, ebx, ecx
invoke SendMessage, hWinStatus, SB_SETTEXT, 0, addr @szTimerBuffer
.endif
;------------------------------------------------------------------------
.elseif eax == WM_KEYDOWN
invoke _KeyDownProc, wParam
;------------------------------------------------------------------------
.elseif eax == WM_COMMAND
mov eax, wParam
;..............................刷新當前關卡..............................
.if eax == IDM_REFLUSH
invoke _SelectGate, CurrentGate
invoke _Repaint ; 繪制窗口客戶區
;..............................加載上一關卡..............................
.elseif eax == IDM_PREV
mov eax, CurrentGate
dec eax
invoke _SelectGate, eax
invoke _Repaint ; 繪制窗口客戶區
;..............................加載下一關卡..............................
.elseif eax == IDM_NEXT
mov eax, CurrentGate
inc eax
invoke _SelectGate, eax
invoke _Repaint ; 繪制窗口客戶區
;.............................."關于"消息命令............................
.elseif eax == IDM_ABOUT
invoke DialogBoxParam, hInstance, DLG_MAIN, hWnd, \
offset _ProcDlgMain, NULL
;..............................退出命令..................................
.else
invoke _FreeRes
invoke _Quit
.endif
;------------------------------------------------------------------------
.elseif eax == WM_PAINT
invoke BeginPaint, hWnd, addr @PS
invoke _WMPaint, eax
invoke EndPaint, hWnd, addr @PS
;------------------------------------------------------------------------
.elseif eax == WM_NOTIFY
mov ebx, lParam
.if [ ebx + NMHDR.code ] == TTN_NEEDTEXT
assume ebx : ptr TOOLTIPTEXT
mov eax, [ebx].hdr.idFrom
mov [ebx].lpszText, eax
push hInstance
pop [ebx].hinst
assume ebx : nothing
.endif
;------------------------------------------------------------------------
.elseif eax == WM_CREATE
;..........................設置標題欄圖標................................
invoke LoadIcon, hInstance, ICO_MAIN
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
;..........................設置工具欄....................................
invoke CreateToolbarEx, hWnd, \
WS_VISIBLE or WS_CHILD or TBSTYLE_FLAT or TBSTYLE_TOOLTIPS, \
ID_TOOLBAR, NUM_BUTTONS, hInstance, IDM_TOOLBAR, offset stToolbar, \
NUM_BUTTONS, 16, 16, 16, 16, sizeof TBBUTTON
mov hWinToolbar, eax
;..........................設置狀態欄....................................
invoke CreateStatusWindow, WS_CHILD OR WS_VISIBLE,
NULL, hWnd, ID_STATUSBAR
mov hWinStatus, eax
invoke SendMessage, hWinStatus, SB_SETPARTS, 4, offset dwStatusWidth
;..........................設置定時器....................................
invoke SetTimer, hWnd, ID_GAMETIMER, 1000, NULL
invoke SetTimer, hWnd, ID_SHOWBOMB, 500, NULL
xor eax, eax
mov TimeFlag, eax ;禁止計時
;..........................讀入地圖數據資源..............................
invoke _LoadRes
;------------------------------------------------------------------------
.elseif eax == WM_CLOSE
invoke _FreeRes
invoke _Quit
;------------------------------------------------------------------------
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
;------------------------------------------------------------------------
.endif
xor eax, eax
ret
_ProcWinMain endp
;************************************************************************
;************************************************************************
_WinMain proc
local @stWndClass : WNDCLASSEX
local @stMsg : MSG
local cxScreen, cyScreen
invoke InitCommonControls
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke LoadMenu, hInstance, IDM_MAIN
mov hMenu, eax
;------------------------------------------------------------------------
; 注冊窗口類
;------------------------------------------------------------------------
invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass
mov @stWndClass.cbSize, sizeof WNDCLASSEX
mov @stWndClass.style, CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc, offset _ProcWinMain
push hInstance
pop @stWndClass.hInstance
invoke LoadCursor, hInstance, IDM_CUR
mov @stWndClass.hCursor, eax
mov @stWndClass.hbrBackground, COLOR_BTNFACE + 1
mov @stWndClass.lpszClassName, offset szClassName
invoke RegisterClassEx,addr @stWndClass
;------------------------------------------------------------------------
; 創建窗口
;------------------------------------------------------------------------
invoke GetSystemMetrics, SM_CXSCREEN
mov cxScreen, eax
invoke GetSystemMetrics, SM_CYSCREEN
mov cyScreen, eax
mov eax, cxScreen
shr eax, 1
mov cxScreen, eax
mov eax, cyScreen
shr eax, 1
mov cyScreen, eax
mov eax, cxScreen
sub eax, 213d
mov cxScreen, eax
mov eax, cyScreen
sub eax, 240
mov cyScreen, eax
invoke CreateWindowEx, NULL, offset szClassName, \
offset szCaption, WS_CAPTION or WS_SYSMENU or WS_BORDER, \
cxScreen, cyScreen, 425, 460,\
NULL, hMenu, hInstance, NULL
mov hWinMain, eax
;------------------------------------------------------------------------
; 顯示窗口
;------------------------------------------------------------------------
invoke _SelectGate, 1
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:
call _WinMain
invoke ExitProcess, NULL
;========================================================================
end start
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -