mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 03:15:43 +08:00
docs: PrismaticJoint docs and example (#2470)
PrismaticJoint example and documentation
This commit is contained in:
@ -23,7 +23,7 @@ Currently, Forge2D supports the following joints:
|
||||
- GearJoint
|
||||
- [`MotorJoint`](#motorjoint)
|
||||
- [`MouseJoint`](#mousejoint)
|
||||
- PrismaticJoint
|
||||
- [`PrismaticJoint`] (#prismaticjoint)
|
||||
- [`PulleyJoint`](#pulleyjoint)
|
||||
- [`RevoluteJoint`](#revolutejoint)
|
||||
- RopeJoint
|
||||
@ -274,6 +274,103 @@ final mouseJointDef = MouseJointDef()
|
||||
initially.
|
||||
|
||||
|
||||
### `PrismaticJoint`
|
||||
|
||||
The `PrismaticJoint` provides a single degree of freedom, allowing for a relative translation of two
|
||||
bodies along an axis fixed in bodyA. Relative rotation is prevented.
|
||||
|
||||
`PrismaticJointDef` requires defining a line of motion using an axis and an anchor point.
|
||||
The definition uses local anchor points and a local axis so that the initial configuration
|
||||
can violate the constraint slightly.
|
||||
|
||||
The joint translation is zero when the local anchor points coincide in world space.
|
||||
Using local anchors and a local axis helps when saving and loading a game.
|
||||
|
||||
```{warning}
|
||||
At least one body should by dynamic with a non-fixed rotation.
|
||||
```
|
||||
|
||||
The `PrismaticJoint` definition is similar to the [`RevoluteJoint`](#revolutejoint) definition, but
|
||||
instead of rotation, it uses translation.
|
||||
|
||||
```{dart}
|
||||
final prismaticJointDef = PrismaticJointDef()
|
||||
..initialize(
|
||||
dynamicBody,
|
||||
groundBody,
|
||||
dynamicBody.worldCenter,
|
||||
Vector2(1, 0),
|
||||
)
|
||||
```
|
||||
|
||||
```{flutter-app}
|
||||
:sources: ../../examples
|
||||
:page: prismatic_joint
|
||||
:subfolder: stories/bridge_libraries/forge2d/joints
|
||||
:show: code popup
|
||||
```
|
||||
|
||||
- `b1`, `b2`: Bodies connected by the joint.
|
||||
- `anchor`: World anchor point, to put the axis through. Usually the center of the first body.
|
||||
- `axis`: World translation axis, along which the translation will be fixed.
|
||||
|
||||
In some cases you might wish to control the range of motion. For this, the `PrismaticJointDef` has
|
||||
optional parameters that allow you to simulate a joint limit and/or a motor.
|
||||
|
||||
|
||||
#### Prismatic Joint Limit
|
||||
|
||||
You can limit the relative rotation with a joint limit that specifies a lower and upper translation.
|
||||
|
||||
```dart
|
||||
jointDef
|
||||
..enableLimit = true
|
||||
..lowerTranslation = -20
|
||||
..upperTranslation = 20;
|
||||
```
|
||||
|
||||
- `enableLimit`: Set to true to enable translation limits
|
||||
- `lowerTranslation`: The lower translation limit in meters
|
||||
- `upperTranslation`: The upper translation limit in meters
|
||||
|
||||
You change the limits after the joint was created with this method:
|
||||
|
||||
```dart
|
||||
prismaticJoint.setLimits(-10, 10);
|
||||
```
|
||||
|
||||
|
||||
#### Prismatic Joint Motor
|
||||
|
||||
You can use a motor to drive the motion or to model joint friction. A maximum motor force is
|
||||
provided so that infinite forces are not generated.
|
||||
|
||||
```dart
|
||||
jointDef
|
||||
..enableMotor = true
|
||||
..motorSpeed = 1
|
||||
..maxMotorForce = 100;
|
||||
```
|
||||
|
||||
- `enableMotor`: Set to true to enable the motor
|
||||
- `motorSpeed`: The desired motor speed in radians per second
|
||||
- `maxMotorForce`: The maximum motor torque used to achieve the desired motor speed in N-m.
|
||||
|
||||
You change the motor's speed and force after the joint was created using these methods:
|
||||
|
||||
```dart
|
||||
prismaticJoint.setMotorSpeed(2);
|
||||
prismaticJoint.setMaxMotorForce(200);
|
||||
```
|
||||
|
||||
Also, you can get the joint angle and speed using the following methods:
|
||||
|
||||
```dart
|
||||
prismaticJoint.getJointTranslation();
|
||||
prismaticJoint.getJointSpeed();
|
||||
```
|
||||
|
||||
|
||||
### `PulleyJoint`
|
||||
|
||||
A `PulleyJoint` is used to create an idealized pulley. The pulley connects two bodies to the ground
|
||||
@ -366,7 +463,7 @@ In some cases you might wish to control the joint angle. For this, the `Revolute
|
||||
optional parameters that allow you to simulate a joint limit and/or a motor.
|
||||
|
||||
|
||||
#### Joint Limit
|
||||
#### Revolute Joint Limit
|
||||
|
||||
You can limit the relative rotation with a joint limit that specifies a lower and upper angle.
|
||||
|
||||
@ -388,7 +485,7 @@ revoluteJoint.setLimits(0, pi);
|
||||
```
|
||||
|
||||
|
||||
#### Joint Motor
|
||||
#### Revolute Joint Motor
|
||||
|
||||
You can use a motor to drive the relative rotation about the shared point. A maximum motor torque is
|
||||
provided so that infinite forces are not generated.
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:examples/stories/bridge_libraries/forge2d/joints/distance_joint.
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/friction_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/motor_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/mouse_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/prismatic_joint.dart';
|
||||
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/camera_and_viewport/camera_and_viewport.dart';
|
||||
@ -43,6 +44,7 @@ void main() {
|
||||
'motor_joint': MotorJointExample.new,
|
||||
'mouse_joint': MouseJointExample.new,
|
||||
'pulley_joint': PulleyJointExample.new,
|
||||
'prismatic_joint': PrismaticJointExample.new,
|
||||
'revolute_joint': RevoluteJointExample.new,
|
||||
};
|
||||
final game = routes[page]?.call();
|
||||
|
||||
@ -12,6 +12,7 @@ import 'package:examples/stories/bridge_libraries/forge2d/joints/distance_joint.
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/friction_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/motor_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/mouse_joint.dart';
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/joints/prismatic_joint.dart';
|
||||
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/raycast_example.dart';
|
||||
@ -134,6 +135,12 @@ void addJointsStories(Dashbook dashbook) {
|
||||
codeLink: link('joints/mouse_joint.dart'),
|
||||
info: MouseJointExample.description,
|
||||
)
|
||||
.add(
|
||||
'PrismaticJoint',
|
||||
(DashbookContext ctx) => GameWidget(game: PrismaticJointExample()),
|
||||
codeLink: link('joints/prismatic_joint.dart'),
|
||||
info: PrismaticJointExample.description,
|
||||
)
|
||||
.add(
|
||||
'PulleyJoint',
|
||||
(DashbookContext ctx) => GameWidget(game: PulleyJointExample()),
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:examples/stories/bridge_libraries/forge2d/utils/boxes.dart';
|
||||
import 'package:flame/events.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
|
||||
class PrismaticJointExample extends Forge2DGame
|
||||
with TapDetector, HasDraggables {
|
||||
static const description = '''
|
||||
This example shows how to use a `PrismaticJoint`.
|
||||
|
||||
Drag the box along the specified axis, bound between lower and upper limits.
|
||||
Also, there's a motor enabled that's pulling the box to the lower limit.
|
||||
''';
|
||||
|
||||
late PrismaticJoint joint;
|
||||
late Vector2 anchor = size / 2;
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
super.onLoad();
|
||||
|
||||
final box = DraggableBox(startPosition: anchor, width: 3, height: 3);
|
||||
add(box);
|
||||
await Future.wait([box.loaded]);
|
||||
|
||||
createJoint(box.body, anchor);
|
||||
}
|
||||
|
||||
void createJoint(Body box, Vector2 anchor) {
|
||||
final groundBody = world.createBody(BodyDef());
|
||||
|
||||
final prismaticJointDef = PrismaticJointDef()
|
||||
..initialize(
|
||||
box,
|
||||
groundBody,
|
||||
anchor,
|
||||
Vector2(1, 0),
|
||||
)
|
||||
..enableLimit = true
|
||||
..lowerTranslation = -20
|
||||
..upperTranslation = 20
|
||||
..enableMotor = true
|
||||
..motorSpeed = 1
|
||||
..maxMotorForce = 100;
|
||||
|
||||
joint = PrismaticJoint(prismaticJointDef);
|
||||
world.createJoint(joint);
|
||||
}
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
super.render(canvas);
|
||||
|
||||
final p1 =
|
||||
worldToScreen(anchor + joint.getLocalAxisA() * joint.getLowerLimit());
|
||||
final p2 =
|
||||
worldToScreen(anchor + joint.getLocalAxisA() * joint.getUpperLimit());
|
||||
|
||||
canvas.drawLine(p1.toOffset(), p2.toOffset(), debugPaint);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user