📄 tilemap.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 + -