บอลฟิสิกส์: ทำให้การเด้งสุดท้ายเป็นไปอย่างราบรื่นเมื่อลูกบอลหยุดนิ่ง


12

ฉันได้เจอกับปัญหาอื่นในเกมลูกบอลกระดอนเล็ก ๆ ของฉัน

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

ฉันเข้าใจได้ว่าทำไมสิ่งนี้ถึงเกิดขึ้น แต่ฉันไม่สามารถทำให้มันราบรื่น

ฉันจะขอบคุณสำหรับคำแนะนำใด ๆ ที่สามารถนำเสนอ

รหัสอัพเดทของฉันคือ:

public void Update()
    {
        // Apply gravity if we're not already on the ground
        if(Position.Y < GraphicsViewport.Height - Texture.Height)
        {
            Velocity += Physics.Gravity.Force;
        }            
        Velocity *= Physics.Air.Resistance;
        Position += Velocity;

        if (Position.X < 0 || Position.X > GraphicsViewport.Width - Texture.Width)
        {
            // We've hit a vertical (side) boundary
            // Apply friction
            Velocity *= Physics.Surfaces.Concrete;

            // Invert velocity
            Velocity.X = -Velocity.X;
            Position.X = Position.X + Velocity.X;
        }

        if (Position.Y < 0 || Position.Y > GraphicsViewport.Height - Texture.Height)
        {
            // We've hit a horizontal boundary
            // Apply friction
            Velocity *= Physics.Surfaces.Grass;

            // Invert Velocity
            Velocity.Y = -Velocity.Y;
            Position.Y = Position.Y + Velocity.Y;
        }
    }

บางทีฉันควรจะชี้ให้เห็นว่าGravity, Resistance GrassและมีทุกประเภทConcreteVector2


เพื่อยืนยันสิ่งนี้: "แรงเสียดทาน" ของคุณเมื่อลูกบอลกระทบกับพื้นผิวเป็นค่า <1 ซึ่งโดยทั่วไปค่าสัมประสิทธิ์ของการแก้ไขถูกต้อง?
Jorge Leitao

@ JCLeitão - ถูกต้อง
Ste

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

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

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

คำตอบ:


19

นี่คือขั้นตอนที่จำเป็นสำหรับการพัฒนาลูปจำลองฟิสิกส์ของคุณ

1. การประทับเวลา

ปัญหาหลักที่ฉันเห็นด้วยรหัสของคุณก็คือมันไม่ได้คำนึงถึงขั้นตอนทางฟิสิกส์ ควรชัดเจนว่ามีสิ่งผิดปกติเกิดขึ้นPosition += Velocity;เนื่องจากหน่วยไม่ตรงกัน ไม่ว่าVelocityจะเป็นความเร็วหรือสิ่งที่ขาดหายไป

แม้ว่าค่าความเร็วและแรงโน้มถ่วงของคุณจะถูกปรับอัตราส่วนให้แต่ละเฟรมเกิดขึ้นที่หน่วยเวลา1(หมายความว่าเช่น Velocityหมายถึงระยะทางที่เดินทางในหนึ่งวินาที) เวลาจะต้องปรากฏที่ใดที่หนึ่งในรหัสของคุณโดยปริยาย (โดยการแก้ไขตัวแปรเพื่อให้ ชื่อของพวกเขาสะท้อนให้เห็นถึงสิ่งที่พวกเขาเก็บจริง ๆ ) หรืออย่างชัดเจน (โดยการแนะนำการประทับเวลา) ฉันเชื่อว่าสิ่งที่ง่ายที่สุดที่จะทำคือการประกาศหน่วยเวลา:

float TimeStep = 1.0;

และใช้ค่านั้นในทุกที่ที่ต้องการ:

Velocity += Physics.Gravity.Force * TimeStep;
Position += Velocity * TimeStep;
...

โปรดทราบว่าคอมไพเลอร์ที่เหมาะสมจะลดความซับซ้อนของการคูณด้วย1.0ดังนั้นส่วนนั้นจะไม่ทำให้ช้าลง

ตอนนี้Position += Velocity * TimeStepยังไม่แน่นอน (ดูคำถามนี้เพื่อทำความเข้าใจว่าทำไม) แต่ตอนนี้อาจจะทำได้

นอกจากนี้ต้องคำนึงถึงเวลาด้วย:

Velocity *= Physics.Air.Resistance;

มันค่อนข้างยากที่จะแก้ไข วิธีหนึ่งที่เป็นไปได้คือ:

Velocity -= Vector2(Math.Pow(Physics.Air.Resistance.X, TimeStep),
                    Math.Pow(Physics.Air.Resistance.Y, TimeStep))
          * Velocity;

2. อัพเดตสองเท่า

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

Position += Velocity * TimeStep;
if (Position.Y < 0)
{
    Velocity.Y = -Velocity.Y * Physics.Surfaces.Grass;
    Position.Y = Position.Y + Velocity.Y * TimeStep;
}

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

Position += Velocity * TimeStep;
if (Position.Y < 0)
{
    /* First, stop at Y = 0 and count how much time is left */
    float RemainingTime = -Position.Y / Velocity.Y;
    Position.Y = 0;

    /* Then, start from Y = 0 and only use how much time was left */
    Velocity.Y = -Velocity.Y * Physics.Surfaces.Grass;
    Position.Y = Velocity.Y * RemainingTime;
}

3. แรงโน้มถ่วง

ตรวจสอบส่วนนี้ของรหัสตอนนี้:

if(Position.Y < GraphicsViewport.Height - Texture.Height)
{
    Velocity += Physics.Gravity.Force * TimeStep;
}            

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

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

4. รหัสคงที่

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

public void Update()
{
    float TimeStep = 1.0;
    Update(TimeStep);
}

public void Update(float TimeStep)
{
    float RemainingTime;

    // Apply gravity if we're not already on the ground
    if(Position.Y < GraphicsViewport.Height - Texture.Height)
    {
        Velocity += Physics.Gravity.Force * TimeStep;
    }
    Velocity -= Vector2(Math.Pow(Physics.Air.Resistance.X, RemainingTime),
                        Math.Pow(Physics.Air.Resistance.Y, RemainingTime))
              * Velocity;
    Position += Velocity * TimeStep;

    if (Position.X < 0 || Position.X > GraphicsViewport.Width - Texture.Width)
    {
        // We've hit a vertical (side) boundary
        if (Position.X < 0)
        {
            RemainingTime = -Position.X / Velocity.X;
            Position.X = 0;
        }
        else
        {
            RemainingTime = (Position.X - (GraphicsViewport.Width - Texture.Width)) / Velocity.X;
            Position.X = GraphicsViewport.Width - Texture.Width;
        }

        // Apply friction
        Velocity -= Vector2(Math.Pow(Physics.Surfaces.Concrete.X, RemainingTime),
                            Math.Pow(Physics.Surfaces.Concrete.Y, RemainingTime))
                  * Velocity;

        // Invert velocity
        Velocity.X = -Velocity.X;
        Position.X = Position.X + Velocity.X * RemainingTime;
    }

    if (Position.Y < 0 || Position.Y > GraphicsViewport.Height - Texture.Height)
    {
        // We've hit a horizontal boundary
        if (Position.Y < 0)
        {
            RemainingTime = -Position.Y / Velocity.Y;
            Position.Y = 0;
        }
        else
        {
            RemainingTime = (Position.Y - (GraphicsViewport.Height - Texture.Height)) / Velocity.Y;
            Position.Y = GraphicsViewport.Height - Texture.Height;
        }

        // Remove excess gravity
        Velocity.Y -= RemainingTime * Physics.Gravity.Force;

        // Apply friction
        Velocity -= Vector2(Math.Pow(Physics.Surfaces.Grass.X, RemainingTime),
                            Math.Pow(Physics.Surfaces.Grass.Y, RemainingTime))
                  * Velocity;

        // Invert velocity
        Velocity.Y = -Velocity.Y;

        // Re-add excess gravity
        float OldVelocityY = Velocity.Y;
        Velocity.Y += RemainingTime * Physics.Gravity.Force;
        // If velocity changed sign again, clamp it to zero
        if (Velocity.Y * OldVelocityY <= 0)
            Velocity.Y = 0;

        Position.Y = Position.Y + Velocity.Y * RemainingTime;
    }
}

5. การเพิ่มเติมเพิ่มเติม

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

public void Update()
{
    float TimeStep = 1.0;
    Update(TimeStep / 4);
    Update(TimeStep / 4);
    Update(TimeStep / 4);
    Update(TimeStep / 4);
}

"เวลาจะต้องปรากฏที่ใดที่หนึ่งในรหัสของคุณ" คุณกำลังโฆษณาที่คูณด้วย 1 ทั่วทุกมุมไม่ใช่แค่ความคิดที่ดี แน่นอนว่าการประทับเวลาที่ปรับได้นั้นเป็นคุณสมบัติที่ดี แต่แน่นอนว่ามันไม่ใช่ข้อบังคับ
aaaaaaaaaaaa

@eBusiness: อาร์กิวเมนต์ของฉันมีความสอดคล้องและตรวจจับข้อผิดพลาดได้มากกว่าการปรับเวลา ฉันไม่ได้หมายถึงการคูณด้วย 1 เป็นสิ่งจำเป็นฉันกำลังบอกว่าvelocity += gravityผิดและมีvelocity += gravity * timestepเหตุผลเท่านั้น อาจให้ผลลัพธ์เดียวกันในที่สุด แต่ไม่มีความคิดเห็นว่า "ฉันรู้ว่าสิ่งที่ฉันทำที่นี่" ยังคงหมายถึงข้อผิดพลาดการเขียนโปรแกรมโปรแกรมเมอร์เลอะเทอะขาดความรู้เกี่ยวกับฟิสิกส์หรือรหัสต้นแบบที่ต้อง ได้รับการปรับปรุง
sam hocevar

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

2
@eBusiness: ตรงไปตรงมาก็คือผิดโดยมาตรฐานสติใด ๆ รหัสไม่ได้“ ทำตามที่ตั้งใจ” เพราะทั้งหมด 1) การเพิ่มความเร็วและแรงโน้มถ่วงไม่ได้มีความหมายอะไรเลย และ 2) ถ้ามันให้ผลลัพธ์ที่สมเหตุสมผลมันเป็นเพราะค่าที่เก็บไว้ในgravityนั้นจริง ๆ แล้ว… ไม่ใช่แรงโน้มถ่วง แต่ฉันสามารถทำให้ชัดเจนยิ่งขึ้นในโพสต์
sam hocevar

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

6

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

MIN_BOUNCE = <0.01 e.g>;

if( Velocity.Y < MIN_BOUNCE ){
    Velocity.Y = 0;
    Position.Y = <ground position Y>;
}

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

@ แบรนดอนดีมากมันควรจะทำงานได้ดีกว่าปกติ
Zhen

1
@Zhen ถ้าคุณใช้พื้นผิวตามปกติคุณมีโอกาสที่คุณจะมีลูกที่เกาะติดกับพื้นผิวที่มีลักษณะปกติที่ไม่ขนานกับแรงโน้มถ่วง ฉันจะลองและคำนวณแรงโน้มถ่วงในการคำนวณถ้าเป็นไปได้
Nic Foster

วิธีแก้ปัญหาเหล่านี้ไม่ควรตั้งค่าความเร็วใด ๆ เป็น 0 คุณ จำกัด การสะท้อนข้ามเวกเตอร์ตามปกติโดยขึ้นอยู่กับเกณฑ์การตีกลับเท่านั้น
แบรนดอน

1

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

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

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

@ คำตอบเมื่อไรก็คงดีถ้าระบบของคุณเหมือนกันซึ่งไม่ใช่ มันมีแรงโน้มถ่วงบนแกน y

ดังนั้นฉันจะบอกว่าการแก้ปัญหาจะไม่เป็นไปได้ว่าความเร็วควรจะต่ำกว่าเกณฑ์ที่กำหนด แต่แรงทั้งหมดที่ใช้กับลูกบอลหลังจากการอัพเดทควรจะต่ำกว่าเกณฑ์ที่กำหนด

แรงนั้นคือการมีส่วนร่วมของแรงที่กระทำโดยผนังบนลูกบอล + แรงโน้มถ่วง

เงื่อนไขนั้นควรเป็นสิ่งที่ต้องการ

ถ้า (newVelocity + Physics.Gravity.Force <threshold)

โปรดสังเกตว่า newVelocity.y เป็นปริมาณบวกถ้าการตีกลับอยู่บนกำแพง botton และแรงโน้มถ่วงเป็นปริมาณลบ

นอกจากนี้โปรดสังเกตว่า newVelocity and Physics.Gravity.Force ไม่มีมิติเดียวกันกับที่คุณเขียน

Velocity += Physics.Gravity.Force;

หมายความว่าเหมือนคุณฉันสมมติว่า delta_time = 1 และ ballMass = 1

หวังว่านี่จะช่วยได้


1

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

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

วิธีง่ายๆในการแก้ไขปัญหานี้คือการตรวจสอบว่าลูกบอลเคลื่อนที่ไปในทิศทางที่ถูกต้องก่อนที่จะทำการเปลี่ยนแปลง

ดังนั้นคุณควรทำ:

if (Position.X < 0 || Position.X > GraphicsViewport.Width - Texture.Width)

เป็น:

if ((Position.X < 0 && Velocity.X < 0) || (Position.X > GraphicsViewport.Width - Texture.Width && Velocity.X > 0))

และคล้ายกับทิศทาง Y

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

Velocity += Physics.Gravity.Force;
if(Position.Y > GraphicsViewport.Height - Texture.Height && Velocity.Y > 0)
{
    Velocity.Y = 0;
}

การเปลี่ยนแปลงทั้งหมดนี้ควรให้การจำลองที่ดีแก่คุณ แต่โปรดทราบว่ามันยังคงเป็นการจำลองที่ง่ายมาก


0

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

public Vector3 Velocity
{
    public get { return velocity; }
    public set
    {
        velocity = value;

        // We get the direction that gravity pulls in
        Vector3 GravityDirection = gravity;
        GravityDirection.Normalize();

        Vector3 VelocityDirection = velocity;
        VelocityDirection.Normalize();

        if ((velocity * GravityDirection).SquaredLength() < 0.25f)
        {
            velocity.Y = 0.0f;
        }            
    }
}
private Vector3 velocity;

ในวิธีการข้างต้นเรา จำกัด การตีกลับเมื่อใดก็ตามที่มันอยู่ในแกนเดียวกันกับแรงโน้มถ่วง

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


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

พวกเขาเป็นหนึ่งเดียวกัน เอนจิ้นฟิสิกส์เช่น Havok หรือ PhysX และการซ่อมแซมฐาน JigLibX บนความเร็วเชิงเส้น (และความเร็วเชิงมุม) วิธีนี้ควรใช้ได้กับทุกการเคลื่อนไหวของลูกบอลรวมถึงการกระดอน อันที่จริงโครงการสุดท้ายที่ฉันใช้ (LEGO Universe) ใช้วิธีการแบบเดียวกับที่ทำเพื่อหยุดยั้งการตีกลับของเหรียญเมื่อพวกเขาชะลอตัวลง ในกรณีนี้เราไม่ได้ใช้ฟิสิกส์แบบไดนามิกดังนั้นเราต้องทำด้วยตนเองแทนที่จะปล่อยให้ Havok ดูแลมันให้กับเรา
Nic Foster

@NicFoster: ฉันสับสนตามความคิดของฉันวัตถุอาจเคลื่อนที่อย่างรวดเร็วในแนวนอนและแนวตั้งแทบจะไม่ในกรณีนี้วิธีการของคุณจะไม่เกิดขึ้นเลย ฉันคิดว่า OP ต้องการให้ระยะทางแนวตั้งตั้งค่าเป็นศูนย์แม้ว่าความยาวของความเร็วจะสูง
George Duckett

@GeorgeDuckett: อ่าขอบคุณฉันเข้าใจผิดคำถามเดิม OP ไม่ต้องการให้ลูกบอลหยุดเคลื่อนที่เพียงแค่หยุดการเคลื่อนที่ตามแนวตั้ง ฉันได้อัปเดตคำตอบสำหรับบัญชีเพื่อให้ได้ความเร็วที่สูงขึ้นเท่านั้น
Nic Foster

0

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

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