在不同位置创建的 PolygonShape
我试图用鼠标关节在屏幕中心创建一个多边形,非常简单。 CircleShape 效果很好。而且鼠标关节的行为很奇怪,我找不到模式。 所有代码都位于主文件此处中。我将代码保持在最低限度。
Vector2 vec2Median(List<Vector2> vecs) {
var sum = Vector2(0, 0);
for (final v in vecs) {
sum += v;
}
return sum / vecs.length.toDouble();
}
void main() {
final game = MyGame();
runApp(GameWidget(game: game));
}
class MyGame extends Forge2DGame with MultiTouchDragDetector, HasTappables {
MouseJoint? mouseJoint;
static late BodyComponent grabbedBody;
late Body groundBody;
MyGame() : super(gravity: Vector2(0, -10.0));
@override
Future<void> onLoad() async {
final boundaries = createBoundaries(this); //Adding boundries
boundaries.forEach(add);
groundBody = world.createBody(BodyDef());
final center = screenToWorld(camera.viewport.effectiveSize / 2);
final poly = Polygon([
center + Vector2(0, 0),
center + Vector2(0, 5),
center + Vector2(5, 0),
center + Vector2(5, 5)
], bodyType: BodyType.dynamic);
add(poly);
grabbedBody = poly;
}
@override
bool onDragUpdate(int pointerId, DragUpdateInfo details) {
final mouseJointDef = MouseJointDef()
..maxForce = 3000 * grabbedBody.body.mass * 10 //Not neccerly needed
..dampingRatio = 1
..frequencyHz = 5
..target.setFrom(grabbedBody.body.position)
..collideConnected = false //Maybe set to true
..bodyA = groundBody
..bodyB = grabbedBody.body;
mouseJoint ??= world.createJoint(mouseJointDef) as MouseJoint;
mouseJoint?.setTarget(details.eventPosition.game);
return false;
}
@override
bool onDragEnd(int pointerId, DragEndInfo details) {
if (mouseJoint == null) {
return true;
}
world.destroyJoint(mouseJoint!);
mouseJoint = null;
return false;
}
}
abstract class TappableBodyComponent extends BodyComponent with Tappable {
final Vector2 position;
final BodyType bodyType;
TappableBodyComponent(this.position, {this.bodyType = BodyType.dynamic});
@override
bool onTapDown(_) {
MyGame.grabbedBody = this;
return false;
}
Body tappableBCreateBody(Shape shape) {
final fixtureDef = FixtureDef(shape)
..restitution = 0.8
..density = 1.0
..friction = 0.4;
final bodyDef = BodyDef()
// To be able to determine object in collision
..userData = this
..angularDamping = 0.8
..position = position
..type = bodyType;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}
class Polygon extends TappableBodyComponent {
final List<Vector2> vertecies;
Polygon(this.vertecies, {BodyType bodyType = BodyType.dynamic})
: super(vec2Median(vertecies), bodyType: bodyType);
@override
Body createBody() {
final shape = PolygonShape()..set(vertecies);
return tappableBCreateBody(shape);
}
}
tappableBCreateBody 封装了 Tappable 和 body 创建方法,Polygon 是我要创建的对象,vec2Median 返回多边形的中心(通过顶点)。
非常感谢!
I'm trying to create a polygon at the center of the screen with a mouse joint, very simple.
A CircleShape works great. Also the mouse joint behaves strangely and I couldn't find a pattern.
All code is in the main file here. I kept the code to a minimum.
Vector2 vec2Median(List<Vector2> vecs) {
var sum = Vector2(0, 0);
for (final v in vecs) {
sum += v;
}
return sum / vecs.length.toDouble();
}
void main() {
final game = MyGame();
runApp(GameWidget(game: game));
}
class MyGame extends Forge2DGame with MultiTouchDragDetector, HasTappables {
MouseJoint? mouseJoint;
static late BodyComponent grabbedBody;
late Body groundBody;
MyGame() : super(gravity: Vector2(0, -10.0));
@override
Future<void> onLoad() async {
final boundaries = createBoundaries(this); //Adding boundries
boundaries.forEach(add);
groundBody = world.createBody(BodyDef());
final center = screenToWorld(camera.viewport.effectiveSize / 2);
final poly = Polygon([
center + Vector2(0, 0),
center + Vector2(0, 5),
center + Vector2(5, 0),
center + Vector2(5, 5)
], bodyType: BodyType.dynamic);
add(poly);
grabbedBody = poly;
}
@override
bool onDragUpdate(int pointerId, DragUpdateInfo details) {
final mouseJointDef = MouseJointDef()
..maxForce = 3000 * grabbedBody.body.mass * 10 //Not neccerly needed
..dampingRatio = 1
..frequencyHz = 5
..target.setFrom(grabbedBody.body.position)
..collideConnected = false //Maybe set to true
..bodyA = groundBody
..bodyB = grabbedBody.body;
mouseJoint ??= world.createJoint(mouseJointDef) as MouseJoint;
mouseJoint?.setTarget(details.eventPosition.game);
return false;
}
@override
bool onDragEnd(int pointerId, DragEndInfo details) {
if (mouseJoint == null) {
return true;
}
world.destroyJoint(mouseJoint!);
mouseJoint = null;
return false;
}
}
abstract class TappableBodyComponent extends BodyComponent with Tappable {
final Vector2 position;
final BodyType bodyType;
TappableBodyComponent(this.position, {this.bodyType = BodyType.dynamic});
@override
bool onTapDown(_) {
MyGame.grabbedBody = this;
return false;
}
Body tappableBCreateBody(Shape shape) {
final fixtureDef = FixtureDef(shape)
..restitution = 0.8
..density = 1.0
..friction = 0.4;
final bodyDef = BodyDef()
// To be able to determine object in collision
..userData = this
..angularDamping = 0.8
..position = position
..type = bodyType;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}
class Polygon extends TappableBodyComponent {
final List<Vector2> vertecies;
Polygon(this.vertecies, {BodyType bodyType = BodyType.dynamic})
: super(vec2Median(vertecies), bodyType: bodyType);
@override
Body createBody() {
final shape = PolygonShape()..set(vertecies);
return tappableBCreateBody(shape);
}
}
tappableBCreateBody encapsulate Tappable and body creation methods, Polygon is the object I'm trying to create, vec2Median returns the center of the polygon (by vertices).
Thank you very much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您必须从顶点中删除
center
,然后仅将其添加为BodyComponent
的位置,就像您在的超级调用中所做的那样多边形
类。I think that you have to remove
center
from the vertices and only add that as the position of theBodyComponent
instead, like you already do in the super call of yourPolygon
class.