Description
What happened?
I turned my device (physcial and emulator) (from portraint to landscape mode) and the render loop stops. This also means that there aren't any visual updates to the game anymore. This behavior seems to be the case when Flame is inside an OrientationBuilder widget.
What do you expect?
I expect that the render loop does NOT stop when I turn the device (rotate the screen).
Run the app, you see the render loop counter going up, both on screen and in the console. You can even toggle visibility of this. Rotate the screen. The render loop counter stops, the visibility toggling also doesn't work anymore.
How can we reproduce this?
Use the code below. Flame v1.29.0 was used.
What steps should take to fix this?
No response
Do have an example of where the bug occurs?
import 'dart:async';
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text('Flame Rotation Bug Test'),
backgroundColor: Colors.blue,
),
body: SafeArea(
child: OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? _buildPortraitLayout()
: _buildLandscapeLayout();
},
),
),
),
);
}
RotationTestGameWithButton game = RotationTestGameWithButton();
Widget _buildPortraitLayout() {
return Column(
children: [
Expanded(
flex: 1,
child: GameWidget(game: game),
),
Expanded(
flex: 1,
child: TestControlsContainer(game: game),
),
],
);
}
Widget _buildLandscapeLayout() {
return Row(
children: [
Expanded(
flex: 1,
child: GameWidget(game: game),
),
Expanded(
flex: 1,
child: TestControlsContainer(game: game),
),
],
);
}
}
class TestControlsContainer extends StatelessWidget {
final RotationTestGameWithButton game;
TestControlsContainer({required this.game});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Rotation Bug Test Controls',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => game.toggleTestVisibility(),
child: Text('Toggle Visibility'),
),
SizedBox(height: 10),
Text(
'Rotate device to test!\nWatch debug console for render counts.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 14),
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.all(16),
margin: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blue[50],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blue),
),
child: Text(
'Expected Bug:\n'
'1. Before rotation: render() runs continuously\n'
'2. After rotation: render() stops or runs only once\n'
'3. Toggle button may not work properly',
style: TextStyle(fontSize: 12),
),
),
],
),
);
}
}
class RotationTestGameWithButton extends FlameGame {
TestRenderComponent? _testComponent;
@override
Color backgroundColor() => const Color(0xFF222222);
@override
FutureOr<void> onLoad() async {
debugPrint('=== GAME ONLOAD ===');
final camera = CameraComponent(world: world);
camera.viewfinder.anchor = Anchor.topLeft;
camera.viewport.anchor = Anchor.topLeft;
await addAll([world, camera]);
_testComponent = TestRenderComponent();
world.add(_testComponent!);
debugPrint('=== GAME ONLOAD COMPLETE ===');
}
@override
void onGameResize(Vector2 size) {
debugPrint('=== GAME RESIZE: $size ===');
super.onGameResize(size);
_testComponent?.onParentResize(size);
}
void toggleTestVisibility() {
debugPrint('=== TOGGLE VISIBILITY CALLED ===');
_testComponent?.toggleVisibility();
}
}
class TestRenderComponent extends Component {
int renderCount = 0;
bool visible = true;
@override
void render(Canvas canvas) {
renderCount++;
debugPrint('TestRenderComponent.render() called #$renderCount, visible: $visible');
if (!visible) return;
final paint = Paint()..color = Colors.green;
final size = Vector2(100, 100);
canvas.drawRect(
Rect.fromLTWH(50, 50, size.x, size.y),
paint
);
final textStyle = TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
);
final textPainter = TextPainter(
text: TextSpan(text: 'Renders: $renderCount', style: textStyle),
textAlign: TextAlign.center,
textDirection: TextDirection.ltr,
);
textPainter.layout();
textPainter.paint(canvas, Offset(60, 170));
}
@override
void update(double dt) {
super.update(dt);
if (renderCount % 60 == 0 && renderCount > 0) {
debugPrint('TestRenderComponent.update() - renderCount: $renderCount');
}
}
void onParentResize(Vector2 newSize) {
debugPrint('TestRenderComponent: Parent resized to $newSize');
}
void toggleVisibility() {
visible = !visible;
debugPrint('TestRenderComponent: visibility toggled to $visible');
}
}
Execute in a terminal and put output into the code block below
Output of: flutter doctor -v
[√] Flutter (Channel stable, 3.27.1, on Microsoft Windows [Version 10.0.19045.5965], locale de-DE)
• Flutter version 3.27.1 on channel stable at D:\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 17025dd882 (6 months ago), 2024-12-17 03:23:09 +0900
• Engine revision cb4b5fff73
• Dart version 3.6.0
• DevTools version 2.40.2
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
• Android SDK at C:\Users\MyUserName\AppData\Local\Android\sdk
• Platform android-35, build-tools 35.0.0
• Java binary at: D:\Android Studio\jbr\bin\java
• Java version OpenJDK Runtime Environment (build 21.0.6+-13368085-b895.109)
• All Android licenses accepted.
[X] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[X] Visual Studio - develop Windows apps
X Visual Studio not installed; this is necessary to develop Windows apps.
Download at https://visualstudio.microsoft.com/downloads/.
Please install the "Desktop development with C++" workload, including all of its default components
[√] Android Studio (version 2024.3.2)
• Android Studio at D:\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.6+-13368085-b895.109)
[√] Connected device (2 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19045.5965]
• Edge (web) • edge • web-javascript • Microsoft Edge 134.0.3124.51
[√] Network resources
• All expected network resources are available.
Affected platforms
All
Other information
No response
Are you interested in working on a PR for this?
- I want to work on this