flutterdartflame

Why Does the Object's Position Differ Between Adding to game and world?


Related: When adding an object in Flame, what criteria should be used to decide whether to add it to the world or to the game?

I have the following codes:

Add to game Code:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const FooApp());
}

class FooApp extends StatelessWidget {
  const FooApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: GameWidget.controlled(gameFactory: FooFlameGame.new),
    );
  }
}

class FooFlameGame extends FlameGame {
  late final CircleComponent _circle;

  @override
  Future<void> onLoad() async {
    super.onLoad();

    _circle = CircleComponent(
      position: Vector2(0, 0),
      radius: 44,
    );
    await add(_circle); // <-------
  }
}

Add to game Result:

enter image description here

Add to world Code:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const FooApp());
}

class FooApp extends StatelessWidget {
  const FooApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: GameWidget.controlled(gameFactory: FooFlameGame.new),
    );
  }
}

class FooFlameGame extends FlameGame {
  late final CircleComponent _circle;

  @override
  Future<void> onLoad() async {
    super.onLoad();

    _circle = CircleComponent(
      position: Vector2(0, 0),
      radius: 44,
    );
    await world.add(_circle); // <-------
  }
}

Add to world Result:

enter image description here

When I add the object to game, it is rendered in the top-left corner. However, when I add it to world, it is rendered in the center.

What could be causing this behavior? I am specifying _circle coordinates as (0, 0). Intuitively, I would expect it to always appear in the top-left corner.


Solution

  • That is because components added to the world will be rendered through the camera, which will translate everything to a different point of view.

    By default, the Flutter Canvas considers the top-left the origin, so when you are not using the camera, that is where the (0, 0) is.

    But the default Flame camera will translate everything so the origin is in the center of the screen. You can easily translate that back if desired by doing camera.translate(-size / 2).

    You can see more details about the difference between using the camera or not on this answer.