Chinaunix首页 | 论坛 | 博客
  • 博客访问: 349189
  • 博文数量: 101
  • 博客积分: 4714
  • 博客等级: 大校
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-01 04:51
文章分类

全部博文(101)

文章存档

2011年(1)

2010年(98)

2008年(2)

分类: Java

2010-01-03 15:48:18

/**
 * 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);
    }


阅读(1473) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~