免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2192 | 回复: 0
打印 上一主题 下一主题

CarmarkBuffer,写在项目中用的模块 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-03 15:48 |只看该作者 |倒序浏览

/**
* 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
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP