?? mybox.asm
字號:
;************************************************************************
.386
.model flat, stdcall
option casemap : none
;************************************************************************
include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
include Comctl32.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
includelib Comctl32.lib
include StoreHouse.inc ; 導(dǎo)入關(guān)卡地圖數(shù)據(jù)
;************************************************************************
; 宏定義數(shù)據(jù)
;------------------------------------------------------------------------
ICO_MAIN equ 1000h ; 窗口圖標(biāo)ID
ICO_MSG equ 1001h
IDM_CUR equ 1000h ; 窗口光標(biāo)ID
IDM_MAIN equ 1000h ; 菜單ID
IDM_REFLUSH equ 1001h
IDM_PREV equ 1002h
IDM_NEXT equ 1003h
IDM_ABOUT equ 1004h
IDM_EXIT equ 1005h
ID_TOOLBAR equ 1 ; 工具欄ID
IDM_TOOLBAR equ 2000h ; 工具欄圖標(biāo)位圖ID
ID_STATUSBAR equ 2 ; 狀態(tài)欄ID
DLG_MAIN equ 3 ; 消息對話框ID
BM_MAIN equ 3000h ; 背景位圖資源ID
ID_GAMETIMER equ 100 ; 關(guān)卡計(jì)時(shí)器
ID_SHOWBOMB equ 101 ; 刷新炸彈計(jì)時(shí)器
xBmBack equ 0d
xBmWall equ 30d
xBmRoad equ 60d
xBmBox1 equ 90d
xBmBox2 equ 120d
xBmObject equ 150d
xBmMan equ 180d
xBmBomb equ 210d
VK_B equ 42h ; 字母"B"的掃描碼
BackStep equ 20d ; 后退的次數(shù)
;************************************************************************
; 數(shù)據(jù)段
;------------------------------------------------------------------------
.const
szClassName db 'Game', 0
szCaption db '推箱子', 0
dwStatusWidth dd 80, 160, 255, -1
NUM_BUTTONS equ 6 ;工具欄圖標(biāo)位圖中包含的小圖標(biāo)個(gè)數(shù)
stToolbar equ this byte
TBBUTTON <0, IDM_REFLUSH, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1>
TBBUTTON <1, IDM_PREV, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1>
TBBUTTON <2, IDM_NEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1>
TBBUTTON <3, IDM_ABOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1>
TBBUTTON <0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, -1>
TBBUTTON <4, IDM_EXIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, -1>
;------------------------------------------------------------------------
.data
szOutOfRange db '已超出游戲關(guān)卡范圍!', 0
szSuccessMsg db '您成功通過了關(guān)卡!是否繼續(xù)?', 0
szGameOver db '已到達(dá)最后一關(guān)', 0
FmtGate db '—第%d關(guān)', 0
szBomb db '炸彈數(shù)量 : 1', 0
szNoBomb db '炸彈數(shù)量 : 0', 0
szStep db '移動(dòng)次數(shù) : %d', 0
szGameTime db ' %02d:%02d:%02d', 0
;------------------------------------------------------------------------
.data?
hInstance dd ? ; 實(shí)例句柄
hWinMain dd ? ; 主窗口句柄
hMenu dd ? ; 菜單句柄
hWinToolbar dd ? ; 工具欄句柄
hWinStatus dd ? ; 狀態(tài)欄句柄
hBackDC dd ? ; 背景位圖設(shè)備環(huán)境句柄
hBitmap dd ? ; 背景位圖句柄
LocalTime dd ? ; 當(dāng)前系統(tǒng)時(shí)間的秒數(shù)
TimeCircle dd ? ; 時(shí)間循環(huán)周期的秒數(shù): 24 * 3600 * n
TimeFlag dd ? ; 計(jì)時(shí)標(biāo)志位,1表示進(jìn)行及時(shí);0表示停止計(jì)時(shí)
GameHour dd ?
GameMinute dd ?
GameSecond dd ?
Map db 14d * 12d dup (?) ; 存放當(dāng)前關(guān)卡的地圖數(shù)據(jù)
ObjectLeft dd ? ; 剩余的目標(biāo)地點(diǎn)數(shù)量
ManXPos dd ? ; 角色的列坐標(biāo)
ManYPos dd ? ; 角色的行坐標(biāo)
BombXPos dd ? ; 炸彈的列坐標(biāo)
BombYPos dd ? ; 炸彈的行坐標(biāo)
CurrentGate dd ? ; 當(dāng)前的關(guān)卡號
BombCount dd ? ; 炸彈的剩余數(shù)量,初始化時(shí)為1
BombFlag dd ? ; 炸彈的存在標(biāo)志,1表示存在,0表示隱藏
StepNumber dd ? ; 玩家移動(dòng)次數(shù)
dwCount dd ? ; 隨機(jī)數(shù)
BackBuffer dd 8 * BackStep dup (?) ; 回退坐標(biāo)緩沖區(qū)
BackLength dd ? ; 當(dāng)前可回退的次數(shù)
;************************************************************************
;************************************************************************
; 代碼段
;------------------------------------------------------------------------
.code
;************************************************************************
_Quit proc
invoke DestroyWindow, hWinMain
invoke PostQuitMessage, NULL
ret
_Quit endp
;************************************************************************
;************************************************************************
; 加載位圖資源
;------------------------------------------------------------------------
_LoadRes proc
local @hDC ; 參考句柄
invoke GetDC, hWinMain
mov @hDC, eax
invoke CreateCompatibleDC, @hDC
mov hBackDC, eax
invoke LoadBitmap, hInstance, BM_MAIN
mov hBitmap, eax
invoke ReleaseDC, hWinMain, @hDC
invoke SelectObject, hBackDC, hBitmap
ret
_LoadRes endp
;************************************************************************
;************************************************************************
; 釋放資源
;------------------------------------------------------------------------
_FreeRes proc
invoke DeleteDC, hBackDC
invoke DeleteObject, hBitmap
invoke KillTimer, hWinMain, ID_GAMETIMER
; invoke KillTimer, hWinMain, ID_SHOWBOMB
ret
_FreeRes endp
;************************************************************************
;************************************************************************
; 設(shè)置當(dāng)前系統(tǒng)時(shí)間
;------------------------------------------------------------------------
_SetLocalTime proc uses ebx
local @Hour, @Minute, @Second
local @stST:SYSTEMTIME
invoke GetLocalTime, addr @stST
movzx eax, @stST.wHour
mov @Hour, eax
movzx eax, @stST.wMinute
mov @Minute, eax
movzx eax, @stST.wSecond
mov @Second, eax
mov eax, @Hour
mov ebx, 60d
mul ebx
add eax, @Minute
mul ebx
add eax, @Second
mov LocalTime, eax
mov eax, 1
mov TimeFlag, eax ; 允許及時(shí)
ret
_SetLocalTime endp
;************************************************************************
;************************************************************************
; 在狀態(tài)欄中顯示游戲中當(dāng)前關(guān)卡的運(yùn)行時(shí)間
;------------------------------------------------------------------------
_SetGameTime proc
local @Hour, @Minute, @Second
local @stST:SYSTEMTIME
pushad
.if TimeFlag == 1
invoke GetLocalTime, addr @stST
movzx eax, @stST.wHour
mov @Hour, eax
movzx eax, @stST.wMinute
mov @Minute, eax
movzx eax, @stST.wSecond
mov @Second, eax
mov eax, @Hour
mov ebx, 60d
mul ebx
add eax, @Minute
mul ebx
add eax, @Second
mov ecx, eax
.if ( ecx == LocalTime && !TimeCircle )
inc eax
.elseif ( ecx < LocalTime || ( ecx == LocalTime && TimeCircle > 0 ) )
mov ecx, 86400d
sub ecx, LocalTime
add TimeCircle, ecx
push eax
invoke _SetLocalTime
pop eax
.endif
add eax, TimeCircle
sub eax, LocalTime
mov edx, 0
mov ebx, 3600d
div ebx
mov GameHour, eax
mov eax, edx
mov edx, 0
mov ebx, 60d
div ebx
mov GameMinute, eax
mov GameSecond, edx
.endif
popad
ret
_SetGameTime endp
;************************************************************************
;************************************************************************
; 使窗口客戶區(qū)無效,使Windows向窗口過程發(fā)送WM_PAINT消息
;------------------------------------------------------------------------
_Repaint proc
local @rect:RECT
invoke GetClientRect, hWinMain, addr @rect
invoke InvalidateRect, hWinMain, addr @rect, 0
ret
_Repaint endp
;************************************************************************
;************************************************************************
; Pos = y * 14 + x, 其中( x, y )以0為起始坐標(biāo)
; eax中存儲(chǔ)著( x, y )在Map中的線性邏輯地址
; edx中存儲(chǔ)著( x, y )在Map中線性邏輯地址對應(yīng)的位圖索引值相應(yīng)的位圖起始X坐標(biāo)
;------------------------------------------------------------------------
_SearchMapLinePos proc uses ebx esi, x, y
mov esi, offset Map
mov eax, y
mov ebx, 14d
mul ebx
add eax, x
mov bl, [esi][eax]
.if bl == MAP_BACK
mov edx, xBmBack
.elseif bl == MAP_WALL
mov edx, xBmWall
.elseif bl == MAP_ROAD
mov edx, xBmRoad
.elseif bl == MAP_BOX1
mov edx, xBmBox1
.elseif bl == MAP_BOX2
mov edx, xBmBox2
.elseif bl == MAP_OBJECT
mov edx, xBmObject
.elseif bl == MAP_MAN
mov edx, xBmMan
.else
mov edx, xBmBomb
.endif
ret
_SearchMapLinePos endp
;************************************************************************
;************************************************************************
; 將"BitMapXPosition"打印到起始點(diǎn)為( xPosition, yPosition )的客戶區(qū)中
;------------------------------------------------------------------------
_PaintOneBitmap proc xPosition, yPosition, BitmapXPosition, @hDC
local x, y
pushad
mov eax, xPosition ; xPosition為在Map中的列號
mov ebx, 30d
mul ebx
mov x, eax
mov eax, yPosition ; yPosition為在Map中的行號
mov ebx, 30d
mul ebx
add eax, 30d ; 因?yàn)楣ぞ邫谝喈嫷娇蛻魠^(qū)中,因此要畫到客戶區(qū)以下
mov y, eax
.if @hDC == 0
invoke GetDC, hWinMain
mov @hDC, eax
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, BitmapXPosition, 0, SRCCOPY
invoke ReleaseDC, hWinMain, @hDC
.else
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, BitmapXPosition, 0, SRCCOPY
.endif
popad
ret
_PaintOneBitmap endp
;************************************************************************
;************************************************************************
; 重新繪制客戶區(qū)
;------------------------------------------------------------------------
_WMPaint proc @hDC
local i, j, x, y
mov x, 0
mov y, 30d
mov i, 1
mov j, 1
mov esi, offset Map
;--------------------------------------------------------------------------
;按照StoreHouse中相應(yīng)的位圖索引將BackBitMap中的位圖像素復(fù)制到窗口的設(shè)備環(huán)境中
;--------------------------------------------------------------------------
@@NextRol:
mov x, 0
mov j, 1
@@NextCol:
;---Calc nPos, nPos = (i-1) * 14 + (j-1)
mov eax, i
dec eax
mov ebx, 14d
mul ebx
add eax, j
dec eax
mov al, [esi][eax]
.if al == MAP_BACK
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmBack, 0, SRCCOPY
.elseif al == MAP_WALL
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmWall, 0, SRCCOPY
.elseif al == MAP_ROAD
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmRoad, 0, SRCCOPY
.elseif al == MAP_BOX1
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmBox1, 0, SRCCOPY
.elseif al == MAP_BOX2
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmBox2, 0, SRCCOPY
.elseif al == MAP_OBJECT
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmObject, 0, SRCCOPY
.else
invoke BitBlt, @hDC, x, y, 30, 30, hBackDC, xBmMan, 0, SRCCOPY
.endif
add x, 30d
inc j
cmp j, 15d
jb @@NextCol
inc i
add y, 30d
cmp i, 13
jb @@NextRol
;------------------------------------------------------------------------
; 按照man在Map中的坐標(biāo),將他對應(yīng)的像素復(fù)制到相應(yīng)位置
;------------------------------------------------------------------------
invoke _PaintOneBitmap, ManXPos, ManYPos, xBmMan, @hDC
ret
_WMPaint endp
;************************************************************************
;************************************************************************
; 選擇參數(shù)@Gate指定的關(guān)卡
;------------------------------------------------------------------------
_SelectGate proc @Gate
local szTmp1[10] : byte
local szTmp2[20] : byte
mov eax, @Gate
.if ( eax > MAX_GATES || eax < 1 )
xor eax, eax
mov TimeFlag, eax
invoke MessageBox, hWinMain, addr szOutOfRange, \
addr szCaption, MB_ICONINFORMATION or MB_OKCANCEL
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -