我有一个名为Obstruct的SpriteComponent。我在super方法中将优先级值设置为0。但是障碍组件是用更新方法重新生成的。当它退出屏幕时就会消失。当它再次出现时,优先级值将变为无效。我正在分享示例屏幕截图。
第一个img
第二个img
选手待在障碍物后面。GameOverPanel总是在后面。
@override
Future<void> onLoad() async {
add(ScreenHitbox());
add(gameRef.homeBackgroundParallaxComponent);
add(gameRef.homeBaseParallax);
add(gameRef.obstacleManager..priority = 0);
add(gameRef.playerManager..priority = 1);
add(gameRef.gameOverPanel..priority = 2);
}
@override
void update(double dt) {
super.update(dt);
gameRef.obstacleManager.updateObstacle(GameConst.gameSpeed * dt);
gameRef.playerManager.changePositionDown(value: GameConst.gravity * dt);
}
- 面板游戏
class GameOverPanel extends Component with HasGameRef<HopyBirdGame> {
GameOverPanel() : super(priority: 4);
@override
Future<void> onLoad() async {
add(GameOverText());
}
@override
void renderTree(Canvas canvas) {
if (gameRef.gameOver) {
super.renderTree(canvas);
}
}
}
class GameOverText extends SpriteComponent with HasGameRef<HopyBirdGame> {
GameOverText() : super(size: Vector2(300, 80), anchor: Anchor.center);
@override
Future<void>? onLoad() async {
sprite = await gameRef.loadSprite(Assets.gameOver.path);
position = Vector2(gameRef.screenWidth / 2, gameRef.screenHeight / 2);
return super.onLoad();
}
}
-障碍物
class Obstacle extends SpriteComponent
with HasGameRef<HopyBirdGame>, CollisionCallbacks {
final ObstacleType obstacleType;
Obstacle({
required this.obstacleType,
super.position,
super.priority,
}) : super(
size: Vector2(GameConst.obstacleWidth, GameConst.obstacleHeight),
anchor: Anchor.center,
);
Obstacle.empty({this.obstacleType = ObstacleType.empty});
@override
Future<void> onLoad() async {
switch (obstacleType) {
case ObstacleType.up:
sprite = await gameRef.loadSprite(
Assets.redPipeUp.path,
);
break;
case ObstacleType.down:
sprite = await gameRef.loadSprite(
Assets.redPipeDown.path,
);
break;
case ObstacleType.empty:
return;
}
add(RectangleHitbox());
}
}
class Obstacles extends Component with HasGameRef<HopyBirdGame> {
final Obstacle upObstacle;
final Obstacle downObstacle;
bool isCreateNextObstacles = true;
Obstacles({
required this.upObstacle,
required this.downObstacle,
super.priority,
});
@override
Future<void>? onLoad() {
upObstacle.priority = 1;
downObstacle.priority = 1;
createChildren();
return super.onLoad();
}
void createChildren() {
final children = [upObstacle, downObstacle];
addAll(children);
}
}
- 障碍物管理器
class ObstacleManager extends Component with HasGameRef<HopyBirdGame> {
ObstacleManager() : super(priority: 1);
ListQueue<Obstacles> history = ListQueue();
@override
Future<void> onLoad() async {
createObstacles();
}
void updateObstacle(double value) {
if (!gameRef.gameOver) {
if (history.isNotEmpty) {
history.last.upObstacle.position.x -= value;
history.last.downObstacle.position.x -= value;
if (history.last.upObstacle.position.x <= gameRef.screenWidth / 2) {
createObstacles();
final isThereAnyObstaclesOutsideScreen = history.any(
(element) =>
element.downObstacle.position.x <=
-(GameConst.obstacleWidth / 2),
);
if (isThereAnyObstaclesOutsideScreen) {
final obstaclesOutsideScreen = history
.lastWhere((element) => element.downObstacle.position.x <= 0);
obstaclesOutsideScreen.removeFromParent();
gameRef.remove(obstaclesOutsideScreen);
}
}
if (history.length >= 2) {
history.elementAt(history.length - 2).upObstacle.position.x -= value;
history.elementAt(history.length - 2).downObstacle.position.x -=
value;
}
}
}
}
void createObstacles() {
final obstaclesGap =
gameRef.screenHeight - gameRef.difficulty.spaceForPlayers;
final gapAboveTheObstacleOnScreen =
((2 * GameConst.obstacleHeight) - obstaclesGap) / 2;
final randomNumber = _randomGenerator(
min: -gameRef.difficulty.distanceAxisYToGoUpAndDown,
max: gameRef.difficulty.distanceAxisYToGoUpAndDown,
);
final axisYOfUpObstacle = (GameConst.obstacleHeight / 2) -
gapAboveTheObstacleOnScreen +
randomNumber;
final axisYOfDownObstacle = axisYOfUpObstacle +
GameConst.obstacleHeight +
gameRef.difficulty.spaceForPlayers;
final obstacles = Obstacles(
upObstacle: Obstacle(
obstacleType: ObstacleType.up,
position: Vector2(
gameRef.screenWidth + (GameConst.obstacleWidth / 2),
axisYOfUpObstacle,
),
),
downObstacle: Obstacle(
obstacleType: ObstacleType.down,
position: Vector2(
gameRef.screenWidth + (GameConst.obstacleWidth / 2),
axisYOfDownObstacle,
),
),
);
history.add(obstacles);
gameRef.add(obstacles);
}
double _randomGenerator({required double min, required double max}) {
final gap = (max - min).toInt();
return min + Random().nextInt(gap);
}
}
编辑:同样的问题也适用于面板游戏。
- 面板游戏
class GameOverPanel extends Component with HasGameRef<HopyBirdGame> {
GameOverPanel() : super();
@override
Future<void> onLoad() async {
add(GameOverText());
}
@override
void renderTree(Canvas canvas) {
if (gameRef.gameOver) {
super.renderTree(canvas);
}
}
}
class GameOverText extends SpriteComponent with HasGameRef<HopyBirdGame> {
GameOverText()
: super(
size: Vector2(300, 80),
anchor: Anchor.center,
);
@override
Future<void>? onLoad() async {
sprite = await gameRef.loadSprite(Assets.gameOver.path);
position = Vector2(gameRef.screenWidth / 2, gameRef.screenHeight / 2);
return super.onLoad();
}
}
同样,第一个作业是在火焰游戏类中完成的。
我猜(因为ObstacleManager
的代码不存在(您是在将障碍物从ObstacleManager
直接添加到游戏的组件树中,而不是将priority
添加到实际的Obstacle
组件中。
如果不是这样,请使用ObstacleManager
的代码更新问题。
编辑:代码上传后。当组件不是作为子级添加到管理器类,而是作为gameRef
添加时,将优先级赋予管理器类是没有帮助的。由于问题中不包括玩家管理者类,您必须将Obstacles
设置为优先级-1,或者必须将玩家优先级设置为1(障碍物默认为0(。
gameRef.add(obstacles..priority = -1);
这将使障碍物位于背景后面,因此您还必须更改背景视差:
add(gameRef.homeBackgroundParallaxComponent..priority = -3);
add(gameRef.homeBaseParallax..priority = -2);
因此,最好将玩家的优先级设置为1,将其添加到游戏中,因为这样你就不必更改所有其他类。