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

📄 mappy.java

📁 一个JAVA的地图编辑器,适合快速开发移动终端游戏的好工具.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:


	/**
	 * Loads the BKDT chunk from the InputStream. <br>
	 * <br>
	 * BKDT: Block data. Contains BLKSTR structures for however many block
	 * structures were made. <br>
	 **/
	private void loadBKDT(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
		byte	bytBKDT[];
		byte	bytTemp;
		int		intIndex;
		int		intImageByteSize;
		Block	block;

		log.info("Found Chunk - BKDT, reading...");

		log.info("  loading " + Integer.toString(m_intNoOfBlocks) + " blocks.");
		bytBKDT 			= new byte[m_intBlockByteSize];
		m_clsMapBlockStrPt 	= new Block[m_intNoOfBlocks];

		for (intIndex = 0; intIndex < m_intNoOfBlocks; intIndex++) {
			readStream(stream, bytBKDT, 0, bytBKDT.length);

			// twistin..
			if (blnLSB) {
				for (int j = 0; j < 24; j += 4) {
					bytTemp 		= bytBKDT[j];
					bytBKDT[j] 		= bytBKDT[j+3];
					bytBKDT[j+3]	= bytTemp;
					bytTemp 		= bytBKDT[j+1];
					bytBKDT[j+1] 	= bytBKDT[j+2];
					bytBKDT[j+2] 	= bytTemp;
				}
				bytTemp 		= bytBKDT[24];
				bytBKDT[24]		= bytBKDT[25];
				bytBKDT[25] 	= bytTemp;
				bytTemp 		= bytBKDT[26];
				bytBKDT[26] 	= bytBKDT[27];
				bytBKDT[27] 	= bytTemp;
			}

			// read in block
			if (m_intMapType == 0) intImageByteSize	= m_intBlockWidth * m_intBlockHeight * ((m_intColourDepth + 1) / 8);	// that '+1' will be to cater for a colour depth of 15
			else intImageByteSize = 1;
			
			block 				= new Block();

			block.setImageIndex(block.BACKGROUND,  convertToInt(bytBKDT,  0, 4) / intImageByteSize);
			block.setImageIndex(block.FOREGROUND1, convertToInt(bytBKDT,  4, 4) / intImageByteSize);
			block.setImageIndex(block.FOREGROUND2, convertToInt(bytBKDT,  8, 4) / intImageByteSize);
			block.setImageIndex(block.FOREGROUND3, convertToInt(bytBKDT, 12, 4) / intImageByteSize);

			block.setUserData(1, convertToInt(bytBKDT, 16, 4));
			block.setUserData(2, convertToInt(bytBKDT, 20, 4));
			block.setUserData(3, convertToInt(bytBKDT, 24, 2));
			block.setUserData(4, convertToInt(bytBKDT, 26, 2));
			block.setUserData(5, convertToInt(bytBKDT, 28, 1));
			block.setUserData(6, convertToInt(bytBKDT, 29, 1));
			block.setUserData(7, convertToInt(bytBKDT, 30, 1));
			block.setFlag(block.COLLISION_TOP_LEFT,     ((bytBKDT[31] & 0x01) != 0 ? true : false));
			block.setFlag(block.COLLISION_TOP_RIGHT,    ((bytBKDT[31] & 0x02) != 0 ? true : false));
			block.setFlag(block.COLLISION_BOTTOM_LEFT,  ((bytBKDT[31] & 0x04) != 0 ? true : false));
			block.setFlag(block.COLLISION_BOTTOM_RIGHT, ((bytBKDT[31] & 0x08) != 0 ? true : false));
			block.setFlag(block.TRIGGER,				((bytBKDT[31] & 0x10) != 0 ? true : false));
			block.setFlag(block.UNUSED1,				((bytBKDT[31] & 0x20) != 0 ? true : false));
			block.setFlag(block.UNUSED2,				((bytBKDT[31] & 0x40) != 0 ? true : false));
			block.setFlag(block.UNUSED3,				((bytBKDT[31] & 0x80) != 0 ? true : false));

			m_clsMapBlockStrPt[intIndex] = block;
		}
	}



	/**
	 * Loads the ANDT chunk from the InputStream. <br>
	 * <br>
	 * ANDT: Animation data. Contains ANISTR structures for however many
	 * animation structures were made, and also animation data. <br>
	 **/
	private void loadANDT(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
		byte	bytANDT[];
		byte	bytTemp;
		int		intIndex;
		int 	intANDTPos;
		int 	intOffset1, intOffset2;

		log.info("Found Chunk - ANDT, reading...");

		bytANDT = new byte[intChunkLength];
		readStream(stream, bytANDT, 0, bytANDT.length);

		// count the no of AnimStructures
		intIndex 	= 0;
		intANDTPos	= intChunkLength - 16;
		while (bytANDT[intANDTPos] != -1) {
			intIndex++;
			intANDTPos -= 16;
		}

		log.info("  loading " + Integer.toString(intIndex) + " animation blocks." );
		m_clsMapAniStrPt = new AnimStructure[intIndex];

		// read in all the AnimStructures
		intIndex 	= 0;
		intANDTPos = intChunkLength - 16;
		while (bytANDT[intANDTPos] != -1) {
			m_clsMapAniStrPt[intIndex] 			= new AnimStructure();
			m_clsMapAniStrPt[intIndex].antype 	= (int) bytANDT[intANDTPos + 0];
			m_clsMapAniStrPt[intIndex].andelay 	= (int) bytANDT[intANDTPos + 1];
			m_clsMapAniStrPt[intIndex].ancount 	= (int) bytANDT[intANDTPos + 2];
			m_clsMapAniStrPt[intIndex].anuser 	= (int) bytANDT[intANDTPos + 3];

			if (blnLSB) {
				for (int j = 4; j < 16; j += 4) {
					bytTemp 				= bytANDT[intANDTPos+j+0];
					bytANDT[intANDTPos+j+0] = bytANDT[intANDTPos+j+3];
					bytANDT[intANDTPos+j+3] = bytTemp;

					bytTemp 				= bytANDT[intANDTPos+j+1];
					bytANDT[intANDTPos+j+1] = bytANDT[intANDTPos+j+2];
					bytANDT[intANDTPos+j+2] = bytTemp;
				}
			}

			intOffset1 = convertToInt(bytANDT, intANDTPos +  8, 4);
			intOffset2 = convertToInt(bytANDT, intANDTPos + 12, 4);
			if (m_intMapType > 0) {
				intOffset1 *= 4;
				intOffset1 -= intChunkLength;
				intOffset2 *= 4;
				intOffset2 -= intChunkLength;
			}

			m_clsMapAniStrPt[intIndex].annumframes = (intOffset2 - intOffset1) / 4;
			m_clsMapAniStrPt[intIndex].ancurframe  = 1;
			m_clsMapAniStrPt[intIndex].anframelist = new int[((intOffset2 - intOffset1) / 4) + 1];

			for (int i = 0; i < (m_clsMapAniStrPt[intIndex].annumframes + 1); i++) {
				if (blnLSB) {
					bytTemp 								 = bytANDT[intChunkLength + intOffset1 - 4];
					bytANDT[intChunkLength + intOffset1 - 4] = bytANDT[intChunkLength + intOffset1 - 1];
					bytANDT[intChunkLength + intOffset1 - 1] = bytTemp;

					bytTemp 								 = bytANDT[intChunkLength + intOffset1 - 3];
					bytANDT[intChunkLength + intOffset1 - 3] = bytANDT[intChunkLength + intOffset1 - 2];
					bytANDT[intChunkLength + intOffset1 - 2] = bytTemp;
				}

				m_clsMapAniStrPt[intIndex].anframelist[i] 	 = convertToInt(bytANDT, intChunkLength + intOffset1 - 4, 4);
				if (m_intMapType == 0)  m_clsMapAniStrPt[intIndex].anframelist[i] /= m_intBlockByteSize;
				intOffset1 += 4;
			}

			intIndex++;
			intANDTPos -= 16;
		}
	}


	/**
	 * Loads the BGFX chunk from the InputStream. <br>
	 * <br>
	 * BGFX: The raw graphics in whatever format the map is in. <br>
	 **/
	private void loadBGFX(InputStream stream, int intChunkLength, Component component) throws IOException {
		byte	bytBGFX[];
		byte	bytTemp;
		int		intIndex;
		int 	intRed, intGreen, intBlue;
		int 	intColIndex;
		int 	intX, intY, intImageY = -1;
		int		intColour;
		int		intImageSource[];
		int		intBlockIndex;

		log.info("Found Chunk - BGFX, reading...");
		log.info("Transpcol = "+((m_intTransparentColour>>16)&0xFF)+"."+((m_intTransparentColour>>8)&0xFF)+"."+((m_intTransparentColour)&0xFF));

		log.info("  loading " + Integer.toString(m_intNoOfImages) + " images.");
		bytBGFX 		= new byte[m_intBlockWidth * m_intBlockHeight * ((m_intColourDepth + 1) / 8)];

		m_imgOpaqueBlocks = new Image[m_intNoOfImages];
		m_imgTransparentBlocks = new Image[m_intNoOfImages];

		for (intIndex = 0; intIndex < m_intNoOfImages; intIndex++) {
			intImageSource	= new int [m_intBlockWidth * m_intBlockHeight];
			m_imgOpaqueBlocks[intIndex] = component.createImage(m_intBlockWidth, m_intBlockHeight);
			Graphics gfx = m_imgOpaqueBlocks[intIndex].getGraphics();

			// read in Image data
			readStream(stream, bytBGFX, 0, bytBGFX.length);

			// Note: LSB doesn't apply in graphics
			intColIndex = 0;
			for (intY = 0 ; intY < m_intBlockHeight; intY++) {
				intImageY ++;
				for (intX = 0 ; intX < m_intBlockWidth; intX++) {

					// grab the colour of the pixel
					switch (m_intColourDepth) {
						case 8:
							intRed 		= ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 0])) & 0xFF;
							intGreen	= ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 1])) & 0xFF;
							intBlue 	= ((int) (m_bytColourMap[(((int) bytBGFX[intColIndex])&0xFF) * 3 + 2])) & 0xFF;
							break;
						case 15:
							intRed 		=  (((int) bytBGFX[intColIndex * 2 + 0]) & 0x7C) << 1;
							intGreen 	= ((((int) bytBGFX[intColIndex * 2 + 0]  & 0x03) << 3) | ((((int) bytBGFX[intColIndex * 2 + 1]) & 0xFF) >> 5)) << 3;
							intBlue 	=  (((int) bytBGFX[intColIndex * 2 + 1]) & 0x1F) << 3;
							intRed &= 0xFF; intRed |= (intRed >> 5);
							intGreen &= 0xFF; intGreen |= (intGreen >> 5);
							intBlue &= 0xFF; intBlue |= (intBlue >> 5);
							break;
						case 16:
							intRed 		=  (((int) bytBGFX[intColIndex * 2 + 0]) & 0xF8);
							intGreen 	= ((((int) bytBGFX[intColIndex * 2 + 0]  & 0x07) << 3) | ((((int) bytBGFX[intColIndex * 2 + 1]) & 0xFF) >> 5)) << 2;
							intBlue 	=  (((int) bytBGFX[intColIndex * 2 + 1]) & 0x1F) << 3;
							intRed &= 0xFF; intRed |= (intRed >> 5);
							intGreen &= 0xFF; intGreen |= (intGreen >> 6);
							intBlue &= 0xFF; intBlue |= (intBlue >> 5);
							break;
						case 24:
							intRed 		=   ((int) bytBGFX[intColIndex * 3 + 0]) & 0xFF;
							intGreen 	=   ((int) bytBGFX[intColIndex * 3 + 1]) & 0xFF;
							intBlue 	=   ((int) bytBGFX[intColIndex * 3 + 2]) & 0xFF;
							break;
						case 32:
							intRed 		=   ((int) bytBGFX[intColIndex * 4 + 1]) & 0xFF; // need & 0xFF to keep the int's posative
							intGreen	=   ((int) bytBGFX[intColIndex * 4 + 2]) & 0xFF;
							intBlue 	=   ((int) bytBGFX[intColIndex * 4 + 3]) & 0xFF;
							break;
						default:
							intRed 		= 0;
							intGreen 	= 0;
							intBlue 	= 0;
							break;
					}

					gfx.setColor(new Color(intRed, intGreen, intBlue));
					gfx.drawLine(intX, intY, intX, intY);

					// build up pixel information of the transparent image
					if (m_intColourDepth == 8) {
						if (((int) bytBGFX[intColIndex]) == m_intTransparentColour) {
							intColour = 0;
						} else {
							intColour = (255 << 24) | (intRed << 16) | (intGreen << 8) | intBlue;
						}
					} else {
						if (((intRed << 16) | (intGreen << 8) | intBlue) == m_intTransparentColour) {
							if (intX == 0 && intY == 0) log.info("Transpcol = "+m_intTransparentColour);
							intColour = 0;
						} else {
							intColour = (255 << 24) | (intRed << 16) | (intGreen << 8) | intBlue;
						}
					}
					intImageSource[intColIndex] = intColour;

					intColIndex++;
				}
			}
			// generate transparent image
			m_imgTransparentBlocks[intIndex] = component.createImage(new MemoryImageSource (m_intBlockWidth, m_intBlockHeight, intImageSource, 0, m_intBlockWidth));

		}
	}



	/**
	 * Loads the BODY / LYR? chunk from the InputStream. <br>
	 * <br>
	 * BODY: An array of short ints containing positive offsets into BKDT, and
	 * negative offsets into ANDT. <br>
	 * <br>
	 * LYR?: Where ? is an ASCII number form 1 to 7. These are the same size
	 * and format as BODY <br>
	 **/
	private void loadLayer(InputStream stream, int intChunkLength, boolean blnLSB) throws IOException {
		byte	bytBODY[];
		byte	bytTemp;
		int		intIndex;
		int		intX, intY;
		short	shtMapLayer[][];
		int		intLayer;

		if (m_intMaxLayerNo == 0) {
			log.info("Found Chunk - BODY, reading...");
		} else {
			log.info("Found Chunk - LYR" + Integer.toString(m_intMaxLayerNo) + ", reading...");
		}

		shtMapLayer = new short[m_intMapHeight][m_intMapWidth];
		bytBODY 	= new byte[2];

		for (intY = 0; intY < m_intMapHeight; intY++) {
			for (intX = 0; intX < m_intMapWidth; intX++) {
				readStream(stream,bytBODY, 0, 2);

				if (blnLSB) {
					bytTemp 	= bytBODY[0];
					bytBODY[0] 	= bytBODY[1];
					bytBODY[1] 	= bytTemp;
				}

				if (m_intMapType == 2) {		//map is RLE compressed
					int rlecount = ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
					if (rlecount >= 32768) rlecount -= 65536;
					if (rlecount > 0) {
						while (rlecount > 0) {
							readStream(stream,bytBODY, 0, 2);

							if (blnLSB) {
								bytTemp 	= bytBODY[0];
								bytBODY[0] 	= bytBODY[1];
								bytBODY[1] 	= bytTemp;
							}
							shtMapLayer[intY][intX] = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
							intX++; rlecount--;
						}
					} else {
						readStream(stream,bytBODY, 0, 2);

						if (blnLSB) {
							bytTemp 	= bytBODY[0];
							bytBODY[0] 	= bytBODY[1];
							bytBODY[1] 	= bytTemp;
						}
						short rleval = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));
						while (rlecount < 0) {
							shtMapLayer[intY][intX] = rleval;
							intX++; rlecount++;
						}
					}
					intX--; //correct for RLE
				} else {
					shtMapLayer[intY][intX] = (short) ((((int) bytBODY[0]) << 8) | (((int) bytBODY[1]) & 0xFF));

					if (shtMapLayer[intY][intX] >= 0) {
						if (m_intMapType == 0) shtMapLayer[intY][intX] /= m_intBlockByteSize;
					} else {
						if (m_intMapType == 0) shtMapLayer[intY][intX] /= 16;
					}
				}
			}
		}

		// save layer to The Map
		m_shtTheMap[m_intMaxLayerNo] = shtMapLayer;
		m_intMaxLayerNo++;
	}




	/**
	 * This checks wether the given Map layer is valid or not. Originally used
	 * by a couple of methods, now only used by one, so I may incorporate this
	 * in to that one method before long. <br>
	 * <br>
	 * @see		#setCurrentMapLayer(int)
	 **/
	private boolean validateMapLayer(int intMapLayer, String strMethodName) {
		boolean blnValid;

		// default return value
		blnValid = true;

		// validate intLayer
		if ((intMapLayer < 0) || (intMapLayer >= m_intMaxLayerNo)) {
			log.error(new ArrayIndexOutOfBoundsException(strMethodName + " - 'intMapLayer' is out of bounds, there are only " + Integer.toString(m_intMaxLayerNo) + " layers : " + Integer.toString(intMapLayer)));
			blnValid = false;
		}

		// return validity
		return blnValid;
	}



//______________________________________________________________________________
//------------------------------------------------------------------------------
// Private Methids : Drawing Routines
//______________________________________________________________________________
//------------------------------------------------------------------------------

	/**
	 * This <code>drawLayer()</code> method is called by both of the public draw
	 * methods. <br>
	 * <br>
	 * @see		#drawBackground(Graphics, boolean)
	 * @see		#drawForeground(Graphics, int)
	 **/
	private void drawLayer(Graphics gfx, int intBlockLayer, boolean blnTransparency) {
		int intBlockX,  intBlockY;
		int intSrcPixX, intSrcPixY;

		if (!m_blnMapLoaded) {
			log.warn("drawLayer() - A map hasn't been successfully loaded yet!");
			return;
		}

		intBlockX 	= m_intX[m_intCurrentMapLayer] / m_intBlockGapX;
		intBlockY 	= m_intY[m_intCurrentMapLayer] / m_intBlockGapY;
		intSrcPixX 	= m_intX[m_intCurrentMapLayer] % m_intBlockGapX;
		intSrcPixY 	= m_intY[m_intCurrentMapLayer] % m_intBlockGapY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -