- 论坛徽章:
- 0
|
/**
* 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);
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/24501/showart_2138344.html |
|