मैं libgdx में ऑन-स्क्रीन HUD कैसे बना सकता हूँ?


23

मैं libgdx के लिए नया हूं, और मुझे पता चल रहा है कि मैं सबसे सरल चीजों से प्रभावित हो रहा हूं। ऐसा लगता है कि मैं चीजों को एक विशिष्ट तरीके से करना चाहता हूं, लेकिन प्रलेखन मुझे यह नहीं बताएगा कि वह क्या है।

मैं एक बहुत ही सरल 2d गेम बनाना चाहता हूं जिसमें खिलाड़ी एक स्पेसशिप को नियंत्रित करता है। माउस व्हील ज़ूम इन और आउट होगा, और सूचना और नियंत्रण स्क्रीन पर प्रदर्शित होते हैं।

लेकिन मैं माउस व्हील को UI को ज़ूम न करने के लिए प्रतीत नहीं कर सकता। मैंने बीच में प्रोजेक्शन मैट्रिसेस के साथ फ्यूजनिंग की कोशिश की है

यहाँ मेरा (वर्तमान) कोड है:

public class PlayStage extends Stage {
...
    public void draw() {
    // tell the camera to update its matrices.
    camera.update();

    // tell the SpriteBatch to render in the
    // coordinate system specified by the camera.
    spriteBatch.setProjectionMatrix(camera.combined);

    spriteBatch.begin();

    aButton.draw(spriteBatch, 1F);

    playerShip.draw(spriteBatch, 1F);

    spriteBatch.end();
}
}

camera.zoom स्क्रॉल (इंट राशि) द्वारा सेट किया गया है।

मैंने बटन के खींचे जाने के बाद कैमरा के प्रक्षेपण मैट्रिक्स को बदलने के विषय पर लगभग एक दर्जन विविधताओं की कोशिश की है, लेकिन जहाज से पहले, लेकिन कोई फर्क नहीं पड़ता कि मैं क्या करता हूं, वही चीजें बटन और जहाज दोनों के लिए होती हैं। इसलिए:

ऑन-स्क्रीन UI को लागू करने का सामान्य libgdx तरीका क्या है जो कैमरा के प्रोजेक्शन मैट्रिक्स / ज़ूम द्वारा रूपांतरित नहीं होता है?


आप camera.project(Vector3 screenCoords)दुनिया के निर्देशांक से लेकर स्क्रीन डोरियों तक कुछ प्रोजेक्ट करने के लिए उपयोग कर सकते हैं ।
JDSweetBeat

जवाबों:


17

आप HUD को आकर्षित करने के लिए प्रक्षेपण मैट्रिक्स की स्थापना के बिना बस एक और स्प्राइटबैच का उपयोग कर सकते हैं,

camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
aButton.draw(spriteBatch, 1F);
playerShip.draw(spriteBatch, 1F);
spriteBatch.end();

hudBatch.begin();
//Draw using hudBatch
hudBatch.end();

1
जो मैं कर रहा था, उसके लिए मुझे यह सबसे सरल तरीका लगता था, बेसिक यूआई के लिए जो हमेशा स्क्रीन पर एक ही स्थान पर दिखाई देना चाहिए (जैसे स्कोर, जीवन आदि)
रिचर्ड

प्रोजेक्शन मैट्रिक्स के बिना स्प्रिटबैच होने के बाद जब मैंने यह कोशिश की तो अलग-अलग स्क्रीन रिज़ॉल्यूशन पर अलग पोजिशनिंग हुई
कोडुलिक

8

मुझे लगता है कि एक हूड मैप को पूरा करने का सबसे आसान तरीका एक दूसरे कैमरे का उपयोग करना और उन्हें ओवरले करना होगा। इस मुद्दे पर कुछ समय पहले libgdx मंचों पर चर्चा की गई है और मुझे याद है कि कोई व्यक्ति अपना हड कोड पोस्ट कर रहा है। तुम वहाँ पर चारों ओर प्रहार करना चाहते हैं और देख सकते हैं कि आप क्या कर रहे हैं।


2
हां, यह सही जवाब है। या हड के लिए एक अलग स्टेज का उपयोग करें और गेम स्टफ के बाद इसे ड्रा करें।
मात्सेमन

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

4
क्या आप कृपया कुछ नमूना कोड, या शायद @DevinCarless जोड़ सकते हैं?
ashes999

6

यहाँ एक विधि है जिसका उपयोग मैं एक ही बैच के साथ काम करने के लिए करता हूँ:

पहले सब कुछ ड्रा करें, फिर अपना HUD ड्रा करें:

Matrix4 uiMatrix = cam.combined.cpy();
uiMatrix.setToOrtho2D(0, 0, WIDTH, HEIGHT);
batch.setProjectionMatrix(uiMatrix);
batch.begin();

यदि आप इसके बाद और अधिक आकर्षित करना चाहते हैं, तो सुनिश्चित करें कि आपने जो कुछ भी होना चाहिए, उसे प्रक्षेपण मैट्रिक्स को रीसेट कर दिया है।


चेतावनी दी है कि आप बहुत जल्दी स्मृति में बहुत सारे मैट्रिक्स के साथ समाप्त हो जाएंगे (क्योंकि .cpu()हर बार एक नया मैट्रिक्स बनाता है)। बेहतर में एक स्थायी बफर मैट्रिक्स होता है और इसके मूल्यों को हर फ्रेम पर सेट करता है।
डेनिस नियाज़ेव

1

याद रखें, पहला कैमरा वह जगह है जहां पृष्ठभूमि तय होती है। दूसरा वह स्थान है जहां जमीन चलती है। यदि आप सोच रहे हैं कि स्प्राइट चरण में क्यों चलता है क्योंकि यह रहस्य है कि यह जमीन चलती है। स्प्राइट केवल तीसरे कैमरे का उपयोग करने के बाद से आपके स्थान पर चल रहा है। आपने दूसरे कैमरे की जमीन को स्क्रॉल किया हो सकता है लेकिन HUD तीसरे स्थान पर है। वादा करो, यह सच है! तीसरा कैमरा वह है जहां वह दिशा के लिए केंद्र में स्प्राइट प्रदर्शित करता है, चाहे वह थोड़ा एनीमेशन कोड द्वारा बाएं या दाएं जाता है, और HUD (यानी स्कोर, शेष जीवन, उपयोग की गई वस्तु)। अगर आपको कुछ चाहिए, तो मुझसे पूछिए।


मैं दूसरे कैमरे से स्प्राइट को कैसे अलग कर सकता हूं? मैं जो करना चाहता हूं वह पाठ को आकर्षित करना है, लेकिन यह बड़ा है ... इसलिए मुझे एक और कैमरे की आवश्यकता है, लेकिन जब मैं ऐसा करता हूं तो पाठ मेरे साथ जाता है .. खिलाड़ी के साथ, मेरी स्क्रीन के साथ ... यह थोड़ा चलता है स्क्रीन पर दुश्मन की तरह लेकिन यह अभी भी मेरे साथ है ... क्या आप कृपया सलाह दे सकते हैं?
निमित्तक

1

मैंने इसे इस तरह किया है:

पहले मैंने एक नया वर्ग बनाया है जिसे हड कहा जाता है। यह Disposableसंसाधन प्रबंधन के कारण लागू होता है। फिर आपको Stageअपनी सामग्री और एक नए के लिए परिभाषित करने की आवश्यकता है viewportक्योंकि एक नया कैमरा उपयोग किया जाएगा। आपको एक नया परिभाषित करने की आवश्यकता है Tableजिसे आप इसमें जोड़ सकते हैं Stage। आप अपनी सामग्री को tableहमेशा की तरह जोड़ सकते हैं । बाकी कोड मैं यह दिखाने के लिए डालूंगा कि यह कैसे काम करता है खेल विशिष्ट है इसलिए इसे अनदेखा करें।

public class Hud implements Disposable{

public Stage stage;
private Viewport viewport;

//score && time tracking variables
private Integer worldTimer;
private float timeCount;
private static Integer score;
private boolean timeUp;

//Scene2D Widgets
private Label countdownLabel, timeLabel, linkLabel;
private static Label scoreLabel;

public Hud (SpriteBatch sb){
    //define tracking variables
    worldTimer = 250;
    timeCount = 0;
    score = 0;

    //setup the HUD viewport using a new camera seperate from gamecam
    //define stage using that viewport and games spritebatch
    viewport = new FitViewport(GetTheTriforce.V_WIDTH, GetTheTriforce.V_HEIGHT, new OrthographicCamera());
    stage = new Stage(viewport, sb);

    //define labels using the String, and a Label style consisting of a font and color
    countdownLabel = new Label(String.format("%03d", worldTimer), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    scoreLabel =new Label(String.format("%06d", score), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    timeLabel = new Label("LEFTOVER TIME", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    linkLabel = new Label("POINTS", new Label.LabelStyle(new BitmapFont(), Color.WHITE));

    //define a table used to organize hud's labels
    Table table = new Table();
    table.top();
    table.setFillParent(true);

    //add labels to table, padding the top, and giving them all equal width with expandX
    table.add(linkLabel).expandX().padTop(10);
    table.add(timeLabel).expandX().padTop(10);
    table.row();
    table.add(scoreLabel).expandX();
    table.add(countdownLabel).expandX();

    //add table to the stage
    stage.addActor(table);

}

public void update(float dt){
    timeCount += dt;
    if(timeCount >= 1){
        if (worldTimer > 0) {
            worldTimer--;
        } else {
            timeUp = true;
        }
        countdownLabel.setText(String.format("%03d", worldTimer));
        timeCount = 0;
    }
}

public static void addScore(int value){
    score += value;
    scoreLabel.setText(String.format("%06d", score));
}

@Override
public void dispose() { stage.dispose(); }

public boolean isTimeUp() { return timeUp; }


public static Label getScoreLabel() {
    return scoreLabel;
}

public static Integer getScore() {
    return score;
}

}

और फिर इस तरह से प्लेस्क्रीन में:

सबसे पहले आपको अपने हड को संदर्भित करने के लिए एक चर की आवश्यकता है जैसे:

private Hud hud; 

और फिर कंस्ट्रक्टर में आप अपनी कक्षा का एक नया उदाहरण बनाते हैं:

hud= new Hud(); 

अपडेट-मेथड में आपको कोड की इन लाइनों को डालने की आवश्यकता है क्योंकि मुझे लगता है कि आप कुछ गेम की जानकारी जैसे कि पॉइंट या जीवन छोड़ कर दिखाना चाहते हैं:

hud.update();

रेंडर में- विधि यह करें:

//Set batch to now draw what the Hud camera sees.
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();

और अंत में अपने हुड को डिस्पोज़ करने की विधि में भूल मत जाना

मुझे आशा है कि वह मदद करेंगे

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