Files
flame/examples/lib/stories/components/look_at_example.dart
Lukas Klingsbo dbda37b81a refactor: Add new lint rules (#2477)
This PR adds the following lint rules to our list:

```
always_put_required_named_parameters_first
avoid_multiple_declarations_per_line
avoid_positional_boolean_parameters
avoid_returning_null_for_void
avoid_returning_this
avoid_unnecessary_containers
enable_null_safety
library_private_types_in_public_api
no_leading_underscores_for_library_prefixes
no_leading_underscores_for_local_identifiers
prefer_null_aware_method_calls
tighten_type_of_initializing_formals
unnecessary_late
use_setters_to_change_properties
```

And these rules were considered, and some changes were made according to
them as a clean-up, but in many places they didn't make sense
(`prefer_asserts_with_message` I would have included, but there were too
many places that needed to be changes):

```
collection_methods_unrelated_type
prefer_asserts_with_message
avoid_renaming_method_parameters
```
2023-04-13 19:42:00 +00:00

115 lines
3.3 KiB
Dart

import 'dart:math';
import 'package:flame/components.dart';
import 'package:flame/extensions.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/palette.dart';
import 'package:flame/sprite.dart';
import 'package:flutter/material.dart';
class LookAtExample extends FlameGame with TapDetector {
static const description = 'This example demonstrates how a component can be '
'made to look at a specific target using the lookAt method. Tap anywhere '
'to change the target point for both the choppers. '
'It also shows how nativeAngle can be used to make the component '
'oriented in the desired direction if the image is not facing the '
'correct direction.';
late SpriteAnimationComponent _chopper1;
late SpriteAnimationComponent _chopper2;
final CircleComponent _targetComponent = CircleComponent(
radius: 5,
anchor: Anchor.center,
paint: BasicPalette.black.paint(),
);
@override
Color backgroundColor() => const Color.fromARGB(255, 96, 145, 112);
@override
Future<void>? onLoad() async {
camera.viewport = FixedResolutionViewport(Vector2(640, 360));
final spriteSheet = SpriteSheet(
image: await images.load('animations/chopper.png'),
srcSize: Vector2.all(48),
);
_spawnChoppers(spriteSheet);
_spawnInfoText();
return super.onLoad();
}
@override
void onTapDown(TapDownInfo info) {
if (!_targetComponent.isMounted) {
add(_targetComponent);
}
_targetComponent.position = info.eventPosition.game;
_chopper1.lookAt(_targetComponent.absolutePosition);
_chopper2.lookAt(_targetComponent.absolutePosition);
super.onTapDown(info);
}
void _spawnChoppers(SpriteSheet spriteSheet) {
// Notice now the nativeAngle is set to pi because the chopper
// is facing in down/south direction in the original image.
add(
_chopper1 = SpriteAnimationComponent(
nativeAngle: pi,
size: Vector2.all(64),
anchor: Anchor.center,
animation: spriteSheet.createAnimation(row: 0, stepTime: 0.05),
position: Vector2(size.x * 0.3, size.y * 0.5),
),
);
// This chopper does not use correct nativeAngle, hence using
// lookAt on it results in the sprite pointing in incorrect
// direction visually.
add(
_chopper2 = SpriteAnimationComponent(
size: Vector2.all(64),
anchor: Anchor.center,
animation: spriteSheet.createAnimation(row: 0, stepTime: 0.05),
position: Vector2(size.x * 0.6, size.y * 0.5),
),
);
}
// Just displays some information. No functional contribution to the example.
void _spawnInfoText() {
final shaded = TextPaint(
style: TextStyle(
color: BasicPalette.white.color,
fontSize: 20.0,
shadows: const [
Shadow(offset: Offset(1, 1), blurRadius: 1),
],
),
);
add(
TextComponent(
text: 'nativeAngle = pi',
textRenderer: shaded,
anchor: Anchor.center,
position: _chopper1.absolutePosition + Vector2(0, -50),
),
);
add(
TextComponent(
text: 'nativeAngle = 0',
textRenderer: shaded,
anchor: Anchor.center,
position: _chopper2.absolutePosition + Vector2(0, -50),
),
);
}
}