निरंतर गति के साथ 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);

तो यह मेरी वस्तु को 1 सेकंड में बिंदु 0 से बिंदु 1 तक ले जाता है। मुझे जो 2 की आवश्यकता है, वह बिंदु 0 से ऑब्जेक्ट को स्थानांतरित करने में सक्षम होने के लिए, स्थिर गति के साथ बिंदु 1 का सामना करना (दिशा में) है। इस प्रकार, जब मेरे पास मेरे प्रारंभिक बिंदु के करीब एक बिंदु होता है, तो वस्तु उसी गति से उस ओर बढ़ेगी जैसा कि वह करता है यदि मेरे पास एक दूर बिंदु होगा। किसी भी सुझाव की सराहना की है। धन्यवाद।


संभावित डुप्लिकेट: gamedev.stackexchange.com/questions/23430/… मैं वही उत्तर दूंगा जो मैंने दूसरे प्रश्न को दिया था। लेकिन यह मेरे हिस्से की बेशर्मी होगी।
गुस्तावो मैकिएल

जवाबों:


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;
    }
}

त्वरित वेक्टर ऑपरेशन संदर्भ

प्रतिनिधित्व

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
@ फाफोल इसीलिए मैंने अंत में वैक्टर पर स्पष्टीकरण दिया। जवाब जेनेरिक होना चाहिए था। यदि आपके पास वेक्टर क्लास नहीं है, तो दो अलग-अलग फ़्लोट का उपयोग करें। मसलन Vector2 start;बन जाता है float startX, startY;। और आप आसानी से दूरी की गणना आसानी से कर सकते हैं, जैसे कि मैं अंत में समझाता हूं। Ie float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);
डेविड गाविया

@ फाफोल संपादित की जाँच करें, मैंने एक उदाहरण जोड़ा। मुझे यकीन नहीं है कि अगर मैं कुछ याद किया।
डेविड गाविया

3 साल बाद और आपने मुझे समझा दिया कि कैसे वैक्टर के साथ वस्तुओं को स्थानांतरित किया जाए। चीयर्स!
ओलिवर शॉनिंग

3

एक वेक्टर बनाएं और इसे सामान्य करें। चेतावनी, गलत संख्याओं के साथ कुछ छद्म कोड आगे:

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

यह आपको एक वेक्टर देगा जैसे:

25.96; 85.41

अब वेक्टर को सामान्य करें, और आप इसे प्राप्त करेंगे :

0.12; 0.75

यहाँ से आपके डेल्टा के साथ भी यही आंदोलन है।


2

मेरे उत्तर से कॉपी और पेस्ट किया गया: दो बिंदुओं के बीच एक रेखा पर अंक प्राप्त करें

स्यूडोकोड में:

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
}

इस उत्तर ने मेरे उपयोग के मामले में सबसे अच्छा काम किया।
शेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.