ฉันจะสร้างวงสวิงในเกม platformer ได้อย่างไร?


9

ฉันกำลังพัฒนาเกมที่ผู้เล่นสามารถใช้เชือกในการแกว่ง (เช่นเดียวกับที่ Spiderman หรือBionic Commandoทำ) และฉันมีปัญหาในการใช้พฤติกรรมนี้ ทุกคนสามารถช่วยฉันได้อย่างไรฉันหมายถึงสูตรฟิสิกส์และอื่น ๆ จนถึงตอนนี้ฉันมี 3 แนวคิด มีใครใช้สปริง แต่ก็กินเวลาเยอะและบางครั้งก็น่ากลัว อีกสองคนกำลังพยายามคำนวณขั้นตอนต่อไป (อันหนึ่งผ่านการคำนวณพลังงานที่มีศักยภาพและอีกอันผ่านการคำนวณแรงบิด) และทั้งคู่ก็เกือบจะชนกันทุกครั้งที่นักแสดงพยายามแกว่ง

นี่คือรหัสที่ฉันเขียนเพื่อคำนวณแรงบิด:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

ที่เกี่ยวข้อง (ในการทำเชือก): การตรวจจับการชนกันของเชือก 2 มิติ
doppelgreener

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

ลูกตุ้มง่าย ๆ สำหรับเชือก + ภาพเคลื่อนไหวบางอย่างที่ทำให้เกิดการเล่นเชือก ฉันไม่เชื่อว่าเกมเก่า ๆ อย่าง Bionic Commando มีสิ่งอื่นใดนอกจากลูกตุ้ม
user712092

@ ผู้ใช้ที่ความคิดลูกตุ้มควรทำงานได้ดี แต่ในกรณีของฉันเนื่องจากการเคลื่อนไหวที่รวดเร็วของผู้เล่นหรือการนำไปใช้ที่ไม่ดีของฉันมันไม่ได้ให้ผลลัพธ์ที่ดี
Ali1S232

@Gajet พยายามทำการวาดภาพ debug บางส่วนจนกว่าจะทำให้ถูกต้อง? เส้นลูกตุ้มนี้อาจทำในรูปแบบกล่องที่บางพอใน Box2D เพื่อชน (และอาจแยกออกจากฟิสิกส์และเคลื่อนที่ด้วยมือ?)
user712092

คำตอบ:


6

หากคุณต้องการการแกว่งที่มั่นคงดังนั้นระยะทางถึงจุดหมุนจะคงที่เพียงแค่ถือตัวละครเป็นจุดบนวงกลมที่อยู่ตรงกลางที่จุดหมุน ให้ความเร็วเชิงมุมหนึ่งมิติ (ตามวงกลม) กับเขา แต่ละเฟรมควรมีการเร่งความเร็วเชิงมุมaccelerationDueToGravity * cos(angleOfPlayerOnCircle)(โดยชี้ไปทางขวา 0 องศา)

หากคุณต้องการให้เชือกยาวขึ้นหรือสั้นลงคุณสามารถใช้รูปแบบข้างต้นและเปลี่ยนรัศมีในแต่ละเฟรม


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

3

หลังจากพยายามหลายครั้งฉันก็ไปกับ box2d

มี generaly สองคนเห็นด้วยกับการจำลองนี้หรืออย่างน้อยฉันก็พบว่า 2:

  1. หนึ่งคือการใช้รูปร่างวงกลมและเชื่อมต่อพวกเขาโดยใช้ข้อต่อที่ห่างไกล
  2. และอีกอันหนึ่งก็คือการหารูปสี่เหลี่ยมสำหรับโซ่นั้นจากนั้นจึงใช้ข้อต่อที่หมุนรอบได้

ใน senario แต่ละอันคุณต้องมี ancher (ซึ่งในกรณีของฉันคือกล่องคงที่) มันจะดีกว่าถ้าคุณลดน้ำหนักของส่วนเชือก (ไม่ว่าคุณจะใช้รูปทรงวงกลมหรือรูปสี่เหลี่ยมผืนผ้า) ตัวอย่างเช่นมีฟิสิกส์ที่เหมือนจริงมากขึ้นฉันตั้งความหนาแน่นไว้ที่ 0.1 และสำหรับกล่องที่ต่อท้ายเชือกฉันใช้ความหนาแน่น 10

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

สิ่งต่อไปที่คุณต้องกังวลคือจำนวนการทำซ้ำที่คุณกำลังอัพเดททั่วโลก: สำหรับส่วนของเชือกที่ต่ำ (อาจจะมากที่สุด 8) ไม่จำเป็นต้องใช้ค่าการทำซ้ำสูงบางที 10/10 ซึ่ง box2d แนะนำตัวเอง ก็เพียงพอแล้ว แต่ถ้าคุณเพิ่มจำนวนเซกเมนต์เช่นฉันลอง 30 เซกเมนต์ด้วยการวนซ้ำที่น้อยดูเหมือนว่าเชือกของคุณจะเพิ่มความยาวได้มากกว่าที่ควรดังนั้นคุณต้องมีการซ้ำ 40/40 เพื่อแก้ไขสถานการณ์เหล่านั้น

หลังจากการทดสอบบางอย่างดูเหมือนว่ากล่อง 2d ได้รับการออกแบบมาสำหรับฉากที่มีขนาดวัตถุ 0.1m ถึง 10m และขนาดสูงสุดที่แนะนำสำหรับฉากขนาดใหญ่คือบางสิ่งประมาณ 50mx50m ดังนั้นพื้นฐานคุณต้องปรับขนาดวัตถุของคุณลงเพื่อให้ตรงกับพารามิเตอร์เหล่านี้ ในกรณีของฉันฉันแรกพยายามส่งตำแหน่งพิกเซลโดยตรงกับ box2d แต่ดูเหมือนว่ามีข้อ จำกัด ความเร็วในการป้องกันไม่ให้โลกเคลื่อนที่เร็วเท่าที่ควรดังนั้นฉันต้องปรับขนาดฉากของฉันประมาณ 64 ครั้งเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด แม้ว่าฉันจะไม่ได้ทดสอบตัวเอง แต่ก็มีข้อ จำกัด บางอย่างใน box2d ที่ป้องกันไม่ให้คุณใช้ฉากขนาดใหญ่ ตัวอย่างเช่นมีค่าที่กำหนดในb2Setting.hไฟล์#define b2_maxTranslation 2.0fคุณสามารถเปลี่ยนการตั้งค่า box2d แต่ดูเหมือนว่าไม่แนะนำ


ทำไมต้องใช้ box2d เพื่อรับ downvote ให้ฉันด้วย
Ali1S232

สิ่งนี้ไม่ตอบคำถาม อย่างน้อยก็เขียนวิธีที่คุณใช้งาน Box2D
bummzack

@bummzack: ตกลงฉันจะเพิ่มคำตอบของฉัน
Ali1S232

หากคุณยอมรับสิ่งนี้เป็นคำตอบของคุณคำถามของคุณหากมีข้อบกพร่อง ฟิสิกส์เชือกแบ่งส่วนนั้นแตกต่างจากที่คุณอธิบายไว้มาก
AttackHobo

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

2

คุณคิดว่าการชะลอความเร็วของการเคลื่อนที่แบบสวิงนั้นขึ้นอยู่กับว่าเชือกมาจากแนวลูกดิ่ง (กลาง) หรือไม่?


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

ยิ่งห่างจากจุดศูนย์กลางมากเท่าใดความล่าช้าก็จะยิ่งนานขึ้นก่อนที่การเคลื่อนที่ของแกว่งเชือกครั้งต่อไปจะเกิดขึ้น คุณสามารถคูณค่า ABSolute ของการหน่วงเวลาด้วยค่าอย่าง 0.28 (คุณจะต้องทดลองกับสิ่งนี้)
Randolf Richardson

ฉันไม่สามารถหาสิ่งที่คุณพยายามจะพูดได้เมื่อฉันคำนวณขั้นตอนถัดไปฉันมีค่าคงที่สำหรับ delta_time และใช้พารามิเตอร์ทั้งหมดที่ฉันมี (เช่นความเร็ว previus ตำแหน่ง previes ความยาวเชือก ฯลฯ ) เพื่อคำนวณ ความเร็วใหม่แล้วเพิ่มความเร็วนี้คูณด้วย delta_time ไปยังตำแหน่งสุดท้ายเพื่อสร้างตำแหน่งใหม่ หากคุณหมายถึงสิ่งอื่นใดโปรดระบุรายละเอียดทั้งหมดในคำตอบของคุณ
Ali1S232

1

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

เมื่อติดเชือกแล้ว บันทึกmaxLengthค่า

แต่ละการอัปเดตตรวจสอบdistanceระหว่างplayerและattachPoint

หากdistanceน้อยกว่าการmaxLengthอัพเดทตามปกติจะไม่มีผลกระทบจากเชือก

หากระยะทางที่มากกว่าmaxLengthหาnormalจากattachPointให้กับผู้เล่น ได้รับความแตกต่างระหว่างและdistance maxLengthเพิ่มplayerVelocity, normalคูณด้วยความแตกต่าง

รหัสหลอก:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

ดังนั้นรหัสที่ฉันแก้ไขลงในคำตอบของคุณ (ขออภัยเกี่ยวกับเรื่องนั้น แต่ฉันไม่พบที่ที่ดีกว่าในการเพิ่ม) ที่คุณแนะนำ
Ali1S232

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

หลังจากพยายามผมคิดว่าผมจะไปพยายาม box2d สำหรับปัญหานี้และโดยวิธีการที่คุณจะต้องเปลี่ยนรหัสว่าเพื่อให้คุณมีและdx = player.x - attachpoint.x dy = player.y - attachpoint.y
Ali1S232

1

หากคุณดูที่http://www.cocos2d-iphone.org/archives/1112จะมีการติดตั้งเชือกที่มีลำตัวที่แข็งแรงติดกับปลายเชือก มันใช้ Box2D สำหรับเครื่องยนต์ฟิสิกส์ หากคุณดูซอร์สโค้ดฉันแน่ใจว่าคุณสามารถใช้มันในภาษาใดก็ได้ที่คุณต้องการ

นอกจากนี้ลิงก์ด้านบนไปยังคำถาม Rope คือของฉันและการสาธิตนี้ (ลิงก์ที่ให้ไว้) ด้านบนช่วยได้จริงๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.