mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 10:38:17 +08:00
@ -27,7 +27,7 @@ Currently, Forge2D supports the following joints:
|
||||
- [`PulleyJoint`](#pulleyjoint)
|
||||
- [`RevoluteJoint`](#revolutejoint)
|
||||
- [`RopeJoint`](#ropejoint)
|
||||
- WeldJoint
|
||||
- [`WeldJoint`](#weldjoint)
|
||||
- WheelJoint
|
||||
|
||||
|
||||
@ -599,3 +599,38 @@ will have no effect.
|
||||
The joint assumes that the maximum length doesn't change during simulation.
|
||||
See `DistanceJoint` if you want to dynamically control length.
|
||||
```
|
||||
|
||||
|
||||
### `WeldJoint`
|
||||
|
||||
A `WeldJoint` is used to restrict all relative motion between two bodies, effectively joining them
|
||||
together.
|
||||
|
||||
`WeldJointDef` requires two bodies that will be connected, and a world anchor:
|
||||
|
||||
```dart
|
||||
final weldJointDef = WeldJointDef()
|
||||
..initialize(bodyA, bodyB, anchor);
|
||||
|
||||
world.createJoint(WeldJoint(weldJointDef));
|
||||
```
|
||||
|
||||
```{flutter-app}
|
||||
:sources: ../../examples
|
||||
:page: weld_joint
|
||||
:subfolder: stories/bridge_libraries/forge2d/joints
|
||||
:show: code popup
|
||||
```
|
||||
|
||||
- `bodyA`, `bodyB`: Two bodies that will be connected
|
||||
|
||||
- `anchor`: Anchor point in world coordinates, at which two bodies will be welded together
|
||||
to 0, the higher the value, the less springy the joint becomes.
|
||||
|
||||
|
||||
#### Breakable Bodies and WeldJoint
|
||||
|
||||
Since the Forge2D constraint solver is iterative, joints are somewhat flexible. This means that the
|
||||
bodies connected by a WeldJoint may bend slightly. If you want to simulate a breakable body, it's
|
||||
better to create a single body with multiple fixtures. When the body breaks, you can destroy a
|
||||
fixture and recreate it on a new body instead of relying on a `WeldJoint`.
|
||||
|
||||
@ -16,6 +16,7 @@ import 'package:examples/stories/bridge_libraries/forge2d/joints/prismatic_joint
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/pulley_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/revolute_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/rope_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/weld_joint.dart';
|
||||
import 'package:examples/stories/camera_and_viewport/camera_and_viewport.dart';
|
||||
import 'package:examples/stories/collision_detection/collision_detection.dart';
|
||||
import 'package:examples/stories/components/components.dart';
|
||||
@ -50,6 +51,7 @@ void main() {
|
||||
'prismatic_joint': PrismaticJointExample.new,
|
||||
'revolute_joint': RevoluteJointExample.new,
|
||||
'rope_joint': RopeJointExample.new,
|
||||
'weld_joint': WeldJointExample.new,
|
||||
};
|
||||
final game = routes[page]?.call();
|
||||
if (game != null) {
|
||||
|
||||
@ -17,6 +17,7 @@ import 'package:examples/stories/bridge_libraries/forge2d/joints/prismatic_joint
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/pulley_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/revolute_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/rope_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/weld_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/raycast_example.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/revolute_joint_with_motor_example.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/sprite_body_example.dart';
|
||||
@ -166,5 +167,11 @@ void addJointsStories(Dashbook dashbook) {
|
||||
(DashbookContext ctx) => GameWidget(game: RopeJointExample()),
|
||||
codeLink: link('rope_joint.dart'),
|
||||
info: RopeJointExample.description,
|
||||
)
|
||||
.add(
|
||||
'WeldJoint',
|
||||
(DashbookContext ctx) => GameWidget(game: WeldJointExample()),
|
||||
codeLink: link('weld_joint.dart'),
|
||||
info: WeldJointExample.description,
|
||||
);
|
||||
}
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/utils/balls.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/utils/boxes.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WeldJointExample extends Forge2DGame with TapDetector {
|
||||
static const description = '''
|
||||
This example shows how to use a `WeldJoint`. Tap the screen to add a
|
||||
ball to test the bridge built using a `WeldJoint`
|
||||
''';
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
super.onLoad();
|
||||
|
||||
const pillarHeight = 20.0;
|
||||
final leftPillar = Box(
|
||||
startPosition: Vector2(10, size.y - pillarHeight / 2),
|
||||
width: 5,
|
||||
height: pillarHeight,
|
||||
bodyType: BodyType.static,
|
||||
color: Colors.white,
|
||||
);
|
||||
final rightPillar = Box(
|
||||
startPosition: Vector2(size.x - 10, size.y - pillarHeight / 2),
|
||||
width: 5,
|
||||
height: pillarHeight,
|
||||
bodyType: BodyType.static,
|
||||
color: Colors.white,
|
||||
);
|
||||
|
||||
addAll([leftPillar, rightPillar]);
|
||||
|
||||
createBridge(size.y - pillarHeight);
|
||||
}
|
||||
|
||||
Future<void> createBridge(double positionY) async {
|
||||
const sectionsCount = 10;
|
||||
final sectionWidth = (size.x / sectionsCount).ceilToDouble();
|
||||
Body? prevSection;
|
||||
|
||||
for (var i = 0; i < sectionsCount; i++) {
|
||||
final section = Box(
|
||||
startPosition: Vector2(sectionWidth * i, positionY),
|
||||
width: sectionWidth,
|
||||
height: 1,
|
||||
);
|
||||
await add(section);
|
||||
|
||||
if (prevSection != null) {
|
||||
createJoint(
|
||||
prevSection,
|
||||
section.body,
|
||||
Vector2(sectionWidth * i + sectionWidth, positionY),
|
||||
);
|
||||
}
|
||||
|
||||
prevSection = section.body;
|
||||
}
|
||||
}
|
||||
|
||||
void createJoint(Body first, Body second, Vector2 anchor) {
|
||||
final weldJointDef = WeldJointDef()..initialize(first, second, anchor);
|
||||
|
||||
world.createJoint(WeldJoint(weldJointDef));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onTapDown(TapDownInfo info) async {
|
||||
super.onTapDown(info);
|
||||
final ball = Ball(info.eventPosition.game, radius: 5);
|
||||
add(ball);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,9 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/events.dart';
|
||||
import 'package:flame/extensions.dart';
|
||||
import 'package:flame/palette.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
|
||||
class Box extends BodyComponent {
|
||||
@ -13,7 +17,16 @@ class Box extends BodyComponent {
|
||||
required this.width,
|
||||
required this.height,
|
||||
this.bodyType = BodyType.dynamic,
|
||||
});
|
||||
Color? color,
|
||||
}) {
|
||||
if (color != null) {
|
||||
paint = PaletteEntry(color).paint();
|
||||
} else {
|
||||
paint = randomPaint();
|
||||
}
|
||||
}
|
||||
|
||||
Paint randomPaint() => PaintExtension.random(withAlpha: 0.9, base: 100);
|
||||
|
||||
@override
|
||||
Body createBody() {
|
||||
|
||||
Reference in New Issue
Block a user