มีอัลกอริทึมสำหรับเกมพูลหรือไม่?


14

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

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

ฉันต้องการฝึกการเขียนโค้ด Java ดังนั้นฉันกำลังมองหารหัสจาวาหรือแพ็คเกจที่มีรหัสประเภทนี้


2
ถ้าคุณต้องการแก้ปัญหาด้วยตัวเองคุณอาจต้องได้ความรู้เกี่ยวกับเวกเตอร์บ้าง โชคดีที่มีคนโพสต์คำแนะนำเกี่ยวกับคณิตศาสตร์เชิงเส้นที่อื่นในเว็บไซต์นี้เมื่อวันก่อน
doppelgreener

เว็บไซต์นี้อาจจะช่วยให้คุณสามารถarchive.ncsa.illinois.edu/Classes/MATH198/townsend/...

คำตอบ:


8

ในขณะที่การตรวจจับ / การตอบสนองการปะทะกันของทรงกลมพื้นฐานนั้นค่อนข้างง่ายการทำอย่างถูกต้องเพียงพอสำหรับการจำลองสระว่ายน้ำที่ดีนั้นจะยุ่งยากมากขึ้นตามที่คุณต้องจัดการกับการหมุน

คุณรู้หรือไม่ว่าเครื่องยนต์ฟิสิกส์มีอยู่จริงหรือไม่? ตัวอย่างที่ได้รับความนิยม ได้แก่ : อาจเป็นทางเลือกที่ดีสำหรับการสร้างเกมพูล แต่ไม่มากสำหรับการเรียนรู้ Java ...

ในแบบ 2D

Box2D: http://www.box2d.org

Chipmunk: http://code.google.com/p/chipmunk-physics/

ในแบบ 3 มิติ

กระสุน: http://bulletphysics.org/

ODE: http://www.ode.org

หากคุณกำลังทำเกมเชิงพาณิชย์ขนาดใหญ่:

Havok: http://www.havok.com


1
ข้อใดบ้างที่เป็นเอ็นจิ้นฟิสิกส์ของ Java
Ricket

มีพอร์ต Java ของหรืออย่างน้อยผูกสำหรับ Box2D, Chipmunk, Bullet และ ODE
bluescrn

6

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


2

สำหรับเกมพูลแบบง่าย ๆ ที่ไม่มีการสปินแบบอัลกอริทึมนั้นค่อนข้างง่าย

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

ในรหัสเทียมจะกลายเป็น:

vector difference = ball2.position - ball1.position
float distance = sqrt(difference)
if (distance < ball1.radius + ball2.radius) {
    vector normal = difference / distance
    //vector velocityDelta = ball2.velocity - ball1.velocity
    vector velocityDelta = ball1.velocity - ball2.velocity

    float dot = dotProduct(velocityDelta, normal)

    if (dot > 0) {
        float coefficient = 0.5
        float impulseStrength = (1 + coefficient) * dot * (1 / ball1.mass + 1 / ball2.mass)
        vector impulse = impulseStrength * normal
        ball1.velocity -= impulse / ball1.mass
        ball2.velocity += impulse / ball2.mass
    }
}

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

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


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

@Poldie หากจุดนั้นเป็นลบลูกบอลจะเคลื่อนที่ไปจากกันและกัน ไม่จำเป็นต้องจัดการกับการชนในกรณีนั้น
msell

ฉันเพิ่งเคาะรหัสรุ่นของคุณที่นี่: ideone.com/DhsAoWและฉันได้รับ -0.707 สำหรับตำแหน่ง 110,90 และ 100,100 และความเร็ว 0,2 และ 0, -3 นี่คือการชนกันของข้อมูลแบบ head-on มากขึ้นหรือน้อยลง (สมมติว่าการตรวจจับการชนกันของรัศมีเริ่มต้นเกิดขึ้นแล้ว)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.