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

📄 mybox.asm

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