我尝试使用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();
}
}
我尝试在控制器层设置优先级,但不起作用。
您的操纵杆已添加到位于世界下方的
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
代替。