首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GPU Jank生成无限二维地形

GPU Jank生成无限二维地形
EN

Stack Overflow用户
提问于 2022-09-05 08:33:46
回答 2查看 41关注 0票数 0

我在做一个有无限模式的跑步游戏。所以,我得大约每1s生成一个地形。它有一些滞后,我的LG Q9 1,我检查了性能,它似乎有一些问题的栅格线程。

我试过三星Galaxy 10的游戏,它有更好的gpu,显示更少的门(但它还是有门卫)。

我在这里添加了我的代码。有什么更好的方法来提高表现吗?

代码语言:javascript
复制
class MyGame extends FlameGame {
  final Grid grid = Grid();
  final EndlessMap endlessMap = EndlessMap();
  final Runner runner = Runner();

  double speed = 100.0;

  @override
  Future<void>? onLoad() {
    add(grid);
    add(endlessMap);
    add(runner);
    return super.onLoad();
  }
}

/// Camera follows the runner.
class Runner extends PositionComponent with HasGameRef<MyGame> {
  @override
  Future<void>? onLoad() {
    gameRef.camera.followComponent(this);
    return super.onLoad();
  }

  @override
  void update(double dt) {
    x += gameRef.speed * dt;
    super.update(dt);
  }
}

/// Set the size of tile and grid
class Grid extends Component with HasGameRef<MyGame> {
  late int rows = 10;
  late int columns;
  late int mapColumns;
  late double tileSize;

  @override
  void onGameResize(Vector2 size) {
    tileSize = (size.y / rows).floorToDouble();
    columns = (size.x / tileSize).ceil();
    mapColumns = columns + 2;
    super.onGameResize(size);
  }
}

/// Generate terrains endlessly
class EndlessMap extends PositionComponent with HasGameRef<MyGame> {
  late final Sprite terrainSprite;
  late final List<SpriteComponent> terrainSpritePool;

  int firstTerrainIndex = 0;

  // Init terrain sprite
  @override
  Future<void> onLoad() async {
    terrainSprite = Sprite(
      await Flame.images.load('terrains.png'),
      srcPosition: Vector2(4.0, 0.0),
      srcSize: Vector2(32.0, 32.0 * 10),
    );

    terrainSpritePool = List.generate(
      gameRef.grid.mapColumns,
      (index) => SpriteComponent(sprite: terrainSprite),
    );

    for (var i = 0; i < terrainSpritePool.length; i++) {
      terrainSpritePool[i].size.x = gameRef.grid.tileSize;
      terrainSpritePool[i].position = Vector2(
        i * gameRef.grid.tileSize,
        gameRef.grid.tileSize,
      );
      add(terrainSpritePool[i]);
    }

    return super.onLoad();
  }

  @override
  void update(double dt) {
    final dx = gameRef.speed * dt;
    final lastTerrainIndex = firstTerrainIndex == 0
        ? terrainSpritePool.length - 1
        : firstTerrainIndex - 1;

    // When the first terrain is behind the camera,
    if (terrainSpritePool[firstTerrainIndex].position.x +
            gameRef.grid.tileSize <=
        gameRef.camera.position.x + dx) {
      // Move the first terrain to the end
      terrainSpritePool[firstTerrainIndex].size.x = gameRef.grid.tileSize;
      terrainSpritePool[firstTerrainIndex].position = Vector2(
        terrainSpritePool[lastTerrainIndex].position.x + gameRef.grid.tileSize,
        gameRef.grid.tileSize,
      );

      firstTerrainIndex = (firstTerrainIndex + 1) % terrainSpritePool.length;
    }

    super.update(dx);
  }
}

您可以在github中找到完整的代码。

2022.09.12

看来我的手机(LG Q9 One)有一个坏的gpu来正常运行它的问题。我删除了所有的代码,除了移动相机,它仍然显示的是门卫。

EN

回答 2

Stack Overflow用户

发布于 2022-09-05 08:54:37

为了减少着色器编译和顺利运行动画,官方颤动网站上有一篇关于解决方案希望的文章。

票数 0
EN

Stack Overflow用户

发布于 2022-09-08 19:21:28

不要在update方法中创建新对象。所以当你在做:

代码语言:javascript
复制
terrainSpritePool[firstTerrainIndex].position = Vector2(
  terrainSpritePool[lastTerrainIndex].position.x + gameRef.grid.tileSize,
  gameRef.grid.tileSize,
);

由于SpriteComponent已经有了一个Vector2,所以可以像这样重用它:

代码语言:javascript
复制
terrainSpritePool[firstTerrainIndex].position.setValues(
  terrainSpritePool[lastTerrainIndex].position.x + gameRef.grid.tileSize,
  gameRef.grid.tileSize,
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73606617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档