ฉันจะทำให้หางงูเป็นไปตามหัวได้อย่างไร


10

ทำตามการมอบหมายและเพิ่งเริ่มต้นกับlibGDXโดยการสร้าง Snake clone ขนาดเล็กที่ฉันพบเจอปัญหาที่ฉันอาจจะละอายใจในระยะเวลาหนึ่ง

ขณะนี้ฉันมีหัวงู (สี่เหลี่ยมเรียบง่ายในขั้นตอนนี้) เคลื่อนที่ไปทั่วผืนผ้าใบของเกม วิธีที่ตรงไปตรงมาที่สุดในการสร้างส่วนที่เหลือของงูนั้นคือการมีหัวของตัวเองเป็น Java Collections LinkedList รายการของ SnakeElements ซึ่งจะลดขนาด / ตามขนาดของสิ่งที่ผู้เล่นทำ

มีรายการ SnakeElements นี้ตามหัว แต่ได้พิสูจน์แล้วว่าไม่น่ารำคาญ

ฟังก์ชั่นปัจจุบันการทำเช่นนี้มีดังต่อไปนี้และถูกเรียกว่าทุกครั้งที่หัวหน้าอัพเดตตำแหน่ง:

private void moveTail (float x, float y, int direction) {
    float tmpx, tmpy;
    int tmpdirection;
    int offset_x, offset_y;

    for (SnakeSegment snse : tail) {
        offset_x = 0;
        offset_y = 0;

        tmpx = snse.getX();
        tmpy = snse.getY();
        tmpdirection = snse.getDirection();

        switch(direction) {
            case 0:
                offset_x = 0;
                offset_y = -(2 + snse.width);
                break;
            case 1:
                offset_x = -(2 + snse.width);
                offset_y = 0;
                break;
            case 2:
                offset_x = 0;
                offset_y = (2 + snse.width);
                break;
            case 3:
                offset_x = (2 + snse.width);
                offset_y = 0;
                break;
            default:
                System.out.println("wrong direction");
        }

        snse.setX(x + offset_x);
        snse.setY(y + offset_y);
        snse.setDirection(direction);

        x = tmpx;
        y = tmpy;
        direction = tmpdirection;
    }
}

ซึ่งน่าเสียดายที่ผลลัพธ์ในพฤติกรรมนี้:

GIF

เคล็ดลับใด ๆ เกี่ยวกับวิธีการทำให้หางงูทำงานอย่างถูกต้องจะได้รับการชื่นชมมาก :)

คำตอบ:


18

ลองนึกถึงปัญหาเช่นนี้
งูในเกมเริ่มต้นอย่างไร?
งูเคลื่อนที่ไปในทิศทางปัจจุบัน พฤติกรรมดูเหมือนว่าศีรษะไม่ปรากฏอะไรเลยส่วนหางสุดท้ายก็หายไป

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


โอ้โหขอบคุณ! มันสมเหตุสมผลมากและน่าจะเป็นความคิดตั้งแต่เริ่มต้นดูเหมือนว่าฉันจะได้รับการฟื้นฟูใหม่ ๆ :) ฉันแค่ขอโทษกรรมจำนวนเศร้าที่ทำให้ฉันไม่อยากถอน ฉันสัญญาว่าฉันจะกลับมาอีกในอนาคต!
Kilian

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

2
นี่เป็นเวอร์ชั่นปัจจุบันตามทางขอขอบคุณอีกครั้ง :) i.imgur.com/IaT5PNH.gif
Kilian

1

วิธีที่ฉันเห็นมันเป็นเหมือน "หนอน" เหมือนระบบที่งูแต่ละส่วนตามมาข้างหน้า

กล่าวอีกนัยหนึ่งงูแต่ละส่วนจะเป็นวัตถุที่มีตำแหน่ง (x, y)ซึ่งเป็นการอ้างอิงไปยังส่วนที่อยู่ข้างหน้าว่ามันจะใช้เพื่อเลื่อนไปรอบ ๆ และฟังก์ชั่นในการประมวลผลตำแหน่งของส่วนข้างหน้าและ ย้ายตาม งูหลัก (หัว) ควรมีการอ้างอิงสำหรับทุกส่วนของงูและจะเรียกหน้าที่ที่รับผิดชอบในการทำให้ส่วนนี้เป็นไปตามบรรพบุรุษของมันโดยเป็นหัวหน้าผู้บุกเบิกของส่วนแรก
หวังว่ามันจะช่วย!


นี่เป็นความคิด แต่การจัดการมุมกลายเป็นเรื่องที่ค่อนข้างซับซ้อน และจะเกิดอะไรขึ้นหากผู้เล่นหันมุม 180 องศาที่คมชัด เราไม่แน่ใจว่าจะจัดการกับสิ่งนี้ได้อย่างถูกต้องและใช้วิธีการตามที่อธิบายโดย Pontus Magnusson แก้ปัญหาเหล่านี้ได้อย่างดี
Kilian

ฉันเห็น. ครั้งเดียวที่ฉันติดตั้งระบบ caterpillar ฉันมีตารางกับเซลล์ตามขนาดของชิ้นส่วนดังนั้นแต่ละส่วนจะอยู่ในเซลล์เดียวเสมอด้วยวิธีนี้ปัญหาไม่ได้เกิดขึ้น ขอโทษสำหรับภาษาอังกฤษที่ไม่ดีของฉัน
Lince Assassino

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