?? mybox.asm
字號:
invoke _SelectGate, CurrentGate
ret
.endif
pushad
mov CurrentGate, eax
mov eax, 14d * 12d + 4
mov ebx, @Gate
dec ebx
mul ebx
mov esi, offset BoxMaps
add esi, eax
mov eax, dword ptr [esi] ; 取出本關卡的目標地點數量
mov ObjectLeft, eax
add esi, 4
mov edi, offset Map
mov ecx, 14d * 12d
cld ; 設置內存地址為遞增方向
rep movsb
mov ecx, 0
mov esi, offset Map
;------------------查找玩家控制角色的線性邏輯坐標---------------------
@@:
mov ebx, ecx
mov al, [esi][ebx]
cmp al, MAP_MAN
jz @F
inc ecx
cmp ecx, 14d * 12d
jnz @B
@@:
mov al, MAP_ROAD
mov [esi][ebx], al
;------------------將角色的線性邏輯坐標轉換為二維邏輯坐標--------------
mov edx, 0
mov eax, ecx ; ecx的值為man在Map中的邏輯線性地址
mov ebx, 14d
div ebx
mov ManXPos, edx ; 余數,注意坐標從0開始計算
mov ManYPos, eax ; 商, 注意坐標從0開始計算
invoke wsprintf, addr szTmp1, addr FmtGate, CurrentGate
invoke lstrcpy, addr szTmp2, addr szCaption
invoke lstrcat, addr szTmp2, addr szTmp1
invoke SendMessage, hWinMain, WM_SETTEXT, 0, addr szTmp2 ; 設置標題欄上的文本顯示
;-------------------初始化當前可回退次數為0-----------------------------
xor eax, eax
mov BackLength, eax
;-------------------初始化炸彈狀態--------------------------------------
inc eax
mov BombCount, eax
dec eax
mov BombFlag, eax
mov BombXPos, eax
invoke SendMessage, hWinStatus, SB_SETTEXT, 1, addr szBomb
;-------------------初始化玩家移動步數----------------------------------
xor eax, eax
mov StepNumber, eax
invoke wsprintf, addr szTmp2, addr szStep, StepNumber
invoke SendMessage, hWinStatus, SB_SETTEXT, 2, addr szTmp2
;-------------------初始化游戲時間--------------------------------------
xor eax, eax
mov TimeCircle, eax
mov TimeFlag, eax ; 禁止計時
mov GameHour, eax
mov GameMinute, eax
mov GameSecond, eax
invoke _SetLocalTime ; 測試使用
popad
ret
_SelectGate endp
;************************************************************************
;************************************************************************
; 炸彈移動
;------------------------------------------------------------------------
_BombMove proc @KeyDown
local @xNext, @yNext
local @addrBomb
pushad
mov eax, BombXPos
mov @xNext, eax
mov eax, BombYPos
mov @yNext, eax
mov eax, @KeyDown
.if eax == VK_UP
dec @yNext
.elseif eax == VK_DOWN
inc @yNext
.elseif eax == VK_LEFT
dec @xNext
.elseif eax == VK_RIGHT
inc @xNext
.else
ret
.endif
invoke _SearchMapLinePos, @xNext, @yNext
mov @addrBomb, eax
invoke _SearchMapLinePos, ManXPos, ManYPos
.if eax != @addrBomb ; eax中為角色在Map中的線性邏輯地址
mov esi, offset Map
invoke _SearchMapLinePos, @xNext, @yNext
mov al, [esi][eax]
.if ( al == MAP_ROAD || al == MAP_OBJECT || al == MAP_WALL )
invoke _SearchMapLinePos, BombXPos, BombYPos
invoke _PaintOneBitmap, BombXPos, BombYPos, edx, 0
push @xNext
pop BombXPos
push @yNext
pop BombYPos
.endif
.endif
popad
ret
_BombMove endp
;************************************************************************
;************************************************************************
; 保存上一次移動的坐標及坐標位圖
;------------------------------------------------------------------------
_SaveStep proc x1, y1, x2, y2
pushad
mov eax, BackLength
.if eax == BackStep
mov esi, offset BackBuffer
mov edi, esi
add esi, 8 * 4
mov ecx, 8 * ( BackStep - 1 )
cld ; 設置內存地址位增加方式
rep movsd
dec BackLength
.endif
mov esi, offset BackBuffer
mov eax, BackLength
mov ebx, 8 * 4
mul ebx
add esi, eax
mov eax, ManXPos
mov [esi], eax
mov eax, ManYPos
mov [esi + 4], eax
mov eax, x1
mov [esi + 8], eax
mov eax, y1
mov [esi + 12], eax
invoke _SearchMapLinePos, x1, y1
mov [esi + 16], edx
mov eax, x2
mov [esi + 20], eax
mov eax, y2
mov [esi + 24], eax
invoke _SearchMapLinePos, x2, y2
mov [esi + 28], edx
inc BackLength
popad
ret
_SaveStep endp
;************************************************************************
;************************************************************************
; 恢復一步Map中的地圖數據
;------------------------------------------------------------------------
_SetCoordinate proc x, y, @BitmapX
pushad
mov esi, offset Map
mov eax, y
mov ebx, 14
mul ebx
add eax, x ; eax中保存著( x, y )在Map中的線性地址
.if @BitmapX == xBmBack
mov bl, MAP_BACK
.elseif @BitmapX == xBmWall
mov bl, MAP_WALL
.elseif @BitmapX == xBmRoad
mov bl, MAP_ROAD
.elseif @BitmapX == xBmBox1
mov bl, MAP_BOX1
.elseif @BitmapX == xBmBox2
mov bl, MAP_BOX2
.else
mov bl, MAP_OBJECT
.endif
mov [esi][eax], bl
popad
ret
_SetCoordinate endp
;************************************************************************
;************************************************************************
; 后退一步
;------------------------------------------------------------------------
_LoadStep proc
local @szTemp[20] : byte
pushad
.if BackLength > 0
;----------------隱藏炸彈------------------
xor eax, eax
mov BombFlag, eax
invoke _SearchMapLinePos, BombXPos, BombYPos
invoke _PaintOneBitmap, BombXPos, BombYPos, edx, 0
;------------------------------------------
dec BackLength
mov esi, offset BackBuffer
mov eax, BackLength
mov ebx, 8 * 4
mul ebx
add esi, eax
invoke _SetCoordinate, [esi + 20], [esi + 24], [esi + 28] ; 恢復地圖位圖數據
invoke _PaintOneBitmap, [esi + 20], [esi + 24], [esi + 28], 0 ; 恢復( xNew2, yNew2 )
invoke _SetCoordinate, [esi + 8], [esi + 12], [esi + 16] ; 恢復地圖位圖數據
invoke _PaintOneBitmap, [esi + 8], [esi + 12], [esi + 16], 0 ; 恢復( xNew1, yNew1 )
mov eax, [esi]
mov ManXPos, eax
mov eax, [esi + 4]
mov ManYPos, eax
invoke _PaintOneBitmap, [esi], [esi + 4], xBmMan, 0 ; 恢復角色位圖
dec StepNumber
mov eax, [esi + 28] ; ( xNew2, yNew2 )對應的位圖數據X起始坐標
mov ebx, [esi + 16] ; ( xNew1, yNew1 )對應的位圖數據X起始坐標
.if ( eax == xBmObject && ebx == xBmBox1 )
inc ObjectLeft ; 恢復目標數值
.elseif ( eax != xBmObject && ebx == xBmBox2 )
dec ObjectLeft ; 恢復目標數值
.endif
invoke wsprintf, addr @szTemp, addr szStep, StepNumber
invoke SendMessage, hWinStatus, SB_SETTEXT, 2, addr @szTemp
.endif
popad
ret
_LoadStep endp
;************************************************************************
;************************************************************************
; 將Map中的元素以二維數組的形勢表示,即由行號和列號表示,但注意行號、列號
; 是以Windows圖形中的坐標為標準,X表示列;Y表示行
;************************************************************************
_ManMove proc @KeyDown
local NewX1, NewY1, NewX2, NewY2
local M1 : byte, M2 : byte
local nPos1, nPos2
local szBuffer[20] : byte
pushad
mov eax, ManXPos
mov NewX1, eax
mov NewX2, eax
mov eax, ManYPos
mov NewY1, eax
mov NewY2, eax
mov eax, @KeyDown
;-----------------------------------------------------------------------
;找到man所在位置的下一個位置坐標,存儲在New*中;下下一個位置坐標,存儲在New*2中
;-----------------------------------------------------------------------
.if eax == VK_UP
dec NewY1
dec NewY2
dec NewY2
.elseif eax == VK_DOWN
inc NewY1
inc NewY2
inc NewY2
.elseif eax == VK_LEFT
dec NewX1
dec NewX2
dec NewX2
.elseif eax == VK_RIGHT
inc NewX1
inc NewX2
inc NewX2
.else
ret
.endif
;-----------------------------------------------------------------------
mov esi, offset Map
; 將點( NewX1, NewY2 )在Map中對應的線性邏輯地址中的數據存儲在M1中
invoke _SearchMapLinePos, NewX1, NewY1
mov ebx, eax
mov nPos1, eax ; nPos1中存儲著man所在二維邏輯位置上的下一個位置坐標
; 在Map中的線性邏輯坐標
mov al, [esi][ebx]
mov M1, al ; M1中存儲著man所在二維邏輯位置上的下一個位置坐標中對
; 應的位圖索引
; 將點( NewX2, NewY2 )在Map中對應的線性邏輯地址中的數據存儲在M2中
invoke _SearchMapLinePos, NewX2, NewY2
mov ebx, eax
mov nPos2, eax ; nPos2中存儲著man所在二維邏輯位置上的下兩個位置坐標
; 在Map中的線性邏輯坐標
mov al, [esi][ebx]
mov M2, al ; M2中存儲著man所在二維邏輯位置上的下兩個位置坐標中對
; 應的位圖索引
;--------------------重新繪制角色所在坐標的背景位圖---------------------
invoke _SearchMapLinePos, ManXPos, ManYPos
invoke _PaintOneBitmap, ManXPos, ManYPos, edx, 0
mov al, M1
.if (al == MAP_ROAD || al == MAP_OBJECT )
invoke _SaveStep, NewX1, NewY1, NewX2, NewY2
push NewX1
pop ManXPos
push NewY1
pop ManYPos
.elseif al == MAP_BOX1
mov al, M2
.if al == MAP_ROAD
invoke _SaveStep, NewX1, NewY1, NewX2, NewY2
mov ebx, nPos2
mov al, MAP_BOX1
mov [esi][ebx], al
mov ebx, nPos1
mov al, MAP_ROAD
mov [esi][ebx], al
push NewX1
pop ManXPos
push NewY1
pop ManYPos
.elseif al == MAP_OBJECT
invoke _SaveStep, NewX1, NewY1, NewX2, NewY2
mov ebx, nPos2
mov al, MAP_BOX2
mov [esi][ebx], al
mov ebx, nPos1
mov al, MAP_ROAD
mov [esi][ebx], al
push NewX1
pop ManXPos
push NewY1
pop ManYPos
dec ObjectLeft ; 剩余目標數減1
.else
jmp @F
.endif
.elseif al == MAP_BOX2
mov al, M2
.if al == MAP_ROAD
invoke _SaveStep, NewX1, NewY1, NewX2, NewY2
mov ebx, nPos2
mov al, MAP_BOX1
mov [esi][ebx], al
mov ebx, nPos1
mov al, MAP_OBJECT
mov [esi][ebx], al
push NewX1
pop ManXPos
push NewY1
pop ManYPos
inc ObjectLeft ; 剩余目標數加1
.elseif al == MAP_OBJECT
invoke _SaveStep, NewX1, NewY1, NewX2, NewY2
mov ebx, nPos2
mov al, MAP_BOX2
mov [esi][ebx], al
mov ebx, nPos1
mov al, MAP_OBJECT
mov [esi][ebx], al
push NewX1
pop ManXPos
push NewY1
pop ManYPos
.else
jmp @F
.endif
.else
jmp @F
.endif
;--------------------在狀態欄上刷新玩家的移動次數-----------------------
inc StepNumber
invoke wsprintf, addr szBuffer, addr szStep, StepNumber
invoke SendMessage, hWinStatus, SB_SETTEXT, 2, addr szBuffer
;--------------------重新繪制( NewX2, NewY2 )位圖-----------------------
invoke _SearchMapLinePos, NewX2, NewY2
invoke _PaintOneBitmap, NewX2, NewY2, edx, 0
@@:
;------------------------重新繪制角色位圖-------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -