⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mybox.asm

📁 推箱子 win32做的!!! 本游戏是从先前Redfox的源程序修改而来(不过
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; 此时的( 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 + -