/** * Carmark buffer unit * To init tile map buffer, * CarmarkBuffer_setTile()/CarmarkBuffer_setView() to set tile and view properties * call CarmarkBuffer_setup() * ! Rewrite function CarmarkBuffer_drawTile() according to your game. * call CarmarkBuffer_draw() when you want to paint tile map */
final static int TILE_WIDTH_DEFAULT = 16; final static int TILE_HEIGHT_DEFAULT = 16; final static int VIEW_LEFT_DEFAULT = 0; final static int VIEW_TOP_DEFAULT = 0; final static int VIEW_WIDTH_DEFAULT = SCREEN_WIDTH; final static int VIEW_HEIGHT_DEFAULT = SCREEN_HEIGHT;
static int CM_TILE_WIDTH = TILE_WIDTH_DEFAULT; static int CM_TILE_HEIGHT = TILE_HEIGHT_DEFAULT; static int CM_VIEW_LEFT = VIEW_LEFT_DEFAULT; static int CM_VIEW_TOP = VIEW_TOP_DEFAULT; static int CM_VIEW_WIDTH = VIEW_WIDTH_DEFAULT; static int CM_VIEW_HEIGHT = VIEW_HEIGHT_DEFAULT;
static int CM_MAPBUFF_WIDTH = (CM_VIEW_WIDTH + CM_TILE_WIDTH + CM_TILE_WIDTH - 1) / CM_TILE_WIDTH * CM_TILE_WIDTH; static int CM_MAPBUFF_HEIGHT= (CM_VIEW_HEIGHT + CM_TILE_HEIGHT + CM_TILE_HEIGHT - 1) / CM_TILE_HEIGHT * CM_TILE_HEIGHT;
static boolean cm_bufferNeedReset = true; static boolean cm_updateMapAll; static Image cm_bufImage; static Graphics cm_gBuf;
static int cm_mapBuffTY0; static int cm_mapBuffTX1; static int cm_mapBuffTY1; static int cm_mapBuffTX0;
static int cm_mapTileW, cm_mapTileH;
private static void CarmarkBuffer_reset(){ cm_bufferNeedReset = false; CM_MAPBUFF_WIDTH = (CM_VIEW_WIDTH + CM_TILE_WIDTH + CM_TILE_WIDTH - 1) / CM_TILE_WIDTH * CM_TILE_WIDTH; CM_MAPBUFF_HEIGHT = (CM_VIEW_HEIGHT + CM_TILE_HEIGHT + CM_TILE_HEIGHT - 1) / CM_TILE_HEIGHT * CM_TILE_HEIGHT;
CarmarkBuffer_initBufferImage(); }
private static void CarmarkBuffer_invalidTiles(int tx0, int ty0, int tx1, int ty1) { for (int y = ty0; y <= ty1; y++) for (int x = tx0; x <= tx1; x++) CarmarkBuffer_drawTile(x, y); }
private static void CarmarkBuffer_paintToScreen(Graphics g, int viewX, int viewY) { int x0 = -viewX % CM_MAPBUFF_WIDTH; if (x0 < 0) x0 += CM_MAPBUFF_WIDTH; int y0 = -viewY % CM_MAPBUFF_HEIGHT; if (y0 < 0) y0 += CM_MAPBUFF_HEIGHT;
g.setClip(CM_VIEW_LEFT, CM_VIEW_TOP, CM_VIEW_WIDTH, CM_VIEW_HEIGHT);
x0 += CM_VIEW_LEFT; y0 += CM_VIEW_TOP; for (int x = x0 - CM_MAPBUFF_WIDTH; x <= x0; x += CM_MAPBUFF_WIDTH) for (int y = y0 - CM_MAPBUFF_HEIGHT; y <= y0; y += CM_MAPBUFF_HEIGHT) g.drawImage(cm_bufImage, x, y, 0); }
private static void CarmarkBuffer_initBufferImage() { cm_gBuf = null; cm_bufImage = null; cm_bufImage = Image.createImage(CM_MAPBUFF_WIDTH, CM_MAPBUFF_HEIGHT); cm_gBuf = cm_bufImage.getGraphics(); }
public static void CarmarkBuffer_setTile(int tileW, int tileH){ if (CM_TILE_WIDTH != tileW || CM_TILE_HEIGHT != tileH) cm_bufferNeedReset = true; CM_TILE_WIDTH = tileW; CM_TILE_HEIGHT = tileH; }
public static void CarmarkBuffer_setView(int viewLeft, int viewTop, int viewW, int viewH){ if (CM_VIEW_WIDTH != viewW || CM_VIEW_HEIGHT != viewH) cm_bufferNeedReset = true;
CM_VIEW_LEFT = viewLeft; CM_VIEW_TOP = viewTop; CM_VIEW_WIDTH = viewW; CM_VIEW_HEIGHT = viewH; }
public static void CarmarkBuffer_setup(int mapTileW, int mapTileH) { cm_mapTileH = mapTileH; cm_mapTileW = mapTileW; cm_updateMapAll = true;
if (cm_bufImage == null) cm_bufferNeedReset = true; if (cm_bufferNeedReset) CarmarkBuffer_reset(); }
/** * draw buffer to screen * @param g * @param viewX: camera x * @param viewY: camera y */ public static void CarmarkBuffer_draw(Graphics g, int viewX, int viewY) { int viewTX0, viewTY0, viewTX1, viewTY1; int viewTX0N, viewTX1N; // avoid drawing crossing areas.
viewTX0N = viewTX0 = viewX / CM_TILE_WIDTH; viewTX1N = viewTX1 = (viewX + CM_VIEW_WIDTH - 1) / CM_TILE_WIDTH; viewTY0 = viewY / CM_TILE_HEIGHT; viewTY1 = (viewY + CM_VIEW_HEIGHT - 1) / CM_TILE_HEIGHT;
if (viewTX0 < 0) viewTX0N = viewTX0 = 0; else if (viewTX0 > cm_mapTileW - 1) viewTX0 = cm_mapTileW - 1;
if (viewTY0 < 0) viewTY0 = 0; else if (viewTY0 > cm_mapTileH - 1) viewTY0 = cm_mapTileH - 1;
if (!cm_updateMapAll){ if (viewTX1 < cm_mapBuffTX0 || viewTX0 > cm_mapBuffTX1 || viewTY1 < cm_mapBuffTY0 || viewTY0 > cm_mapBuffTY1) cm_updateMapAll = true; else { if (viewTX0 < cm_mapBuffTX0) { viewTX0N = cm_mapBuffTX0; CarmarkBuffer_invalidTiles(viewTX0, viewTY0, cm_mapBuffTX0 - 1, viewTY1); } else if (viewTX1 > cm_mapBuffTX1) { viewTX1N = cm_mapBuffTX1; CarmarkBuffer_invalidTiles(cm_mapBuffTX1 + 1, viewTY0, viewTX1, viewTY1); }
if (viewTY1 < cm_mapBuffTY0 || viewTY0 > cm_mapBuffTY1) cm_updateMapAll = true; else if (viewTY0 < cm_mapBuffTY0) CarmarkBuffer_invalidTiles(viewTX0N, viewTY0, viewTX1N, cm_mapBuffTY0 - 1); else if (viewTY1 > cm_mapBuffTY1) CarmarkBuffer_invalidTiles(viewTX0N, cm_mapBuffTY1 + 1, viewTX1N, viewTY1); } } if (cm_updateMapAll) { cm_updateMapAll = false; CarmarkBuffer_invalidTiles(viewTX0, viewTY0, viewTX1, viewTY1); }
cm_mapBuffTX0 = viewTX0; cm_mapBuffTY0 = viewTY0; cm_mapBuffTX1 = viewTX1; cm_mapBuffTY1 = viewTY1;
CarmarkBuffer_paintToScreen(g, viewX, viewY); }
public static void CarmarkBuffer_free() { cm_gBuf = null; cm_bufImage = null; }
static void CarmarkBuffer_drawTile(int tx, int ty){ int x = tx * CM_TILE_WIDTH % CM_MAPBUFF_WIDTH; int y = ty * CM_TILE_HEIGHT % CM_MAPBUFF_HEIGHT; int tileIndex = tx % cm_mapTileW + ty * cm_mapTileW; if (tx < 0 || tx >= cm_mapTileW || ty < 0 || ty >= cm_mapTileH) cm_gBuf.fillRect(x, y, CM_TILE_WIDTH, CM_TILE_HEIGHT); else CGame.Map_PaintTile(cm_gBuf, tileIndex, x, y); }
|