मैं बुलेट पैटर्न आकृतियों का विस्तार कैसे कर सकता हूं?


12

मैं बुलेट पैटर्न का विस्तार करने की एक श्रृंखला बनाना चाहता हूं जो कि आकार बनाते हैं जैसे कि वर्ग, त्रिकोण, आदि। इसके बाद जो कुछ भी मैं देख रहा हूं उसका एक उदाहरण निम्नलिखित वीडियो में देखा जा सकता है जहां सितारों को इकट्ठा किया जाता है जब एक आकार में गोलियां फट जाती हैं विस्तार सितारा:

https://youtu.be/7JGcuTWYdvU?t=2m41s


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

1
उस तरह के प्रभाव के लिए एक लोकप्रिय नाम "कण प्रभाव है।" वह खोज शब्द आपकी सहायता कर सकता है!
Cort Ammon

1
धन्यवाद, मैं काफी समय से XNA और libGDX में कण प्रभावों का उपयोग कर रहा हूं, लेकिन यह निश्चित नहीं था कि प्रभाव की इस विशेष शैली को कैसे संभाला जाए।
लेप्टन

1
इसका एक और जवाब है जो अविश्वसनीय रूप से शक्तिशाली है, लेकिन कार्यक्रम के लिए बहुत जटिल है। और टाइप करने के लिए असली कीबोर्ड की जरूरत होती है। बाद में स्पष्टीकरण के लिए इसे बुकमार्क करना।
Draco18s अब SE

दिलचस्प है - मैं कभी इस तरह से कुछ के लिए कण प्रभाव के साथ चला गया होगा। या हो सकता है कि यह सिर्फ एकता में एक परिसीमन हो। हालांकि कण प्रभाव में कोलाइडर हो सकते हैं (इस प्रकार किसी वस्तु को नुकसान पहुंचाना), ऐसा लगता है कि बस तात्कालिक वस्तु प्रतियों की तुलना में बहुत अधिक ओवरहेड पैदा करेगा।
जेसी विलियम्स

जवाबों:


11

ऐसा करने का सबसे आसान तरीका पहले आकार को डिजाइन करना होगा और फिर कणों की गति की गणना करना होगा। इस उत्तर में मैं एक वर्ग का निर्माण करूंगा, लेकिन यह किसी भी आकार पर लागू होता है।

कुछ मूल बिंदु के आसपास सापेक्ष स्थिति के रूप में अपना आकार डिजाइन करके शुरू करें।

वर्ग

अब आपको यह गणना करने की आवश्यकता है कि आकार का विस्तार कैसे होगा। ऐसा करने के लिए, हम बस वेक्टर की स्थिति की गणना करते हुए originहर स्थिति से अपनी स्थिति को pointघटाते हैं और फिर वेक्टर को सामान्य करते हैं। ।originpointvector = normalize(point.x - origin.x, point.y - origin.y)

वेक्टर

अब हम इस वेक्टर का उपयोग करके किसी भी समय बिंदुओं की स्थिति की गणना कर सकते हैं। आप कर के बिंदुओं की अगली स्थिति की गणना करते हैं point.position += point.vector * point.velocity। हमारे पिछले बिंदु का उपयोग करते हुए स्यूडोकोड उदाहरण:

// When you start your program you set these values.
point.position = (-3, 3); // Start position. Can be anything.
point.vector = normalize(-3, 3); // Normalized vector.
point.velocity = 3; // Can be anything.

// You do this calculation every frame.
point.position += point.vector * point.velocity;
// point.vector * point.velocity = (-3, 3)
// point.position is now (-6, 6) since (-3, 3) + (-3, 3) = (-6, 6)

ऐसा करने से 3 फ्रेम हर फ्रेम पर सभी बिंदु बाहर की ओर निकल जाएंगे।


टिप्पणियाँ

  • आप यहां कुछ सरल वेक्टर गणित पढ़ सकते हैं ।
  • स्थिति कुछ भी हो सकती है जब तक कि सभी पद किसी मूल बिंदु के सापेक्ष हों।
  • एक समान गति सुनिश्चित करने के लिए सभी बिंदुओं का वेग समान होना चाहिए, लेकिन अलग-अलग वेग होने से आपको दिलचस्प परिणाम मिल सकते हैं।
  • यदि आंदोलन बंद लगता है तो आपको मूल बिंदु की जांच करनी चाहिए। यदि यह आकार के ठीक मध्य में नहीं है तो आकार एक अजीब तरीके से फैल सकता है।

9
मैं केवल इंगित करना चाहता हूं, प्रत्येक कण का वेग पहले फ्रेम पर मूल से दूरी के लिए आनुपातिक होना चाहिए (जिसका अर्थ है कि केवल एक बार गणना करें प्रति फ्रेम नहीं)। वैकल्पिक रूप से, आप बस दिशा वेक्टर को सामान्य नहीं कर सकते हैं। यदि आप ऐसा नहीं करते हैं, तो आकार रैखिक रूप से स्केल नहीं करेगा, बल्कि एक सर्कल बनने की दिशा में आगे बढ़ेगा (यदि सभी वेग समान हैं।)
हारून

@ व्याख्याकर्ता स्पष्टीकरण के लिए बहुत धन्यवाद। मैंने वास्तव में विश्वविद्यालय में असतत गणित का अध्ययन किया था लेकिन अब से कुछ समय पहले यह काफी था। आज मैं कुछ करने की कोशिश कर रहा हूं।
लेप्टन

2

तो, वहाँ इस परियोजना है वहाँ बुलाया BulletML जो जटिल कण / बुलेट पैटर्न बनाने के लिए एक मार्कअप भाषा है। आपको कोड को निश्चित रूप से अपनी भाषा में पोर्ट करना होगा, लेकिन यह वास्तव में कुछ आश्चर्यजनक चीजें कर सकता है।

उदाहरण के लिए, इस बॉस को Unity3D (उस पैटर्न के लेखक ने वीडियो और मिसरी के साथ-साथ अच्छा 1 अपलोड किया है) के लिए BulletML के एक (भारी संशोधित) विस्तार में किया गया था । यह उस दुश्मन की सबसे कठिन भिन्नता है और यह दिखाता है कि बुलेटएमएल काफी अच्छी तरह से सक्षम है (और मिसरी के कुछ अन्य मालिकों की तरह, जैसे कि वॉलमास्टर भी )।

या मैं इस उदाहरण को दिखा सकता हूं, जो एक पैटर्न है जिसे मैंने द लास्ट फेडरेशन के लिए एक विस्तार पर काम करते समय लिखा था , सिस्टम के एक पुराने संशोधन का उपयोग करके जो कम-अनुकूल है और केवल एकल वर्ण AZ चर का उपयोग करता है:

बुलेट पैटर्न उदाहरण

उन रिंगों को बनाने वाली हरे रंग की गोलियों को एक मूल बुलेट से उगल दिया जाता है जो तेज गति से घूमती है, लेकिन स्वयं में कोई गति नहीं है। वे बड़े पैमाने पर नुकसान का सामना करते हैं, खिलाड़ी को एक लंबी सीमा पर रखते हैं, उन्हें कम क्षति वाले हथियारों तक सीमित रखते हैं और मोबाइल डिफेंडरों को खिलाड़ी को परेशान करने की अनुमति देते हैं (यदि बीच में ढांचा नष्ट हो गया तो खिलाड़ी जीत गया)।

यहाँ XML सिंटैक्स का एक हिस्सा है जो उन बुलबुले बनाता है:

<bullet_pattern name="Barrier">
    $WallShotAngle B=.3 A=90
    $WallShotAngle B=.3 A=-90
    $WallShotAngle B=.3 A=0
    $WallShotAngle B=.375 A=180
</bullet_pattern>

<var name="WallShotAngle">
    <bullet angle="[A]" speed="4000" interval_mult=".01" dumbfire="1" shot_type="GravityWavePurple">
        <wait time="[B]" />
        <change angle="0" speed="1000" time=".0001" />
        <spawn>
            <bullet_pattern>
                <bullet angle="[A]" speed="0" shot_type="CurveBarGreen" damage_mult="8">
                <wait time="12" />
                <die />
                </bullet>
            </bullet_pattern>
        </spawn>
        <die />
    </bullet>
</var>

आप स्क्रीनशॉट में बैंगनी "ग्रेविटी वेव" शॉट्स में से कुछ देख सकते हैं, जो स्रोत से लगभग तुरंत यात्रा करते हैं (जो घूमता है) बबल के किनारे तक जाता है, जहां यह हरे रंग के "घुमावदार बार" शॉट को जन्म देता है, जो 12 घंटे पहले वहां बैठता है despawning। नीले और पीले रंग के शॉट्स मैंने छोड़ दिए हैं, क्योंकि वे बहुत अधिक जटिल हैं।

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

बुलेटएमएल के साथ काम करना आसान है, आम तौर पर, और अद्भुत चीजें कर सकते हैं। बुलेट दिशा बदल सकते हैं, गति बदल सकते हैं, अन्य पैटर्न बदल सकते हैं, जल्दी मर सकते हैं, एक लूप में कमांड्स का संग्रह दोहरा सकते हैं, देरी का उपयोग कर सकते हैं, बुलेट स्प्राइट छवि बदल सकते हैं, उनके माता-पिता (या नहीं) का पालन कर सकते हैं ... और ऐसा कुछ भी जो आपका समर्थन नहीं कर सकता है। इसमें लिखें।

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

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

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

@ शेल्टन पूरी तरह से समझने योग्य। यह आपके लिए एक निर्णय है, लेकिन इसका जवाब किसी और के लिए "सबसे अच्छा" हो सकता है। मुझे पता है कि टीएलएफ पर काम करने के बाद और अपने खुद के शूटर का निर्माण शुरू करने के लिए मैं इसे सिर्फ इसलिए इस्तेमाल करना चाहता था क्योंकि यह कितना शक्तिशाली और आसान काम था। :)
Draco18s अब SE

1

जैसा कि चरनोर द्वारा बताया गया है कि आप अपने आकार को परिभाषित करने के लिए और फिर समय के साथ उनकी स्थिति को अद्यतन करने के लिए कई बिंदुओं का उपयोग कर सकते हैं। नीचे बिंदुओं का उपयोग करके स्टार आकृति या कस्टम आकार को कैसे लागू किया जाए, इसका एक निम्न उदाहरण है:

package com.mygdx.gtest;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;

public class Test extends ApplicationAdapter{

    public SpriteBatch sb;
    private StarShape ss, ssBig;

    @Override
    public void create() {
        sb = new SpriteBatch();
        Pixmap pmap = new Pixmap(2, 2,Format.RGBA8888);
        pmap.setColor(Color.WHITE);
        pmap.fill();
        ss = new StarShape(50,50,new Texture(pmap), 10, true);
        ssBig = new StarShape(250,250,new Texture(pmap), 50, false);
        pmap.dispose();

    }


    @Override
    public void render() {
        super.render();

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        ss.update(Gdx.graphics.getDeltaTime());
        ssBig.update(Gdx.graphics.getDeltaTime());

        sb.begin();
            ss.draw(sb);
            ssBig.draw(sb);
        sb.end();

    }


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

    private class StarShape{
        public float progress = 1f;
        public Texture bulletTex;
        public Array<Vector2> points = new Array<Vector2>();
        public Vector2 center;

        public StarShape(float x, float y, Texture tex, float initialSize, boolean mathWay){
            center = new Vector2(x,y);
            bulletTex = tex;

            if(mathWay){
                // define star shape with maths
                float alpha = (float)(2 * Math.PI) / 10; 
                float radius = initialSize;

                for(int i = 11; i != 0; i--){
                    float r = radius*(i % 2 + 1)/2;
                    float omega = alpha * i;
                    points.add(
                            new Vector2(
                                    (float)(r * Math.sin(omega)), 
                                    (float)(r * Math.cos(omega)) 
                                )
                            );
                }
            }else{
            // or define star shape manually (better for non geometric shapes etc

                //define circle
                points.add(new Vector2(-3f,0f));
                points.add(new Vector2(-2.8f,1f));
                points.add(new Vector2(-2.2f,2.2f));
                points.add(new Vector2(-1f,2.8f));
                points.add(new Vector2(0f,3f));
                points.add(new Vector2(1f,2.8f));
                points.add(new Vector2(2.2f,2.2f));
                points.add(new Vector2(2.8f,1f));
                points.add(new Vector2(3f,0f));
                points.add(new Vector2(2.8f,-1f));
                points.add(new Vector2(2.2f,-2.2f));
                points.add(new Vector2(1f,-2.8f));
                points.add(new Vector2(0f,-3f));
                points.add(new Vector2(-1f,-2.8f));
                points.add(new Vector2(-2.2f,-2.2f));
                points.add(new Vector2(-2.8f,-1f));

                // mouth
                points.add(new Vector2(-2,-1));
                points.add(new Vector2(-1,-1));
                points.add(new Vector2(0,-1));
                points.add(new Vector2(1,-1));
                points.add(new Vector2(2,-1));
                points.add(new Vector2(-1.5f,-1.1f));
                points.add(new Vector2(-1,-2));
                points.add(new Vector2(0,-2.2f));
                points.add(new Vector2(1,-2));
                points.add(new Vector2(1.5f,-1.1f));

                points.add(new Vector2(-1.5f,1.5f));
                points.add(new Vector2(1.5f,1.5f));

            }

        }

        public void update(float deltaTime){
            this.progress+= deltaTime;
        }

        public void draw(SpriteBatch sb){
            Vector2 temp = new Vector2(0,0);
            for(Vector2 point: points){
                temp.x = (point.x);
                temp.y = (point.y);
                temp.scl(progress);
                sb.draw(bulletTex,temp.x + center.x,temp.y +center.y);
            }
        }
    }
}

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