ป้องกันร่างกายที่ใช้กำลังลากผ่านวัตถุอื่นด้วย MatterJS


14

ฉันใช้ MatterJs สำหรับเกมที่ใช้ฟิสิกส์และไม่พบวิธีแก้ปัญหาสำหรับการป้องกันไม่ให้ร่างกายถูกบังคับลากผ่านเมาส์ผ่านทางวัตถุอื่น หากคุณลากร่างกายไปยังอีกร่างกายหนึ่งร่างกายที่ถูกลากสามารถบังคับตัวเองเข้าและผ่านร่างกายอีกคนได้ ฉันกำลังมองหาวิธีที่เชื่อถือได้เพื่อป้องกันไม่ให้มันตัดกัน คุณสามารถสังเกตเห็นเอฟเฟกต์นี้ในการสาธิต MatterJS ใด ๆ โดยการเลือกร่างกายด้วยเมาส์และพยายามบังคับผ่านร่างกายอื่น นี่คือตัวอย่างทั่วไป:

ป้อนคำอธิบายรูปภาพที่นี่

https://brm.io/matter-js/demo/#staticFriction

โชคไม่ดีที่เกมนี้แตกหรือมีการจำลองโดยขึ้นอยู่กับการลากและวาง ฉันได้พยายามแก้ไขปัญหาหลายอย่างเช่นทำลายข้อ จำกัด ของเมาส์เมื่อเกิดการชนหรือลดความฝืดของข้อ จำกัด แต่ไม่มีสิ่งใดที่ทำงานได้อย่างน่าเชื่อถือ

ข้อเสนอแนะใด ๆ ยินดีต้อนรับ!


ฉันไม่เข้าใจข้อความที่ใช้กำลังลาก คุณหมายถึงร่างกายที่ถูกลากของคุณควรผ่านร่างอื่นหรือไม่?
grodzi

ไม่มันหมายความว่าร่างกายที่ถูกลากนั้นควรได้รับการป้องกันไม่ให้ผ่านร่างกายอื่น ๆ
d13

1
@ d13 คุณสามารถเพิ่มภาพเคลื่อนไหวที่แสดงปัญหาได้หรือไม่ เนื่องจากดูเหมือนว่าจะมีความสับสนบางอย่างขึ้นอยู่กับถ้อยคำ ...
ผี

2
@Ghost เพิ่ม ...
d13

@ d13 นั่นทำให้สิ่งต่าง ๆ ชัดเจน ..... นี่คือสิ่งที่ยุ่งยาก
Ghost

คำตอบ:


6

ฉันคิดว่าคำตอบที่ดีที่สุดในที่นี้คือการยกเครื่องครั้งใหญ่ในMatter.Resolverโมดูลเพื่อดำเนินการหลีกเลี่ยงความขัดแย้งทางกายภาพระหว่างร่างกายใด ๆ สิ่งใดก็ตามที่สั้น ๆ ที่รับประกันว่าจะล้มเหลวภายใต้สถานการณ์บางอย่าง ที่ถูกกล่าวว่าที่นี่มีสอง "โซลูชั่น" ซึ่งในความเป็นจริงเป็นเพียงบางส่วน พวกเขาระบุไว้ด้านล่าง


โซลูชันที่ 1 (อัปเดต)

วิธีนี้มีข้อดีหลายประการ:

  • มีความกระชับมากกว่าโซลูชัน 2
  • สร้างรอยเท้าการคำนวณที่เล็กกว่าโซลูชัน 2
  • พฤติกรรมการลากไม่ถูกขัดจังหวะในวิธีที่2
  • สามารถใช้ร่วมกับโซลูชัน 2แบบไม่ทำลายได้

แนวคิดเบื้องหลังแนวทางนี้คือการแก้ไขความขัดแย้งของสิ่งที่เกิดขึ้น " เมื่อพลังที่ผ่านพ้นไม่ได้เข้าใกล้วัตถุที่เคลื่อนที่ไม่ได้ " โดยการบังคับให้หยุดการทำงาน สิ่งนี้เปิดใช้งานโดยMatter.Event beforeUpdate, ซึ่งอนุญาตให้ใช้ความเร็วและแรงกระตุ้นแบบสัมบูรณ์ (หรือมากกว่าpositionImpulse, ซึ่งไม่ใช่แรงกระตุ้นทางกายภาพจริง ๆ ) ในแต่ละทิศทางที่จะถูก จำกัด ภายในขอบเขตที่ผู้ใช้กำหนด

window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({    element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
     if (dragBody != null) {
        if (dragBody.velocity.x > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: 25, y: dragBody.velocity.y });
        }
        if (dragBody.velocity.y > 25.0) {
            Matter.Body.setVelocity(dragBody, {x: dragBody.velocity.x, y: 25 });
        }
        if (dragBody.positionImpulse.x > 25.0) {
            dragBody.positionImpulse.x = 25.0;
        }
        if (dragBody.positionImpulse.y > 25.0) {
            dragBody.positionImpulse.y = 25.0;
        }
    }
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.1, render: { visible: false }}});
     
    var dragBody = null


    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
    });
    
    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
});
<canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script>

ในตัวอย่างที่ผมกำลัง จำกัดvelocityและpositionImpulseในxและจะขนาดสูงสุดของy 25.0ผลลัพธ์แสดงไว้ด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็นมันเป็นไปได้ที่จะมีความรุนแรงในการลากศพและพวกเขาจะไม่ผ่านกันและกัน นี่คือสิ่งที่กำหนดวิธีการนี้นอกเหนือจากวิธีอื่น: โซลูชันที่มีศักยภาพอื่น ๆ ส่วนใหญ่จะล้มเหลวเมื่อผู้ใช้มีความรุนแรงพอกับการลาก

ข้อบกพร่องเพียงอย่างเดียวที่ฉันได้พบกับวิธีนี้คือมันเป็นไปได้ที่จะใช้ร่างกายที่ไม่คงที่เพื่อตีวัตถุที่ไม่คงที่อีกแรงพอที่จะให้ความเร็วเพียงพอจนถึงจุดที่Resolverโมดูลจะล้มเหลวในการตรวจจับการชนและอนุญาตให้ ร่างที่สองที่จะผ่านร่างอื่น (ในตัวอย่างแรงเสียดทานแบบสแตติกความเร็วที่ต้องการคือประมาณ50.0ฉันทำได้เพียงครั้งเดียวสำเร็จและดังนั้นฉันจึงไม่มีภาพเคลื่อนไหว)


โซลูชันที่ 2

นี่เป็นวิธีแก้ไขเพิ่มเติม แต่เตือนอย่างเป็นธรรมว่าไม่ตรงไปตรงมา

กล่าวอย่างกว้าง ๆ ถึงวิธีการทำงานของมันคือการตรวจสอบว่าร่างกายถูกลากไปdragBodyชนกับวัตถุที่เคลื่อนไหวหรือไม่และหากเมาส์เคลื่อนไปไกลเกินไปโดยไม่dragBodyทำตาม หากตรวจพบว่าการแยกระหว่างเมาส์และdragBodyมีขนาดใหญ่เกินไปจะเป็นการลบMatter.js mouse.mousemoveฟังเหตุการณ์จากmouse.elementและแทนที่มันด้วยฟังก์ชั่น mousemove mousemove()ที่แตกต่างกัน ฟังก์ชั่นนี้จะตรวจสอบว่าเมาส์ได้กลับไปอยู่ในระยะใกล้ที่กำหนดของศูนย์กลางของร่างกายหรือไม่ น่าเสียดายที่ฉันไม่สามารถใช้Matter.Mouse._getRelativeMousePosition()วิธีการในตัวเพื่อทำงานได้อย่างถูกต้องดังนั้นฉันจึงต้องรวมโดยตรง (บางคนที่มีความรู้มากกว่าฉันใน Javascript จะต้องคิดแบบนั้น) ในที่สุดหากmouseupตรวจพบเหตุการณ์มันจะเปลี่ยนกลับไปเป็นmousemoveผู้ฟังปกติ

window.addEventListener('load', function() {
    var canvas = document.getElementById('world')
    var mouseNull = document.getElementById('mouseNull')
    var engine = Matter.Engine.create();
    var world = engine.world;
    var render = Matter.Render.create({ element: document.body, canvas: canvas,
                 engine: engine, options: { width: 800, height: 800,
                     background: 'transparent',showVelocity: true }});
    var body = Matter.Bodies.rectangle(400, 500, 200, 60, { isStatic: true}), 
        size = 50, counter = -1;
     
    var stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 
                                        0, 0, function(x, y) {
     return Matter.Bodies.rectangle(x, y, size * 2, size, {
         slop: 0.5, friction: 1,    frictionStatic: Infinity });
    });
    Matter.World.add(world, [ body, stack,
     Matter.Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
     Matter.Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
     Matter.Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    Matter.Events.on(engine, 'beforeUpdate', function(event) {
     counter += 0.014;
     if (counter < 0) { return; }
     var px = 400 + 100 * Math.sin(counter);
     Matter.Body.setVelocity(body, { x: px - body.position.x, y: 0 });
     Matter.Body.setPosition(body, { x: px, y: body.position.y });
    });

    var mouse = Matter.Mouse.create(render.canvas),
     mouseConstraint = Matter.MouseConstraint.create(engine, { mouse: mouse,
         constraint: { stiffness: 0.2, render: { visible: false }}});
     
    var dragBody, overshoot = 0.0, threshold = 50.0, loc, dloc, offset, 
    bodies = Matter.Composite.allBodies(world), moveOn = true;
    getMousePosition = function(event) {
     var element = mouse.element, pixelRatio = mouse.pixelRatio, 
        elementBounds = element.getBoundingClientRect(),
        rootNode = (document.documentElement || document.body.parentNode || 
                    document.body),
        scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : 
                   rootNode.scrollLeft,
        scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : 
                   rootNode.scrollTop,
        touches = event.changedTouches, x, y;
     if (touches) {
         x = touches[0].pageX - elementBounds.left - scrollX;
         y = touches[0].pageY - elementBounds.top - scrollY;
     } else {
         x = event.pageX - elementBounds.left - scrollX;
         y = event.pageY - elementBounds.top - scrollY;
     }
     return { 
         x: x / (element.clientWidth / (element.width || element.clientWidth) *
            pixelRatio) * mouse.scale.x + mouse.offset.x,
         y: y / (element.clientHeight / (element.height || element.clientHeight) *
            pixelRatio) * mouse.scale.y + mouse.offset.y
     };
    };     
    mousemove = function() {
     loc = getMousePosition(event);
     dloc = dragBody.position;
     overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
     if (overshoot < threshold) {
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    }
    Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
     dragBody = event.body;
     loc = mouse.position;
     dloc = dragBody.position;
     offset = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5;
     Matter.Events.on(mouseConstraint, 'mousemove', function(event) {
         loc = mouse.position;
         dloc = dragBody.position;
         for (var i = 0; i < bodies.length; i++) {                      
             overshoot = ((loc.x - dloc.x)**2 + (loc.y - dloc.y)**2)**0.5 - offset;
             if (bodies[i] != dragBody && 
                 Matter.SAT.collides(bodies[i], dragBody).collided == true) {
                 if (overshoot > threshold) {
                     if (moveOn == true) {
                         mouse.element.removeEventListener("mousemove", mouse.mousemove);
                         mouse.element.addEventListener("mousemove", mousemove);
                         moveOn = false;
                     }
                 }
             }
         }
     });
    });

    Matter.Events.on(mouseConstraint, 'mouseup', function(event) {
     if (moveOn == false){
         mouse.element.removeEventListener("mousemove", mousemove);
         mouse.element.addEventListener("mousemove", mouse.mousemove);
         moveOn = true;
     }
    });
    Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
     overshoot = 0.0;
     Matter.Events.off(mouseConstraint, 'mousemove');
    });

    Matter.World.add(world, mouseConstraint);
    render.mouse = mouse;
    Matter.Engine.run(engine);
    Matter.Render.run(render);
});
<canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.js"></script>

หลังจากใช้ชุดรูปแบบการสลับผู้ฟังเหตุการณ์ตอนนี้เนื้อความจะทำงานมากกว่านี้

ป้อนคำอธิบายรูปภาพที่นี่

ฉันได้ทดสอบสิ่งนี้อย่างทั่วถึงแล้ว แต่ฉันไม่สามารถรับประกันได้ว่ามันจะใช้ได้ในทุกกรณี นอกจากนี้ยังมีการสังเกตว่าmouseupเหตุการณ์ไม่ได้รับการตรวจพบเว้นแต่ว่าเมาส์นั้นอยู่ในผืนผ้าใบเมื่อมันเกิดขึ้น - แต่นี่เป็นความจริงสำหรับmouseupการตรวจจับMatter.js ดังนั้นฉันจึงไม่พยายามแก้ไข

หากความเร็วมีขนาดใหญ่พอResolverจะล้มเหลวในการตรวจจับการชนใด ๆ และเนื่องจากไม่มีการป้องกันการทำนายของความขัดแย้งทางกายรสชาตินี้จะช่วยให้ร่างกายผ่านดังที่แสดงไว้ที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

นี้สามารถแก้ไขได้โดยใช้ร่วมกับโซลูชันที่ 1

หนึ่งบันทึกล่าสุดที่นี่เป็นไปได้ที่จะใช้สิ่งนี้กับการโต้ตอบบางอย่างเท่านั้น (เช่นสิ่งที่อยู่ระหว่างร่างกายแบบคงที่และแบบไม่คงที่) การทำเช่นนั้นทำได้โดยการเปลี่ยน

if (bodies[i] != dragBody && Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}

ถึง (สำหรับเช่นวัตถุคงที่)

if (bodies[i].isStatic == true && bodies[i] != dragBody && 
    Matter.SAT.collides(bodies[i], dragBody).collided == true) {
    //...
}

การแก้ปัญหาล้มเหลว

ในกรณีที่ผู้ใช้ในอนาคตเจอคำถามนี้และพบว่าทั้งสองวิธีไม่เพียงพอสำหรับกรณีการใช้งานของพวกเขานี่เป็นวิธีแก้ปัญหาบางอย่างที่ฉันพยายามทำ ได้ผล คู่มือแปลก ๆ สำหรับสิ่งที่ไม่ควรทำ

  • โทรmouse.mouseupโดยตรง: วัตถุถูกลบทันที
  • โทรmouse.mouseupผ่านEvent.trigger(mouseConstraint, 'mouseup', {mouse: mouse}) : แทนที่โดยEngine.updateพฤติกรรมไม่เปลี่ยนแปลง
  • การทำให้วัตถุที่ถูกลากถูกตรึงชั่วคราว: วัตถุถูกลบเมื่อกลับสู่ที่ไม่คงที่ (ไม่ว่าจะผ่าน Matter.Body.setStatic(body, false)หรือbody.isStatic = false)
  • กำหนดแรงที่จะ(0,0)ผ่านsetForceเมื่อใกล้ถึงความขัดแย้ง: วัตถุยังสามารถผ่านไปได้จะต้องถูกนำมาใช้เพื่อให้สามารถใช้งานได้Resolverจริง
  • การเปลี่ยนmouse.elementเป็นผืนผ้าใบอื่นผ่านsetElement()หรือโดยการกลายพันธุ์mouse.elementโดยตรง: วัตถุถูกลบทันที
  • การย้อนกลับวัตถุไปยังตำแหน่ง 'ที่ถูกต้อง' ล่าสุด: ยังอนุญาตให้ผ่านได้
  • เปลี่ยนพฤติกรรมทางcollisionStart: การตรวจจับการชนกันที่ไม่สอดคล้องยังคงอนุญาตให้ผ่านด้วยวิธีนี้


ขอบคุณมากสำหรับการมีส่วนร่วมของคุณ! ฉันมอบรางวัลให้คุณเพราะถึงแม้ว่าวิธีการแก้ปัญหาของคุณจะไม่สมบูรณ์แบบ แต่ก็ชี้ไปข้างหน้าแน่นอนและคุณใช้ความคิดและเวลาจำนวนมากในปัญหานี้ - ขอบคุณ !! ตอนนี้ฉันมั่นใจว่าปัญหานี้จะเกิดขึ้นกับช่องว่างของคุณลักษณะใน MatterJS และหวังว่าการสนทนานี้จะช่วยแก้ปัญหาที่แท้จริงในอนาคต
d13

@ d13 ขอบคุณฉันยอมรับว่าปัญหาคือที่สุดในรหัสพื้นฐาน แต่ฉันดีใจที่ฉันจะได้รับหน้าตาบางส่วนของการแก้ปัญหา
William Miller

0

ฉันจะจัดการคุณสมบัติในอีกทางหนึ่ง:

  • ไม่ "ลาก" (ดังนั้นจึงไม่มีการจัดตำแหน่งจุดเชื่อมต่อจุดลากกับวัตถุที่ลาก Vs ตรงข้าม)
  • บน mouseDown ตำแหน่งตัวชี้เมาส์ให้เวกเตอร์ความเร็วเชิงสำหรับวัตถุที่จะปฏิบัติตาม
  • เมื่อ mouseUp รีเซ็ตเวกเตอร์ความเร็วของคุณ
  • ปล่อยให้เรื่องจำลองทำส่วนที่เหลือ

1
นั่นไม่ใช่วิธีmatter.jsจัดการกับการลากศพหรือเปล่า จากที่นี่ "... เหมือนสปริงเสมือนที่ติดกับเมาส์เมื่อลาก ... สปริงจะถูกยึด [กับร่างกาย] และดึงไปในทิศทางของเมาส์ ... "
Ghost

การตั้งค่าความเร็วเท่านั้นป้องกันการลากทับซ้อนกันแรงหมุนจะบังคับร่างกายผ่านวัตถุอื่น
Mosè Raguzzini

นี่อาจชี้ไปที่โซลูชัน หากฉันเข้าใจถูกต้องแสดงว่าไม่ได้ใช้ MatterJS ที่สร้างขึ้นใน MouseConstraint และตั้งค่าความเร็วของร่างกายด้วยตนเองตามตำแหน่งของเมาส์ ฉันไม่แน่ใจว่าจะนำสิ่งนี้ไปใช้ได้อย่างไรดังนั้นหากใครก็ตามสามารถโพสต์รายละเอียดเกี่ยวกับวิธีจัดแนวเนื้อหาของเมาส์โดยไม่ต้องใช้ setPosition หรือข้อ จำกัด โปรดทำเช่นนั้น
d13

@ d13 คุณยังคงต้องพึ่งพา MatterJS ในResolverการตัดสินใจว่าจะทำอย่างไรกับการชนกันของข้อมูล - การตรวจสอบรหัสนั้นอย่างยุติธรรมฉันคาดหวังว่ามันจะยังคงตัดสินใจอนุญาตให้ลากผ่านภายใต้สถานการณ์ต่าง ๆ ..... อาจทำงานได้ถ้าคุณ ยังใช้เวอร์ชันของคุณเองsolveVelocityและsolvePositionณ จุดนั้นคุณยังคงทำสิ่งที่คุณต้องการให้ MatterJS จัดการเองโดยตรง ....
Ghost

0

ในการควบคุมการชนกันของข้อมูลเมื่อลากคุณต้องใช้ตัวกรองการชนและเหตุการณ์เหตุการณ์ที่เกิดขึ้น

สร้างร่างเริ่มต้นหน้ากากกรองชน 0x0001เพิ่มตัวจับstartdragและenddragเหตุการณ์และตั้งค่าหมวดหมู่ตัวกรองการชนกันของข้อมูลเพื่อหลีกเลี่ยงการชนกันชั่วคราว

Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
    event.body.collisionFilter.category = 0x0008; // move body to new category to avoid collision
});
Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
     event.body.collisionFilter.category = 0x0001; // return body to default category to activate collision
});

window.addEventListener('load', function () {

  //Fetch our canvas
  var canvas = document.getElementById('world');

  //Setup Matter JS
  var engine = Matter.Engine.create();
  var world = engine.world;
  var render = Matter.Render.create({
                                      canvas: canvas,
                                      engine: engine,
                                      options: {
                                        width: 800,
                                        height: 800,
                                        background: 'transparent',
                                        wireframes: false,
                                        showAngleIndicator: false
                                      }
                                    });

  //Add a ball
  const size = 50;
  const stack = Matter.Composites.stack(350, 470 - 6 * size, 1, 6, 0, 0, (x, y) => {
    return Matter.Bodies.rectangle(x, y, size * 2, size, {
      collisionFilter: {
            mask: 0x0001,
      },
      slop: 0.5,
      friction: 1,
      frictionStatic: Infinity,
    });
  });

  Matter.World.add(engine.world, stack);

  //Add a floor
  var floor = Matter.Bodies.rectangle(250, 520, 500, 40, {
    isStatic: true, //An immovable object
    render: {
      visible: false
    }
  });
  Matter.World.add(world, floor);

  //Make interactive
  var mouseConstraint = Matter.MouseConstraint.create(engine, { //Create Constraint
    element: canvas,

    constraint: {
      render: {
        visible: false
      },
      stiffness: 0.8
    }
  });
  Matter.World.add(world, mouseConstraint);

  // add events to listen drag
  Matter.Events.on(mouseConstraint, 'startdrag', function (event) {
    event.body.collisionFilter.category = 0x0008; // move body to new category to avoid collision
  });
  Matter.Events.on(mouseConstraint, 'enddrag', function (event) {
    event.body.collisionFilter.category = 0x0001; // return body to default category to activate collision
  });

  //Start the engine
  Matter.Engine.run(engine);
  Matter.Render.run(render);

});
<canvas id="world"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.min.js"></script>


1
ขอบคุณมากสำหรับการสาธิตที่ยอดเยี่ยมของคุณ! จริง ๆ แล้วฉันพยายามที่จะบรรลุผลตรงกันข้าม: ฉันต้องป้องกันไม่ให้ร่างกายตัดกันเมื่อมีใครถูกลากเข้าไปอีก
d13

ขออภัยถ้าฉันเข้าใจผิดปัญหา คุณสามารถอธิบายสิ่งที่คุณหมายถึงโดยการป้องกันร่างกายจากการตัดกัน? คุณพยายามป้องกันการลากผ่านวัตถุอื่น ๆ เมื่อมีการใช้แรงหรือไม่?
Temur Tchanukvadze

1
ในกรณีนี้มันเป็นปัญหาแบบเปิดและไม่สามารถทำได้โดยไม่ต้องใช้รหัสยากในการติดตั้ง CCD ดู: github.com/liabru/matter-js/issues/5
Temur Tchanukvadze

0

ดูเหมือนว่าจะเกี่ยวข้องกับปัญหา 672ในหน้า GitHub ซึ่งดูเหมือนว่าจะแนะนำว่าสิ่งนี้เกิดขึ้นเนื่องจากขาดการตรวจจับการชนกันอย่างต่อเนื่อง (CCD)

มีความพยายามในการแก้ไขปัญหานี้และรหัสของมันสามารถพบได้ที่นี่แต่ปัญหายังคงเปิดอยู่ดังนั้นดูเหมือนว่าคุณอาจต้องแก้ไขเอ็นจิ้นเพื่อสร้าง CCD ด้วยตัวคุณเอง


1
ขอบคุณสำหรับคำตอบ! ฉันได้พิจารณาสิ่งนี้ แต่ฉันเชื่อว่าไม่ใช่ปัญหา CCD แต่เป็นปัญหาของ "จะเกิดอะไรขึ้นเมื่อแรงที่ผ่านพ้นไม่ได้เข้ามาถึงสิ่งกีดขวางที่เคลื่อนที่ไม่ได้" ยังไงก็เถอะฉันต้องหาวิธีที่จะต่อต้านกองกำลังเพื่อป้องกันร่างกายจากการตัดกัน
d13
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.