Flutter Flame Controller 移动设备操纵杆未显示在图层前面

问题描述 投票:0回答:1

我尝试使用Flutter和Flame制作手机游戏,但即使我将优先级设置为10并将地图优先级设置为10以下,控制器也没有显示在图层的前面。

这是截图:

这里是操纵杆代码:

import 'dart:async';
import 'dart:io';

import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flutter/painting.dart';
import 'package:pixel_adventure/components/player.dart';
import 'package:pixel_adventure/components/level.dart';

class PixelAdventure extends FlameGame
    with HasKeyboardHandlerComponents, DragCallbacks {
  final Player _player = Player();

  late final CameraComponent _cam;
  late final JoystickComponent _joystick;

  @override
  Color backgroundColor() => const Color(0xFF211F30);

  @override
  FutureOr<void> onLoad() async {
    await images.loadAllImages();

    final world = Level(levelName: 'level-01', player: _player);
    _cam = CameraComponent.withFixedResolution(
      world: world,
      width: 640,
      height: 360,
    );

    _cam.viewfinder.anchor = Anchor.topLeft;

    addAll([_cam, world]);

    if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
      _addJoystick();
    }

    return super.onLoad();
  }

  @override
  void update(double dt) {
    if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
      _updateJoystick();
    }
    super.update(dt);
  }

  void _addJoystick() {
    _joystick = JoystickComponent(
      priority: 10,
      knob: SpriteComponent(
        sprite: Sprite(
          images.fromCache('HUD/knob.png'),
        ),
      ),
      background: SpriteComponent(
        sprite: Sprite(
          images.fromCache('HUD/joystick.png'),
        ),
      ),
      margin: const EdgeInsets.only(left: 32, bottom: 32),
    );

    add(_joystick);
  }

  void _updateJoystick() {
    switch (_joystick.direction) {
      case JoystickDirection.left:
      case JoystickDirection.downLeft:
      case JoystickDirection.upLeft:
        _player.horizontalMovement = -1;
        break;
      case JoystickDirection.right:
      case JoystickDirection.downRight:
      case JoystickDirection.upRight:
        _player.horizontalMovement = 1;
        break;
      default:
        _player.horizontalMovement = 0;
        break;
    }
  }
}

还有这个级别的地图

import 'dart:async';

import 'package:flame/components.dart';
import 'package:flame_tiled/flame_tiled.dart';
import 'package:pixel_adventure/components/background_tile.dart';
import 'package:pixel_adventure/components/collision_block.dart';
import 'package:pixel_adventure/components/player.dart';
import 'package:pixel_adventure/pixel_adventure.dart';

class Level extends World with HasGameRef<PixelAdventure> {
  final String levelName;
  final Player player;

  Level({required this.player, required this.levelName});

  late TiledComponent level;
  List<CollisionBlock> collisionBlocks = [];

  @override
  FutureOr<void> onLoad() async {
    priority = -1;
    level = await TiledComponent.load(
      '$levelName.tmx',
      Vector2.all(16),
    );

    add(level);

    _scrollingObject();
    _spawningObject();
    _addCollisions();

    player.collisionBlocks = collisionBlocks;
    return super.onLoad();
  }

  void _scrollingObject() {
    final Layer? backgroundLayer = level.tileMap.getLayer('background');
    const int tileSize = 65;
    final int numTilesY = (game.size.y / tileSize).floor();
    final int numTilesX = (game.size.x / tileSize).floor();
    if (backgroundLayer != null) {
      final backgroundColor =
          backgroundLayer.properties.getValue('BackgroundColor');

      for (double y = 0; y < numTilesY; y++) {
        for (double x = 0; x < numTilesX; x++) {
          final backgroundTile = BackgroundTile(
              color: backgroundColor ?? 'Gray',
              position: Vector2(x * tileSize, y * tileSize - tileSize));
          add(backgroundTile);
        }
      }
    }
  }

  void _spawningObject() {
    final ObjectGroup? spawnPointsLayer =
        level.tileMap.getLayer<ObjectGroup>('Spawnpoints');
    if (spawnPointsLayer != null) {
      for (final TiledObject spawnPoint in spawnPointsLayer.objects) {
        switch (spawnPoint.class_) {
          case 'Player':
            player.position = Vector2(
              spawnPoint.x,
              spawnPoint.y,
            );
            add(player);
            break;
          default:
        }
      }
    }
  }

  void _addCollisions() {
    final ObjectGroup? collisionsLayer =
        level.tileMap.getLayer<ObjectGroup>('Collisions');
    if (collisionsLayer != null) {
      for (final TiledObject collisions in collisionsLayer.objects) {
        switch (collisions.class_) {
          case 'Platform':
            final platform = CollisionBlock(
              position: Vector2(collisions.x, collisions.y),
              size: Vector2(collisions.width, collisions.height),
              isPlatform: true,
            );
            collisionBlocks.add(platform);
            add(platform);
            break;
          default:
            final block = CollisionBlock(
              position: Vector2(collisions.x, collisions.y),
              size: Vector2(collisions.width, collisions.height),
            );
            collisionBlocks.add(block);
            add(block);
        }
      }
    }
  }
}

还有这个灰色背景

import 'dart:async';

import 'package:flame/components.dart';
import 'package:pixel_adventure/pixel_adventure.dart';

class BackgroundTile extends SpriteComponent with HasGameRef<PixelAdventure> {
  final String color;
  BackgroundTile({this.color = 'Gray', position}) : super(position: position);

  @override
  FutureOr<void> onLoad() {
    priority = -2;
    size = Vector2.all(65.6);
    sprite = Sprite(
      game.images.fromCache('Background/$color.png'),
    );
    super.onLoad();
  }
}

我尝试在控制器层设置优先级,但不起作用。

flutter dart controller flame
1个回答
0
投票

您的操纵杆已添加到位于世界下方的

game
。 仅当您在同级组件之间设置
priority
时,设置它才会产生影响。我会将操纵杆添加到视口,以确保它被视为 HUD 并且始终可见。

camera.viewport.add(joystick);

您的代码中还存在一些其他问题,您有两个摄像头(

FlameGame
已经内置了一个)。 执行此操作以使用内置摄像头:

  @override
  FutureOr<void> onLoad() async {
    await images.loadAllImages();

    camera = CameraComponent.withFixedResolution(
      world: world,
      width: 640,
      height: 360,
    );
    world = Level(levelName: 'level-01', player: _player);

    camera.viewfinder.anchor = Anchor.topLeft;

    if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
      _addJoystick(); // Make sure this adds to `camera.viewport` instead.
    }

    return super.onLoad();
  }

并删除所有对

_cam
的引用并使用
camera
代替。

© www.soinside.com 2019 - 2024. All rights reserved.