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

Android Java中如何重复Bitmap?游戏背景横向重复实现求助

搞定Android平台游戏横向循环滚动背景的小技巧

嘿,老兄!看你在做类似马里奥的Android平台游戏,卡在横向循环滚动背景的问题上了是吧?我来给你捋捋怎么搞定这个事儿~

核心问题拆解

你现在的做法是每次draw都给bgSrcX累加20,但这样下去很快就会超出Bitmap的宽度,背景就会出现空白或者消失。而且你提到Bitmap太大,只画屏幕一半区域——其实咱们的核心需求是让背景无缝循环滚动,同时只绘制屏幕可见的部分,省性能。

具体实现步骤

1. 先把关键变量理清楚

首先得有几个变量跟踪背景状态,别用数组啦,单个变量更清晰:

// 你的超大背景Bitmap
private Bitmap bgBitmap;
// 背景在X轴的滚动偏移量
private float bgScrollOffset = 0;
// 屏幕宽度,用来确定要画多大区域
private int screenWidth;
// 背景Bitmap的实际宽度
private int bgWidth;
// 滚动速度,你之前用的20,这里可以随便调
private final int SCROLL_SPEED = 20;

2. 提前获取屏幕宽度

在View的onSizeChanged方法里拿屏幕宽度,不用每次draw都算:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    screenWidth = w;
    if (bgBitmap != null) {
        bgWidth = bgBitmap.getWidth();
    }
}

3. 重写draw方法,实现循环滚动

这是最关键的部分,咱们要处理偏移量的重置,还要只画屏幕可见的区域:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (bgBitmap == null) return;

    // 更新滚动偏移量
    bgScrollOffset += SCROLL_SPEED;
    
    // 重点!当偏移量超过背景宽度时,取模重置,实现无缝循环
    bgScrollOffset %= bgWidth;

    // 先画第一部分背景:从当前偏移量到背景末尾的区域
    int srcStartX = (int) bgScrollOffset;
    int drawWidth = bgWidth - srcStartX;
    canvas.drawBitmap(bgBitmap,
        new Rect(srcStartX, 0, bgWidth, bgBitmap.getHeight()),
        new Rect(0, 0, drawWidth, getHeight()),
        null);

    // 如果第一部分不够填满屏幕,就从背景开头补剩下的部分
    if (drawWidth < screenWidth) {
        canvas.drawBitmap(bgBitmap,
            new Rect(0, 0, screenWidth - drawWidth, bgBitmap.getHeight()),
            new Rect(drawWidth, 0, screenWidth, getHeight()),
            null);
    }

    // 调用invalidate让View持续重绘,实现滚动效果
    invalidate();
}

4. 为啥这么做?

  • 用%= bgWidth来重置偏移量,相当于让背景“绕回去”,不会出现空白;
  • 用Rect裁剪Bitmap的源区域和目标区域,只画屏幕上能看到的部分,完美解决你说的“Bitmap太大只画屏幕区域”的需求,性能拉满;
  • 分两部分绘制是为了处理背景末尾和开头衔接的情况,保证滚动时不会有断层。

额外的小优化

  • 如果你的背景是由小瓷砖(Tile)组成的,其实可以用BitmapShader加TileMode.REPEAT来实现,更高效,但如果是单张大Bitmap,上面的方法就足够了;
  • 可以把滚动速度和帧率绑定,比如用Choreographer,这样在不同设备上滚动速度更一致;
  • 记得在View销毁时回收Bitmap,别搞内存泄漏:
@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    if (bgBitmap != null && !bgBitmap.isRecycled()) {
        bgBitmap.recycle();
        bgBitmap = null;
    }
}

这样改完,你的背景就能像马里奥里那样无限循环横向滚动啦,而且性能也没问题~

内容的提问来源于stack exchange,提问作者Yekta Sarıoğlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:41:25