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

📄 tilemap.hpp

📁 超级玛丽
💻 HPP
字号:
#ifndef _TILEMAP_H_
#define _TILEMAP_H_

//-------------------------------------------------------------------------------------
//
// This is part of MarioDemo, a platformer demo for JGE++
// 
// Copyright (C) 2006 James Hui (a.k.a. Dr.Watson)
// 
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option) any
// later version.
// 
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA 02111-1307 USA
// 
// Bugs and comments can be forwarded to jhkhui@yahoo.com. 
// 
//-------------------------------------------------------------------------------------

#include "../../JGE/include/JGE.h"


#define		TILE_WIDTH		32
#define		TILE_HEIGHT		32

#define		TILE_SHIFT		5

#define		TILE_SOLID		1
#define		TILE_MONEY		2
#define		TILE_POWERUP	3
#define		TILE_TUNNEL		4


typedef JQuad*		JQUAD_PTR;

class TileMap
{
private:
	JGE* mEngine;
	GameStatePlay* mApp;

	JTexture* mTileTex;
	
	short* mTilemap;
	u8* mTilemapCollision;
	JQUAD_PTR* mTiles;

	int mTileWidth;
	int mTileHeight;
	
	int mCols;
	int mRows;

	int mColsPerScreen;
	int mRowsPerScreen;

	

	float mTargetX;
	float mTargetY;


	float mAnimateCounter;

public:
	TileMap(GameStatePlay* app, JTexture* tex);
	~TileMap();
	float mMapX;
	float mMapY;
	int gangplank; 

	void Load(const char* mapDat, const char* mapCollision);

	void SetTarget(float x, float y);
	void Update(float dt);
	void Render(float x, float y);

	bool BBoxCollide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);

	int CheckHoriz(int x1, int x2, int y, bool fromLeft, int* col, int* row);
	int CheckVert(int x, int y1, int y2, int* col, int* row);

	short GetTile(int col, int row);
	u8 GetTileInfo(int col, int row);

	void SetTile(int col, int row, short tile);
	void SetTileInfo(int col, int row, u8 n);

	void GetPosition(float* x, float* y) { *x = mMapX; *y = mMapY; }
	void GetPositionMap(float x, float y) {mMapX = x; mMapY = y; }
};


TileMap::TileMap(GameStatePlay* app, JTexture* tex): mApp(app)
{
	
	gangplank = 0;

	mEngine = mApp->GetJGE();

	mTileTex = tex;
	
	mTilemap = NULL;
	mTilemapCollision = NULL;

	int col = tex->mWidth/TILE_WIDTH;
	int row = tex->mHeight/TILE_HEIGHT;

	mTiles = new JQUAD_PTR[col*row];
		
	float x = 0.0f;
	float y = 0.0f;

	int n = 0;

	for (int i=0;i<row;i++)
	{
		x = 0.0f;
		for (int j=0;j<col;j++)
		{
			mTiles[n++] = new JQuad(tex, x, y, TILE_WIDTH, TILE_HEIGHT);
			x += TILE_WIDTH;
		}

		y += TILE_HEIGHT;
	}

	mMapX = 0.0f;
	mMapY = 0.0f;//VIRTUAL_HEIGHT - SCREEN_HEIGHT_F;


	mAnimateCounter = 0;
}


TileMap::~TileMap()
{
	if (mTilemap)
		delete mTilemap;

	if (mTilemapCollision != NULL)
		delete mTilemapCollision;

	for (int i=0;i<32;i++)
		delete mTiles[i];

	delete[] mTiles;
}


void TileMap::Load(const char* mapDat, const char* mapCollision)
{
	if (mTilemap != NULL)
		delete mTilemap;

	if (mTilemapCollision != NULL)
		delete mTilemapCollision;

	FILE* f = fopen(mapDat, "rb");

	if (f != NULL)
	{
		short cols;
		short rows;

		fread(&cols, 1, sizeof(short), f);
		fread(&rows, 1, sizeof(short), f);

		mCols = (int)cols;
		mRows = (int)rows;

		mTilemap = new short[cols*rows];
		fread(mTilemap, cols*rows, sizeof(short), f);
		fclose(f);
	}

	f = fopen(mapCollision, "rb");

	if (f != NULL)
	{
		short cols;
		short rows;

		fread(&cols, 1, sizeof(short), f);
		fread(&rows, 1, sizeof(short), f);

		mTilemapCollision = new u8[cols*rows];
		fread(mTilemapCollision, cols*rows, sizeof(u8), f);
		fclose(f);
	}
}


void TileMap::Render(float x, float y)
{
	int mapX = (int) mMapX;
	int mapY = (int) mMapY;

	int col = mapX/TILE_WIDTH;
	float xoffset = -(float)(mapX%TILE_WIDTH);
	int row = mapY/TILE_HEIGHT;
	float yy = -(float)(mapY%TILE_HEIGHT);

	int start = mCols * row + col;
	
	float xx;
	int currCol;
	int n, index;
	while (yy < SCREEN_HEIGHT_F && row < mRows)
	{
		xx = xoffset;
		currCol = col;
		index = start;
		while (xx < SCREEN_WIDTH_F && currCol< mCols)
		{
			n = mTilemap[index++];
			if (n > 0)
			{
				mEngine->RenderQuad(mTiles[n], xx, yy);
			}
			xx += TILE_WIDTH;
			currCol++;
			
		}

		yy += TILE_HEIGHT;
		start += mCols;
		row++;
	}
}


bool BBoxCollide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
	if (x1 - x2 < -w1) return false;
	if (x1 - x2 > w2) return false;
	if (y1 - y2 < -h1) return false;
	if (y1 - y2 > h2) return false;
	
	return true;	// collision!!!
}


int TileMap::CheckHoriz(int x1, int x2, int y, bool fromLeft, int* col, int* row)
{
	int tile;
	
	int colStart;
	int colEnd;
	int incr;

	if (fromLeft)
	{
		colStart = x1>>TILE_SHIFT;
		colEnd = x2>>TILE_SHIFT;
		incr = 1;
	}
	else
	{
		colStart = x2>>TILE_SHIFT;
		colEnd = x1>>TILE_SHIFT;
		incr = -1;
	}

	*row = y>>TILE_SHIFT;
	*col = colStart;


	for (int currCol=colStart;; currCol+=incr)
	{
		if (currCol >= 0 && currCol < mCols && *row >= 0 && *row <= mRows)
		{
			tile = mTilemapCollision[(*row) * mCols + currCol];
			if (tile != 0)
			{
				*col = currCol;
				return tile;
			}
		}

		if (currCol==colEnd) break;
	}

	return 0;
}


int TileMap::CheckVert(int x, int y1, int y2, int* col, int* row)
{
	int tile;

	int rowStart = y1>>TILE_SHIFT;
	int rowEnd = y2>>TILE_SHIFT;
	
	*col = x>>TILE_SHIFT;
	*row = rowStart;

	for (int currRow = rowStart;currRow<=rowEnd;currRow++)
	{
		if (*col >= 0 && *col < mCols && currRow >= 0 && currRow <= mRows)
		{
			tile = mTilemapCollision[currRow * mCols + (*col)];
			if (tile != 0)
			{
				*row = currRow;
				return tile;
			}
		}
	}
	
	return 0;
}


short TileMap::GetTile(int col, int row)
{
	return mTilemap[row*mCols + col];
}


u8 TileMap::GetTileInfo(int col, int row)
{
	return mTilemapCollision[row*mCols + col];
}


void TileMap::SetTile(int col, int row, short tile)
{
	mTilemap[row*mCols + col] = tile;
}


void TileMap::SetTileInfo(int col, int row, u8 n)
{
	mTilemapCollision[row*mCols + col] = n;
}

void TileMap::SetTarget(float x, float y)
{
	mTargetX = x;
	mTargetY = y;
	
	if (mTargetX < 0.0f)
		mTargetX = 0.0f;
	if (mTargetX + SCREEN_WIDTH_F > VIRTUAL_WIDTH)
		mTargetX = VIRTUAL_WIDTH - SCREEN_WIDTH_F;

	if (mTargetY < 0.0f)
		mTargetY = 0.0f;
	if (mTargetY + SCREEN_HEIGHT_F > VIRTUAL_HEIGHT)
		mTargetY = VIRTUAL_HEIGHT - SCREEN_HEIGHT_F;
}


void TileMap::Update(float dt)
{
	
	float speed = DEFAULT_WALK_SPEED;
	if (mMapX < mTargetX)
	{
		mMapX += speed*dt;
		if (mMapX > mTargetX)
			mMapX = mTargetX;
	}
	else if (mMapX > mTargetX)
	{
		mMapX -= speed*dt;
		if (mMapX < mTargetX)
			mMapX = mTargetX;
	}

	speed = 0.2f;
	if (mMapY < mTargetY)
	{
		mMapY += speed*dt/2;
		if (mMapY > mTargetY)
			mMapY = mTargetY;
	}
	else if (mMapY > mTargetY)
	{
		mMapY -= speed*dt*2;
		if (mMapY < mTargetY)
			mMapY = mTargetY;
	}


	mAnimateCounter += dt;
	if (mAnimateCounter > 100.0f)
	{
		mAnimateCounter = 0.0f;

		//mColsPerScreen;

		int col = (((int)mMapX)>>TILE_SHIFT)-1;
		int row = (((int)mMapY)>>TILE_SHIFT)-1;
		if (col<0) col = 0;
		if (row<0) row = 0;

		//int index = row*mColsPerScreen + col;

		short tile;
		u8 tileInfo;
		int currCol, currRow;

		for (int i=0;i<15+2;i++)
		{
			for (int j=0;j<20+2;j++)
			{
				currCol = col+j;
				currRow = row+i;

				if (currCol >=0 && currCol < mCols && currRow >= 0 && currRow < mRows)
				{
					
					//1 , 31, flashing tiles
					tile = GetTile(currCol, currRow);
					//if (tile == 1)
					//	SetTile(currCol, currRow, 31);
					//else if (tile == 31)
					//	SetTile(currCol, currRow, 1);

					tileInfo = GetTileInfo(currCol, currRow);
					if (tileInfo == BLOCK_TURTLE)
					{
						SetTileInfo(currCol, currRow, 0);
						mApp->SpawnTurtle(currCol, currRow);
					}
					else if (tileInfo == BLOCK_FLOWER)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnBadFlower(currCol, currRow);
					}
					else if (tileInfo == BLOCK_BADMUSH)
					{
						SetTileInfo(currCol, currRow, 0);
						mApp->SpawnBadMush(currCol, currRow);
					}
					else if (tileInfo == BLOCK_STAR)
					{
					}
					else if (tileInfo == BLOCK_COIN2)
					{
						SetTileInfo(currCol, currRow, 0);
						mApp->SpawnStaticCoin(currCol, currRow);
					}
					else if (tileInfo == BLOCK_TUNNEL)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnTunnel(currCol, currRow);
					}
					else if (tileInfo == BLOCK_TUNNEL_01)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnTunnel_1(currCol, currRow);
					}
					else if (tileInfo == BLOCK_TUNNEL_02)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnTunnel_2(currCol, currRow);
					}
					else if (tileInfo == BLOCK_TUNNEL_03)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnTunnel_3(currCol, currRow);
					}
					else if (tileInfo == BLOCK_TUNNEL_04)
					{
						SetTileInfo(currCol, currRow, 1);
						mApp->SpawnTunnel_4(currCol, currRow);
					}
					else if (tileInfo == BLOCK_SPRING)
					{			
						mApp->SpawnGangplank(currCol, currRow);
					}
					else if (tileInfo == BLOCK_DISAPPEAR)
					{
						mApp->SpawnGangplank(currCol, currRow);
					}
					else if (tileInfo == BLOCK_RIGHT)
					{
						mApp->SpawnGangplank_1(currCol, currRow);
					}
					else if (tileInfo == BLOCK_LEFT)
					{
						mApp->SpawnGangplank_2(currCol, currRow);
					}
					
				}
			}
		}

	}
}
#endif

⌨️ 快捷键说明

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