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

LibGDX中基于Actor类实现飞船无限水平滚动的问题

问题解决:保持Actor与Sprite坐标一致实现飞船水平循环滚动

核心问题分析

你的代码存在三个关键问题导致效果异常:

  1. Spaceship作为Actor未设置尺寸,导致无法通过getRight()、getWidth()判断飞船边界位置;
  2. 位置触发条件错误,仅当飞船完全移出屏幕右侧才执行重置,不符合“部分消失即触发”的需求;
  3. 绘制逻辑遗漏:Spaceship的draw方法未执行Sprite绘制,且SpaceshipLayer未调用父类draw方法,导致飞船无法正常渲染。

修改后的完整代码实现

1. 修正Spaceship类(同步Actor与Sprite坐标,设置正确尺寸)

class Spaceship extends Actor {
    Sprite sprite;
    
    public Spaceship(Texture texture) {
        sprite = new Sprite(texture);
        // 同步Actor尺寸与Sprite一致,确保边界判断有效
        setSize(sprite.getWidth(), sprite.getHeight());
        // 初始化坐标同步
        syncSpritePosition();
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        syncSpritePosition();
        sprite.draw(batch, parentAlpha); // 必须执行Sprite绘制
    }

    // 封装坐标同步方法,确保Actor与Sprite位置始终一致
    private void syncSpritePosition() {
        sprite.setPosition(getX(), getY());
    }

    // 可选优化:重写位置设置方法,实时同步Sprite,避免每次draw重复设置
    @Override
    public void setX(float x) {
        super.setX(x);
        sprite.setX(x);
    }

    @Override
    public void setY(float y) {
        super.setY(y);
        sprite.setY(y);
    }
}

2. 修正SpaceshipLayer类(实现两种循环滚动逻辑)

根据你的需求,提供两种实现方案:

方案A:平滑无限滚动(移出右屏的部分从左屏显示)

适合无缝循环的视觉效果:

class SpaceshipLayer extends Group {
    Spaceship spaceship;
    float screenWidth;

    public SpaceshipLayer() {
        // 初始化飞船(此处需传入Texture实例,示例省略)
        spaceship = new Spaceship(yourTexture);
        addActor(spaceship);
        // 获取屏幕宽度
        screenWidth = Gdx.graphics.getWidth();
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha); // 必须调用父方法,否则Actor不会被绘制
        if (isRightKeyPressed) {
            spaceship.moveBy(5, 0);
            // 当飞船右边缘超出屏幕右侧时,循环到左侧
            if (spaceship.getRight() > screenWidth) {
                spaceship.setX(spaceship.getX() - screenWidth);
            }
        }
    }
}
方案B:部分移出即重置到左屏起始位置

适合直接跳转的循环逻辑:

class SpaceshipLayer extends Group {
    Spaceship spaceship;
    float screenWidth;

    public SpaceshipLayer() {
        spaceship = new Spaceship(yourTexture);
        addActor(spaceship);
        screenWidth = Gdx.graphics.getWidth();
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        if (isRightKeyPressed) {
            spaceship.moveBy(5, 0);
            // 只要飞船有部分移出右屏,就重置到左边界
            if (spaceship.getRight() > screenWidth) {
                spaceship.setX(0);
            }
        }
    }
}

3. Main类无需修改,确保Stage正常渲染即可

class Main implements Screen {
    SpaceshipLayer spaceshipLayer;
    Stage stage;
    
    public Main() {
        stage = new Stage();
        spaceshipLayer = new SpaceshipLayer();
        stage.addActor(spaceshipLayer);
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.act(delta);
        stage.draw();
    }

    // 实现Screen接口的其他方法(resize、show、hide等)
    ...
}

关键说明

  • 必须为Spaceship设置尺寸:Actor默认宽高为0,只有同步Sprite尺寸后,getRight()等边界方法才能正确工作;
  • 坐标同步:通过syncSpritePosition()方法或重写setX/setY,确保Actor与Sprite的坐标始终一致,满足你用Actor坐标处理碰撞的需求;
  • 渲染逻辑:Group的draw方法必须调用super.draw,否则内部的Actor不会被绘制;Spaceship的draw方法必须执行sprite.draw,否则飞船无法显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:37:03