ย้ายจาก A (x, y) ไปยัง B (x1, y1) ด้วยความเร็วคงที่หรือไม่


21

ขณะนี้ฉันมีสิ่งที่ชอบ:

float deltaX = point0.getX() - point1.getX();
float deltaY = point0.getY() - point1.getY();

และทุกๆ 0.01 วินาทีฉันจะรีเฟรชตำแหน่งวัตถุของฉันเช่นนี้:

object.setPosition(object.getX()-deltaX/100,object.getY()-deltaY/100);

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


ซ้ำซ้อนที่เป็นไปได้: gamedev.stackexchange.com/questions/23430/… ฉันจะโพสต์คำตอบเดียวกับที่ฉันตอบคำถามอื่น แต่นี่จะไร้ยางอายในส่วนของฉัน
Gustavo Maciel

คำตอบ:


26

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

สมมติว่าคุณเริ่มต้นด้วยค่าเหล่านี้: startและendทำเครื่องหมายจุดสิ้นสุดของการเคลื่อนไหวspeedคือจำนวนพิกเซลที่ควรเคลื่อนที่ในแต่ละวินาทีและelapsedเป็นอัตราที่คุณจะอัปเดตตำแหน่งของวัตถุของคุณ ):

Vector2 start = new Vector2(x1, y2);
Vector2 end = new Vector2(x2, y2);
float speed = 100;
float elapsed = 0.01f;

สิ่งแรกที่คุณต้องการคำนวณคือระยะห่างระหว่างจุดทั้งสองกับเวกเตอร์ที่ทำให้เป็นมาตรฐานซึ่งมีทิศทางตั้งแต่ต้นจนจบ นอกจากนี้คุณควร "สแน็ป" ตำแหน่งวัตถุไปยังstartจุด ขั้นตอนนี้ทำได้เพียงครั้งเดียวในตอนเริ่มต้น:

float distance = Vector2.Distance(start, end);
Vector2 direction = Vector2.Normalize(end - start);
object.Position = start;
moving = true;

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

if(moving == true)
{
    object.Position += direction * speed * elapsed;
    if(Vector2.Distance(start, object.Position) >= distance)
    {
        object.Position = end;
        moving = false;
    }
}

การอ้างอิงการดำเนินการ Vector ด่วน

การแสดง

Vector2 A = float aX, aY;

ผลรวม / ลบ

A+B = a.x + b.x; a.y + b.y;
A-B = a.x - b.x; a.y - b.y;

ทวีคูณโดยสเกลาร์ (ลอย)

A*float = a.x*float; a.y*float;

ความยาว / ระยะทาง

length(A) = sqrt(a.x*a.x + a.y*a.y)
distance(A,B) = length(B-A)

ปกติ

normalize(A) = a.X/length(A); a.Y/length(A);

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


ตัวอย่างของการแปลง

// Your Variables
float startX, startY, endX, endY;
float speed = 100;
float elapsed = 0.01f;

// On starting movement
float distance = Math.sqrt(Math.pow(endX-startX,2)+Math.pow(endY-startY,2));
float directionX = (endX-startX) / distance;
float directionY = (endY-startY) / distance;
object.X = startX;
object.Y = startY;
moving = true;

// On update
if(moving == true)
{
    object.X += directionX * speed * elapsed;
    object.Y += directionY * speed * elapsed;
    if(Math.sqrt(Math.pow(object.X-startX,2)+Math.pow(object.Y-startY,2)) >= distance)
    {
        object.X = endX;
        object.Y = endY;
        moving = false;
    }
}

1
@Fofole นั่นเป็นเหตุผลที่ฉันให้คำอธิบายเกี่ยวกับเวกเตอร์ในตอนท้าย คำตอบนั้นควรจะเป็นคำทั่วไป หากคุณไม่มีคลาส Vector ให้ใช้การลอยสองแบบแยกกัน ยกตัวอย่างเช่นจะกลายเป็นVector2 start; float startX, startY;และคุณสามารถคำนวณระยะทางได้อย่างง่ายดายเหมือนที่ฉันอธิบายตอนท้าย float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);กล่าวคือ
David Gouveia

@Fafole ตรวจสอบการแก้ไขฉันเพิ่มตัวอย่าง ไม่แน่ใจว่าฉันพลาดบางอย่าง
David Gouveia

3 ปีต่อมาและคุณทำให้ฉันเข้าใจวิธีเคลื่อนย้ายวัตถุด้วยเวกเตอร์ ไชโย!
Oliver Schöning

3

สร้างเวกเตอร์และทำให้เป็นมาตรฐาน คำเตือนโค้ดหลอกบางอันที่มีตัวเลขผิดข้างหน้า:

Vector = new Vector(point0.getX() - point1.getX(), point0.getY() - point1.getY());

สิ่งนี้จะให้เวกเตอร์ที่คุณชอบ:

25.96; 85.41

ตอนนี้ทำให้เวกเตอร์เป็นปกติและคุณจะได้รับ :

0.12; 0.75

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


2

คัดลอกและวางจากคำตอบของฉันไปที่: รับคะแนนในบรรทัดระหว่างสองคะแนน

ใน Pseudocode:

speed_per_tick = 0.05 //constant speed you want the object to move at
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}

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