flame-engine / flame

A Flutter based game engine.
https://flame-engine.org
MIT License
9.29k stars 913 forks source link

Flame text-box not rendering if render() or update() defined in BaseGame subclass. #619

Closed zacharyblasczyk closed 3 years ago

zacharyblasczyk commented 3 years ago

Description

MyTextBox class defined in documentation not rendering if BaseGame Subclass has either render() or update() function defined.

Development environment

Flame version: ^1.0.0-rc5

Flutter doctor:

zb3119@mbp flame-text-box % flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale en-US)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.52.1)
[✓] Connected device (1 available)

• No issues found!

Runtime

This issue is related to running on which platform? (Select all that apply)

Minimal reproducible code (Required for bugs)

Include a minimal code that reproduces the problem add it inline using code block markdown, or a link to Github repository: Link to sample issue repo with 5 scenarios defined to be uncommented one at a time: zb3119/flame-text-box.

Example "working" code: Displays MyTextBox

class BoxCount extends BaseGame {

  //Shows in bottom left if render() and update() are commented out
  @override
  Future<void> onLoad() async {
    add(MyTextBox(
      'Example Text',
    )
      ..anchor = Anchor.bottomLeft
      ..y = size.y);
  }
}

Example issue code:

class BoxCount extends BaseGame {

  //Shows in bottom left if render() and update() are commented out
  @override
  Future<void> onLoad() async {
    add(MyTextBox(
      'Example Text',
    )
      ..anchor = Anchor.bottomLeft
      ..y = size.y);
  }

  //... Scenario's 1-4 in link

  // Begin Scenario 5
  // Uncomment to break MyTextBox from onLoad()
  // Draws green canvas and Pink Text Box without words in upper left
  void render(Canvas canvas) {
    // Green Screen
    Rect bgRect = Rect.fromLTWH(0, 0, size.x, size.y);
    Paint bgPaint = Paint();
    bgPaint.color = Color(0xff0ff000);
    canvas.drawRect(bgRect, bgPaint);
    // textbox test2
    MyTextBox mtb = MyTextBox("Example Text");
    mtb.drawBackground(canvas);
    // Draws in upper left hand corner, but no text.
  }
  // End Scenario 5
}
lig commented 3 years ago

This is BaseGame.render implementation and docs

  /// This implementation of render basically calls [renderComponent] for every component, making sure the canvas is reset for each one.
  ///
  /// You can override it further to add more custom behaviour.
  /// Beware of however you are rendering components if not using this; you must be careful to save and restore the canvas to avoid components messing up with each other.
  @override
  @mustCallSuper
  void render(Canvas canvas) {
    canvas.save();
    components.forEach((comp) => renderComponent(canvas, comp));
    canvas.restore();
  }

I guess you need to do the same job it does saving/restoring canvas or call super.render but I'm not exactly sure.

erickzanardo commented 3 years ago

You render method on your base game class is not calling super, you must call super on that method otherwise the rendering of components will not work.