Cocos2d-x 3 - ปิดการใช้งานการชนกันระหว่างวัตถุสองชิ้นและตรวจจับเมื่อทั้งสองแยกจากกัน

ฉันกำลังพัฒนาเกม cocos2d-x (เวอร์ชัน 3.8) เกมของฉันใช้ฟิสิกส์ของกระแตและมีร่างกายที่นิ่งซึ่งทำงานเหมือนกับผู้ขัดขวาง ตัวขัดจังหวะนี้จะเปิดใช้งานเมื่อมีอีกวัตถุหนึ่งอยู่เหนือมัน ผู้ขัดขวางจะถูกปิดใช้งานเมื่อร่างกายแยกจากกัน

ฉันต้องการ:

  • การเคลื่อนไหวร่างกายไม่ชนกับสิ่งกีดขวาง มันต้องข้ามตัวขัดขวางโดยไม่มีการเด้งกลับ
  • ฉันต้องการตรวจจับเมื่อร่างกายเคลื่อนไหวแยกผู้ขัดขวาง

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

ปัญหาคือไม่ได้เรียกเมธอด onContactSeparate เนื่องจากการติดต่อไม่ได้เกิดขึ้น

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

[แก้ไข] ข้อมูลเพิ่มเติม

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

ผู้ขัดขวางถูกปิดใช้งาน

นี่คือสถานการณ์ที่สไปรท์สองตัวสัมผัสกันและวัตถุ 1 (ลูกบอล) อยู่เหนือตัวขัดขวาง ฉันต้องการตรวจสอบว่าสไปรต์สองตัวแยกจากกันตรงไหน

เปิดใช้งานตัวขัดขวาง

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม!


person Daniel Albert    schedule 29.09.2015    source แหล่งที่มา


คำตอบ (1)


สำหรับฉันดูเหมือนว่าคุณกำลังใช้ Box2D ภายใน cocos ดังนั้นฉันจะตอบโดยถือเป็นสมมติฐานพื้นฐานของฉัน

นี่คือสิ่งที่ฉันจะทำ

  1. ผู้ขัดขวางของฉันจะเป็น b2Body* ที่ไม่มีการกำหนดมิติ BodyDef หรือเป็นเพียง def มิติ 0x0
  2. ฉันจะตั้งค่าข้อมูลผู้ใช้สำหรับ bodyDef เป็นรูปสี่เหลี่ยมผืนผ้าที่อธิบายพื้นที่ขัดจังหวะของฉัน วิธีนี้ทำให้คุณสามารถแสดงพื้นที่ขัดจังหวะของคุณได้ตลอดเวลา แต่จะไม่ชนกับสิ่งใดๆ
  3. (ไม่บังคับ) หากคุณต้องการให้พื้นที่หยุดชะงักเคลื่อนที่ไปตามเนื้อหาปลอมที่คุณกำหนดไว้ คุณสามารถอัปเดตได้หลังจากฟังก์ชันขั้นตอนโดยใช้สิ่งที่ต้องการด้านล่าง

    world->Step(delta, 10, 10);   
    for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
    { 
     auto userData = static_cast<Node*>(physicsBody->GetUserData());
     if(userData != NULL)
     {
       // Set interruptor area rectangle = physicsBody->GetPosition();
     }
    }
    
  4. เพื่อให้ส่วนที่เหลือของระบบทราบเมื่อฉันออกจากผู้ขัดขวาง ฉันจะเก็บตัวชี้ฟังก์ชันไปยังฟังก์ชันที่ฉันต้องการเรียกเมื่อสิ่งนี้เกิดขึ้น เมื่อวัตถุเข้าสู่พื้นที่หยุดชะงัก ฉันจะตั้งค่าสถานะโดยบอกว่า "ฉันอยู่ในพื้นที่นั้น" " หลังจากนั้น ขั้นตอนการอัปเดตแรกที่คุณได้รับเมื่อไม่ได้อยู่ในพื้นที่อีกต่อไป ฉันจะเริ่มการโทรกลับและรีเซ็ตแฟล็กที่ฉันเคยไปถึงจุดนั้น

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

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

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

person Filled Stacks    schedule 30.09.2015
comment
ขอบคุณ แต่ฉันใช้ฟิสิกส์กระแต ฉันได้เพิ่มข้อมูลเพิ่มเติมและรูปภาพบางส่วนที่แสดงให้เห็นว่ามันทำงานอย่างไร - person Daniel Albert; 30.09.2015
comment
@DanielAlbert จากการแก้ไขที่คุณเขียนว่าคุณต้องการตรวจสอบว่าสไปรต์สองตัวแยกจากกันที่ไหน นี่หมายความว่าคุณต้องการทราบว่าเมื่อใดที่สไปรต์หยุดชนกันและเคลื่อนตัวออกจากกัน? หรือคุณต้องการทราบจุดตัดของสไปรท์เมื่อชนกัน? - person Filled Stacks; 01.10.2015
comment
ใช่ ฉันแค่ต้องการการติดต่อกลับเพื่อตรวจจับทันทีที่สไปรท์สองตัวแยกจากกัน บางอย่างเช่นการโทรกลับ onContactSeparate เมื่อเกิดการชนกัน ฉันไม่ต้องการจุดตัด - person Daniel Albert; 01.10.2015
comment
@DanielAlbert โอเค ใน cocos2d-x คุณจะได้รับสิ่งที่เรียกว่า EventListenerPhysicsContact คุณสามารถสร้างได้โดยใช้ฟังก์ชัน static create ในตัวฟังนี้คุณมี 4 ฟังก์ชั่นที่เปิดเผยสำหรับการแก้ปัญหาการติดต่อ onContactBegin, onContactPreSolve และ onContactSeperate กำหนดการโทรกลับให้กับ onContactSeperate และวางตรรกะของคุณสำหรับการแยกไว้ที่นั่น ตรวจสอบให้แน่ใจว่า onContactBegin ของคุณส่งคืนค่า false เพื่อให้คุณสามารถเพิกเฉยต่อปฏิกิริยาการชนกัน (ถ้าคุณต้องการ) - person Filled Stacks; 02.10.2015
comment
แต่หากฉันคืนค่าเท็จใน onContactBegin การโทรกลับ onContactSeparate จะไม่ถูกเรียก จะถูกเรียกก็ต่อเมื่อ onContactBegin ส่งคืนค่าจริง ถ้าฉันคืนค่าจริงในวิธี onContactBegin การชนกันของวัตถุทั้งสองและลูกบอลไม่ข้ามผู้ขัดขวาง - person Daniel Albert; 02.10.2015
comment
@DanielAlbert โปรดดูคำตอบที่แก้ไขด้านบน ฉันปรับใช้พฤติกรรมที่คุณต้องการและอธิบายว่าฉันทำอย่างไรในการแก้ไข - person Filled Stacks; 02.10.2015