2012-04-29 18 views
5

मैं टाइल्स का उपयोग कर जावा गेम बना रहा हूं। मुझे टकराव तत्व में परेशानी हो रही है। मैं मानचित्र पर प्रत्येक टाइल के लिए आयताकार परिभाषित कर रहा हूं, और खिलाड़ी के लिए एक और आयत। मुझे क्या परेशानी हो रही है यह जानकर कि खिलाड़ी आयत को कब मारता है, और उसके बाद प्लेयर को उस दिशा में बंद कर देता है जिससे खिलाड़ी आया था। मैंने पहले ही एक विधि बनाई है जो यह जांचता है कि चरित्र आयत के अंदर कितना है, इसलिए यह जान सकता है कि इसे कितना धक्का देना है, लेकिन मैं यह नहीं समझ सकता कि चरित्र किस पक्ष से आ रहा है। टिप्पणी rect1 चरित्र है और rect2 टाइलजावा टाइल गेम - टकराव का पता लगाने

public void collision(Rectangle rect1, Rectangle rect2) { 
    float xAdd; 
    float xAdd2; 
    float yAdd; 
    float yAdd2; 

    boolean hitRight = false; 
    boolean hitLeft = false; 
    boolean hitTop = false; 
    boolean hitBot = false; 

    Vector2f rect1Origin = new Vector2f(rect1.x, rect1.y); 
    Vector2f rect2Origin = new Vector2f(rect2.x, rect2.y); 
    Vector2f rect1Mid = new Vector2f((rect1.x + rect1.width)/2,(rect1.y + rect1.height)/2); 
    Vector2f rect2Mid = new Vector2f((rect2.x + rect2.width)/2,(rect2.y + rect2.height)/2); 

    Vector2f rect1A = new Vector2f(rect1Origin.x + rect1.width, rect1.y); 
    Vector2f rect1B = new Vector2f(rect1Origin.x, rect1Origin.y+ rect1.height); 
    Vector2f rect1C = new Vector2f(rect1Origin.x + rect1.width,rect1Origin.y + rect1.height); 

    Vector2f rect2A = new Vector2f(rect2Origin.x + rect2.width, rect2.y); 
    Vector2f rect2B = new Vector2f(rect2Origin.x, rect2Origin.y 
      + rect2.height); 
    Vector2f rect2C = new Vector2f(rect2Origin.x + rect2.width, 
      rect2Origin.y + rect2.height); 

    xAdd = rect2C.x - rect1B.x; 
    xAdd2 = rect1C.x - rect2B.x; 

    yAdd = rect2A.y - rect1B.y; 
    yAdd2 = rect2C.y - rect1A.y; 


    if (rect1Mid.y < rect2Mid.y) { 
     if (rect1.intersects(rect2)) { 
      y_pos += yAdd; 
     } 
    } 
    if (rect1Mid.y > rect2Mid.y) { 
     if (rect1.intersects(rect2)) { 
      System.out.println(yAdd2); 
      y_pos += yAdd2; 
     } 

    } 
    if(rect1Mid.x > rect2Mid.x){ 
     if(rect1.intersects(rect2)){ 
      hitRight = true; x_pos += xAdd; 
     } 
    } 
    if(rect1Mid.x< rect2Mid.x){ 
      if(rect1.intersects(rect2)) { 
       x_pos += -xAdd2; 
      } 
    } 
} 

किसी भी मदद की बहुत सराहना

धन्यवाद

उत्तर

2

अपने चरित्र के लिए दो स्थानों रखें होगा -

यहाँ मेरे वर्तमान टक्कर methoe है - जहां यह है (अंतिम फ्रेम, चाल, इत्यादि के रूप में), और जहां आप इसे स्थानांतरित करना चाहते हैं। फिर यदि आप टकराव का पता नहीं लगाते हैं तो केवल इसे स्थानांतरित करें - यदि आप भ्रष्ट स्थिति की अनुमति नहीं देते हैं, तो आपको इसे ठीक करने की आवश्यकता नहीं है।

संपादित करें:collision विधि boolean होना चाहिए - यह से पहले किया जाना चाहिए वास्तव में चरित्र चलती,

if (!collision(character, tile)) 
{ 
    doMove(character); 
} 
else 
{ 
    //custom handling if required 
} 

EDIT2 की तरह: पिछले, एक छोटे से कदम के लिए केवल काम करेगा अगर आपको आंशिक कदम की आवश्यकता है, आपको वास्तव में move(originalPosition, desiredPosition, tile) जैसे चरित्र की मूल स्थिति जानने की आवश्यकता है, जहां आप originalPosition और tile से दिशा को घटा सकते हैं।

मुख्य बिंदु यह है कि, आप वास्तव में चरित्र को स्थानांतरित नहीं करते हैं, इससे पहले कि आपके पास वैध स्थिति हो।

+0

यह समय अंतराल के आधार पर अजीब स्थिति का कारण बन जाएगा। – Matzi

+0

@Matzi वास्तव में कुछ उपयोगकर्ता कमांड निष्पादित करने से पहले इसकी पुष्टि की बात नहीं है - अगर यह मान्य नहीं है, तो आप कस्टम हैंडलिंग कर सकते हैं। – jmruc

+0

@ किरीलरेचेव मैं वास्तव में समझ नहीं पा रहा हूं कि आप – grimrader22

1

सबसे पहले, स्प्राइट (यहां वर्ण और टाइल) में चार सदस्य होना चाहिए: xPos, yPos, xVec, yVec। इसे ध्यान में रखते हुए, आप जानते हैं कि चरित्र कहां था और अगले फ्रेम में होगा।

sprite.xPos += sprite.xVec; 
sprite.yPos += sprite.yVec; 

इसके अलावा अपने कोड पर एक नज़र डालें, तो आप प्रस्ताव में सुधार करना चाहिए (उदाहरण के लिए, आप जाँच करता है, तो (rect1.intersects (rect2)) चार अगर बयान में)। इसके बजाय, intersects() के लिए केवल एक बार जांचें, और प्रत्येक संभावित मामले (बाएं, दाएं, ऊपर, नीचे हिट) के लिए चेक के अंदर।

अंत में, टक्कर विधि 2 स्प्राइट प्राप्त करना चाहिए (उदाहरण के लिए, sprite1 और sprite2) वस्तुओं, और फिर intersects() विधि के लिए जाँच, खाते में दोनों स्प्राइट और की मूल स्थानों लेने अपने वैक्टर। यदि स्प्राइट नई स्थिति में छेड़छाड़ करते हैं, तो आप तदनुसार ऑब्जेक्ट के वेक्टर को घुमाते हैं।

+0

के उस हिस्से को अक्षम कर सकता हूं xVec और yVec चर क्या दर्शाते हैं? – grimrader22

+0

मुझे खेद है कि मैं इतना स्पष्ट नहीं था, वे स्प्राइट के दिशात्मक वैक्टर हैं (आप वेक्टर 2 एफ या प्वाइंट 2 डी का भी उपयोग कर सकते हैं)। मूल्य को प्रत्येक दिशा में स्प्राइट की गति के रूप में व्याख्या किया जा सकता है। तो यदि चरित्र बाएं से बिल्कुल टाइल हिट करता है, तो xVec एक सकारात्मक मान है, और yVec 0 है; और हिट के बाद, xVec का एक ही मूल्य होना चाहिए, लेकिन अब नकारात्मक होना चाहिए। मुझे बताना, अगर आप को किसी भी अधिक मदद की ज़रूरत हो। –

+0

मुझे समझ में नहीं आता कि आप क्या कह रहे हैं, क्षमा करें अगर मैं गूंगा हूं। क्या xand y Vecs वेग होगा? – grimrader22

1

मान लीजिए कि आप अपने कोड के साथ टकराव का पता लगा सकते हैं। आयत वस्तु के संबंध में अपने चरित्र की स्थिति निर्धारित करने का एक तरीका यहां दिया गया है।

  1. आयताकार के मध्य बिंदु को खोजें। (आरएक्स, राय)।

  2. अपने चरित्र स्प्राइट के मध्य बिंदु को खोजें। (एसएक्स, सीई)।

  3. अब आप तुलना कर सकते हैं आरएक्स, राई, एसएक्स एसवाई निर्धारित करने के लिए है, जिसमें पक्ष Sx और Rx के एसवाई और Ry

  4. पूर्व के लिए है:

    if Sx < Rx then 
        Sx = left side of Rx 
    
1

के साथ संघर्ष कर रहा था यह स्वयं, लेकिन कुछ सोचने के बाद यह जांच आपकी सभी संस्थाओं को सूची में रखकर की जा सकती है, मेरे कोड में मुझे खिलाड़ी को ब्लॉक के माध्यम से जाने से रोकना पड़ा। सभी ब्लॉक एक सूची में है। अब, खिलाड़ियों की स्थिति की जांच करते समय मैं एक नया आयत बना देता हूं और खिलाड़ियों को दिशा में एक फ्रेम आगे बढ़ता हूं ताकि अपडेट अगले फ्रेम में हो जाएगा, अगर आयताकार उस दिशा के लिए उस अद्यतन को छेड़छाड़ नहीं करेगा। इस के लिए मेरे कोड यहाँ:

if (isKeyPressed(KeyEvent.VK_LEFT)) { 
     if(!collisionWithBlocks(1)){ 
      pl.x = pl.x - updatePlayerPosition; 
     } 
    } 
    if (isKeyPressed(KeyEvent.VK_RIGHT)) { 
     if(!collisionWithBlocks(0)){ 
      pl.x = pl.x + updatePlayerPosition; 
     } 
    } 
    if (isKeyPressed(KeyEvent.VK_UP)) { 
     if(!collisionWithBlocks(3)){ 
      pl.y = pl.y - updatePlayerPosition; 
     } 
    } 
    if (isKeyPressed(KeyEvent.VK_DOWN)) { 
     if(!collisionWithBlocks(2)){ 
      pl.y = pl.y + updatePlayerPosition; 
     } 
    } 

collisionWithBlocks():

public boolean collisionWithBlocks(int side){ 
    for(Block b : main.blocks){ 
     Rectangle block = b.getBounds(); 
     Rectangle player = null; 
     if(side == 0){ 
      player = new Rectangle(pl.x + updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight()); 
     } else if(side == 1){ 
      player = new Rectangle(pl.x - updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight()); 
     } else if(side == 2){ 
      player = new Rectangle(pl.x, pl.y + updatePlayerPosition, pl.getWidth(), pl.getHeight()); 
     } else if(side == 3){ 
      player = new Rectangle(pl.x, pl.y - updatePlayerPosition, pl.getWidth(), pl.getHeight()); 
     } 

     if(player.intersects(block)){ 
      return true; 
     } 
    } 

    return false; 
} 

updatePlayerPosition 2 है, और मेरे कोड में परिवर्तन, लेकिन उस के बारे में पर्याप्त। आपके मामले में, मैं संस्थाओं को एक सूची में डालने की सलाह देता हूं और फिर जांच करता हूं जैसे मैंने किया था।

संबंधित मुद्दे