问题描述
在创建我自己版本的 Matter.js slingshot demo[source] 时,我在尝试防止弹丸在发射后被拖动时卡住了.
我的尝试:
创建 3 个 collisionFilter 类别;
-
0x0001:
static
:地面、平台等 -
0x0002:
drag
:与鼠标交互的项目 -
0x0004:
nodrag
:不能与鼠标交互的项目,但会与其他所有东西发生碰撞
这很好用,一切都相互碰撞,而且我只能拖动弹丸(drag
),而不能拖动目标(nodrag
)。
所以我的下一个挑战是在发射后将弹丸从 drag
切换到 nodrag
。否则,您可以抓住射弹并将其用作破坏球。
因此,就在我向弹性体添加新射弹之前,我尝试将 collisionFilter
切换为 nodrag
,如下所示:
Events.on(engine,'afterUpdate',function() {
// If Rock is outside drag-range
if (mouseConstraint.mouse.button === -1 && (rock.position.x > dragborder_x || rock.position.y < dragborder_y)) {
rock.collisionFilter = { category: cat.nodrag };
...
问题^^
不幸的是,这可以防止射弹与所有物体发生碰撞,甚至是墙壁 (static
)。即使具有 nodrag
的目标仍然与墙壁发生碰撞。所以我不知道为什么射弹在切换到 nodrag
后停止碰撞。
(tl;dr)
正在寻找一些指导以阻止射弹在发射后可拖动。
简化示例
- 切换第 72 行以查看上述问题
// Statics
const vw = window.innerWidth;
const vh = window.innerHeight;
var Engine = Matter.Engine,Render = Matter.Render,Runner = Matter.Runner,Composites = Matter.Composites,Events = Matter.Events,Constraint = Matter.Constraint,MouseConstraint = Matter.MouseConstraint,Mouse = Matter.Mouse,World = Matter.World,Bodies = Matter.Bodies;
const cat = {
static: 0x0001,nodrag: 0x0002,drag: 0x0004
};
// Create world
var engine = Engine.create();
var world = engine.world;
// Create render
var render = Render.create({
element: document.body,engine: engine,options: {
width: vw,height: vh,wireframes: false,showAngleIndicator: false
}
});
// render.on()
Render.run(render);
// Create runner
var runner = Runner.create();
Runner.run(runner,engine);
// Body consts
const rock_x = vw * .20;
const rock_y = vh * .66;
const rockOptions = {
density: 0.01,collisionFilter: {
category: cat.drag
}
};
const gift = {
render: {
sprite: {}
},collisionFilter: {
category: cat.nodrag
}
};
// Add Static bodies
var ground = Bodies.rectangle(vw * .5,vh * .9,vw * .9,42,{ isstatic: true,render: { fillStyle: '#060a19' } });
var rock = Bodies.polygon(rock_x,rock_y,8,15,rockOptions);
var anchor = { x: rock_x,y: rock_y };
var elastic = Constraint.create({ pointA: anchor,bodyB: rock,stiffness: 0.09,render: { linewidth: 1 } });
var wall = Composites.stack(vw * .66,2,(vh * .4) / 15,1,(x,y) => Bodies.rectangle(x,y,gift));
var platform = Bodies.rectangle(vw * .75,vh * .6,210,21,render: { fillStyle: '#060a19' },collisionFilter: { category: cat.static } });
var pyramid = Composites.pyramid(vw * .30,11,gift));
World.add(engine.world,[ ground,pyramid,platform,wall,rock,elastic ]);
// Rock drag
const dragborder_x = rock_x + 20;
const dragborder_y = rock_y - 20;
Events.on(engine,function() {
// If Rock is outside drag-range
if (mouseConstraint.mouse.button === -1 && (rock.position.x > dragborder_x || rock.position.y < dragborder_y)) {
// Failed attempt
// rock.collisionFilter = { category: cat.nodrag };
// Add new Rock
rock = Bodies.polygon(rock_x,7,rockOptions);
World.add(engine.world,rock);
// Re-bind elastic
elastic.bodyB = rock;
}
});
// Mouse control
var mouse = Mouse.create(render.canvas);
var mouseConstraint = MouseConstraint.create(engine,{
mouse: mouse,constraint: {
stiffness: 0.2,render: {
visible: false
}
}
});
// Add mouse
World.add(world,mouseConstraint);
render.mouse = mouse;
// Prevent mouse-drag
mouseConstraint.collisionFilter.mask = cat.static | cat.drag;
// Run
Engine.run(engine);
Render.run(render);
<script src="https://cdn.jsdelivr.net/npm/matter-js@0.16.1/build/matter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<Meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,minimal-ui">
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)