You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SurfaceView下固定区域绘制多张Bitmap:卡牌游戏遮挡问题求助

解决SurfaceView中卡牌被按钮遮挡的问题

看起来你遇到了卡牌布局超出预期区域、被按钮遮挡的问题,要把Bitmap限制在固定区域内,我们可以从定义固定绘制区域和调整卡牌布局逻辑两个方面入手,下面是具体的解决方案:


1. 第一步:定义固定的卡牌绘制区域

首先,我们需要明确一个不会被按钮遮挡的矩形区域,所有卡牌都将绘制在这个区域内。你可以在SurfaceView的尺寸变化时初始化这个区域:

private Rect cardDisplayArea;

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    Screen_Width = w;
    Screen_Height = h;
    Screen_Center_X = w / 2;
    
    // 自定义卡牌区域:避开底部按钮,比如按钮高度设为100dp
    int buttonHeight = dpToPx(100);
    // 区域顶部距离屏幕底部为「卡牌高度 + 按钮高度」,底部距离屏幕底部为按钮高度
    int cardAreaTop = h - Card_Height - buttonHeight;
    int cardAreaBottom = h - buttonHeight;
    // 左右留出50px边距,避免贴边
    int cardAreaLeft = 50;
    int cardAreaRight = w - 50;
    
    cardDisplayArea = new Rect(cardAreaLeft, cardAreaTop, cardAreaRight, cardAreaBottom);
}

// 辅助方法:dp转像素,适配不同屏幕
private int dpToPx(int dp) {
    return (int) (dp * getContext().getResources().getDisplayMetrics().density);
}

2. 第二步:调整卡牌布局逻辑,让卡牌在固定区域内排列

你原来的左右交替布局逻辑容易导致卡牌超出可见区域,我们可以改成根据固定区域的大小,自动调整卡牌的间距或重叠度,确保所有卡牌都在区域内:

private void setMainPlayer() {
    Card localcard = null;
    Player mainPlayer = playerList.get(0);
    mainPlayer.sortBySuit();
    int deckSize = mainPlayer.decksize();
    
    int cardAreaWidth = cardDisplayArea.right - cardDisplayArea.left;
    int totalCardWidth = deckSize * Card_Width;
    int cardGap;

    if (totalCardWidth <= cardAreaWidth) {
        // 卡牌总宽度小于区域宽度:均匀分布,居中显示
        int totalGap = cardAreaWidth - totalCardWidth;
        cardGap = totalGap / (deckSize + 1); // 左右和卡牌间的间距相等
        int startX = cardDisplayArea.left + cardGap;
        
        for (int i = 0; i < deckSize; i++) {
            localcard = mainPlayer.getCard(i);
            localcard.setCurrent_Y(cardDisplayArea.top); // Y固定在区域顶部
            localcard.setCurrent_X(startX + i * (Card_Width + cardGap));
            mainPlayer.setCurrentCard(localcard, i);
        }
    } else {
        // 卡牌总宽度超出区域:让卡牌重叠一部分,确保全部可见
        int overlapWidth = (totalCardWidth - cardAreaWidth) / (deckSize - 1);
        int startX = cardDisplayArea.left;
        
        for (int i = 0; i < deckSize; i++) {
            localcard = mainPlayer.getCard(i);
            localcard.setCurrent_Y(cardDisplayArea.top);
            localcard.setCurrent_X(startX + i * (Card_Width - overlapWidth));
            mainPlayer.setCurrentCard(localcard, i);
        }
    }
}

3. 可选:用画布裁剪兜底,确保不超出区域

如果担心布局计算有误差,可以在绘制卡牌时给Canvas添加裁剪区域,强制限制绘制范围:

private void DrawMainPlayerDeck(Canvas canvas) {
    // 保存当前画布状态
    canvas.save();
    // 裁剪到固定区域,超出部分不会被绘制
    canvas.clipRect(cardDisplayArea);

    Card localcard;
    int currentiteration = 0;
    Player mainPlayer = playerList.get(0);
    while (currentiteration < mainPlayer.decksize()) {
        localcard = mainPlayer.getCard(currentiteration);
        canvas.drawBitmap(localcard.getImage(context, Card_Width, Card_Height), localcard.getCurrent_X(), localcard.getCurrent_Y(), null);
        currentiteration++;
    }

    // 恢复画布状态,不影响其他元素绘制
    canvas.restore();
}

调试小技巧

你可以给固定区域绘制一个红色边框,方便确认区域是否正确:

// 在DrawMainPlayerDeck的canvas.save()之前添加
Paint borderPaint = new Paint();
borderPaint.setColor(Color.RED);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(2);
canvas.drawRect(cardDisplayArea, borderPaint);

这样调整后,所有卡牌都会被限制在你设定的高亮矩形类似的区域内,不会再被按钮遮挡啦!

内容的提问来源于stack exchange,提问作者Chetan Mehra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:03:27