कई छोटे पॉलिमॉर्फिक वर्गों (गुणों या संदेशों या घटनाओं के रूप में उपयोग के लिए) C ++ के लचीले विकल्प


9

मेरे खेल में दो कक्षाएं हैं जो वास्तव में उपयोगी हैं, लेकिन धीरे-धीरे दर्द बन रही हैं। संदेश और संपत्ति (संपत्ति अनिवार्य रूप से एक घटक है)।

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

जब मैं अपना खेल बढ़ाता हूं तो मैं लगातार नए संदेश प्रकार और संपत्ति प्रकार बना रहा हूं। हर बार मुझे अनिवार्य रूप से एक classID और एक या दो मानक डेटा प्रकार या पॉइंटर प्राप्त करने के लिए 2 फाइलें (hpp और cpp) और बॉयलरप्लेट का एक टन लिखने की आवश्यकता होती है।

यह चारों ओर से खेलना शुरू कर रहा है और नए विचारों को वास्तविक रूप से विकसित कर रहा है। मेरी इच्छा है कि जब मैं एक नया संदेश या संपत्ति प्रकार बनाना चाहता हूं, तो मैं बस कुछ टाइप करने में सक्षम होना चाहता हूं

ShootableProperty:  int gunType, float shotspeed;

ItemCollectedMessage:  int itemType;

हेडर और सीपीपी फ़ाइल बनाने के बजाय, एक रचनाकार लिखना, जिसमें मूल वर्ग, आदि शामिल हैं।

यह लगभग २० - ४० पंक्तियाँ (जिसमें गार्ड शामिल हैं, और सब कुछ शामिल है) सिर्फ वही करने के लिए जो मेरे दिमाग में १ या २ लाइनें हैं।

क्या इसके आसपास कुछ प्रोग्रामिंग पैटर्न है?

स्क्रिप्टिंग के बारे में क्या (जो मुझे कुछ भी नहीं पता है) ... क्या वर्गों का एक गुच्छा परिभाषित करने का एक तरीका है जो लगभग समान हैं?


यहाँ एक कक्षा जैसा दिखता है:

// Velocity.h

#ifndef VELOCITY_H_
#define VELOCITY_H_

#include "Properties.h"

#include <SFML/System/Vector2.hpp>

namespace LaB
{
namespace P
{

class Velocity: public LaB::Property
{
public:
    static const PropertyID id;

    Velocity(float vx = 0.0, float vy = 0.0)
    : velocity(vx,vy) {}
    Velocity(sf::Vector2f v) : velocity(v) {};

    sf::Vector2f velocity;
};

} /* namespace P */
} /* namespace LaB */
#endif /* LaB::P_VELOCITY_H_ */



// Velocity.cpp

#include "Properties/Velocity.h"

namespace LaB
{
namespace P
{

const PropertyID Velocity::id = Property::registerID();

} /* namespace P */
} /* namespace LaB */

यह सब सिर्फ एक 2D वेक्टर और एक ID के लिए कह रहा है जो 2D वेक्टर की अपेक्षा करता है। (दी गई, कुछ संपत्तियों में अधिक जटिल तत्व हैं, लेकिन यह एक ही विचार है)


3
इस पर एक नज़र डालें, यह आपकी मदद कर सकता है। gameprogrammingpatterns.com/type-object.html

1
यह सब ऐसा लगता है कि टेम्पलेट मदद कर सकते हैं, बस स्थैतिक आरंभ के साथ नहीं। इस मामले में यह निश्चित रूप से बहुत आसान हो सकता है, लेकिन उन आईडी के साथ आप क्या करना चाहते हैं और क्यों आप विरासत का उपयोग कर रहे हैं, इस बारे में अधिक जानकारी के बिना बताना मुश्किल है। सार्वजनिक विरासत का उपयोग करना लेकिन कोई आभासी कार्य निश्चित रूप से एक कोड गंध नहीं है ... यह बहुरूपता नहीं है!
ltjax

क्या आपने 3rd पार्टी लाइब्रेरी पाया है जो इसे लागू करता है?
बोरिस

जवाबों:


1

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

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

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

  1. C ++ टेम्प्लेट का उपयोग करें । टेम्पलेट आपके लिए कंपाइलर "कोड लिखें" को जाने देने का एक शानदार तरीका है। यह C ++ दुनिया में अधिक से अधिक प्रमुख होता जा रहा है, क्योंकि भाषा उन्हें बेहतर समर्थन देने के लिए विकसित होती है (जैसे कि अब आप टेम्पलेट मापदंडों के एक चर संख्या का उपयोग कर सकते हैं )। टेम्पलेट्स के माध्यम से कोड की स्वचालित पीढ़ी के लिए समर्पित एक संपूर्ण अनुशासन है: टेम्पलेट मेटाप्रोग्रामिंग । समस्या यह है: यह कठिन है। यदि आप इस तरह की तकनीक का उपयोग करने की योजना बनाते हैं, तो गैर-प्रोग्रामर से खुद को नई संपत्तियों को जोड़ने में सक्षम होने की उम्मीद न करें।

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

  3. एक अन्य विकल्प आपके लिए कोड उत्पन्न करने के लिए एक बाहरी उपकरण का उपयोग करना है। यह पहले से ही एक पिछले जवाब में उल्लेख किया गया है इसलिए मैं उस पर विस्तार नहीं करूंगा।

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

  5. अंत में अंतिम लेकिन कम से कम, आपको डेटा-संचालित डिज़ाइन का उपयोग करने पर विचार करना चाहिए । आप उन "वर्गों" को सरल पाठ फ़ाइलों में परिभाषित कर सकते हैं जो आपके द्वारा प्रस्तावित एक लेआउट के समान हैं। आपको इसके लिए एक कस्टम प्रारूप और पार्सर बनाना होगा, या पहले से उपलब्ध विकल्पों में से एक (.ini, XML, JSON और whatnot) का उपयोग करना होगा। फिर सी ++ की तरफ, आपको एक ऐसी प्रणाली बनाने की आवश्यकता होगी जो उन विभिन्न प्रकार की वस्तुओं के संग्रह का समर्थन करती है। यह स्क्रिप्टिंग दृष्टिकोण (और शायद और भी अधिक काम करने की आवश्यकता है) के लगभग बराबर है, सिवाय इसके कि आप इसे अपनी आवश्यकताओं के अधिक सटीक रूप से दर्जी कर पाएंगे। और यदि आप इसे सरल बनाते हैं, तो गैर-प्रोग्रामर स्वयं द्वारा नई चीजें बनाने में सक्षम हो सकते हैं।


0

कोड जनरेशन टूल के बारे में आपको कैसे मदद करनी है?

उदाहरण के लिए, आप अपने संदेश प्रकार और सदस्यों को एक छोटी टेक्स्ट फ़ाइल में परिभाषित कर सकते हैं और कोड जीन टूल को इसे पार्स कर सकते हैं और सभी बायलरप्लेट C ++ फ़ाइलों को पूर्व-निर्मित चरण के रूप में लिख सकते हैं।

ANTLR या लेक्रस / YACC जैसे मौजूदा समाधान हैं, और यह आपके गुणों और संदेशों की जटिलता के आधार पर अपना रोल करना मुश्किल नहीं होगा।


केवल लेक्स / YACC aproach का एक विकल्प, जब मुझे केवल मामूली संशोधनों के साथ बहुत ही समान फाइलें उत्पन्न करनी होती हैं, तो मैं एक सरल और छोटी अजगर स्क्रिप्ट और C ++ कोड टेम्पलेट फ़ाइल का उपयोग करता हूं जिसमें टैग होते हैं। पायथन लिपि इन टैगों के लिए खोज करती है खाका में उन्हें तत्व के प्रतिनिधि टोकन द्वारा प्रतिस्थापित किया जाता है।
विजेता

0

मैं आपको Google के प्रोटोकॉल बफ़र्स ( http://code.google.com/p/protobuf/ ) के बारे में शोध करने की सलाह देता हूं । वे सामान्य संदेशों को संभालने के लिए एक बहुत ही चतुर तरीका है। आपको बस एक संरचना-समान पैटर्न में गुणों को निर्दिष्ट करना होगा और एक कोड जनरेटर आपके लिए कक्षाएं उत्पन्न करने का सारा काम करेगा (जावा, सी ++ या सी #)। सभी उत्पन्न वर्गों में पाठ और बाइनरी पार्सर होते हैं, जो उन्हें पाठ-आधारित संदेश आरंभीकरण और क्रमांकन दोनों के लिए अच्छा बनाते हैं।


मेरा मैसेजिंग सेंट्रल मेरा कार्यक्रम मुख्य है - क्या आपको पता है कि प्रोटोकॉल बफ़र्स किसी भी बड़े ओवरहेड को लगाता है?
ब्रायन

मुझे नहीं लगता कि वे बड़े ओवरहेड को उकसाते हैं, क्योंकि एपीआई प्रत्येक संदेश के लिए सिर्फ एक बिल्डर वर्ग है और संदेश के लिए वर्ग है। Google उन्हें अपने बुनियादी ढांचे के मूल के लिए उपयोग करता है। उदाहरण के लिए, Google App Engine Entities सभी को बनाए रखने से पहले प्रोटोकॉल बफ़र्स में कनवर्ट किया जाता है। यदि आपको संदेह है, तो मैं आपको अपने वर्तमान कार्यान्वयन और प्रोटोकॉल बफ़र्स के बीच तुलना परीक्षण लागू करने की सलाह देता हूं। यदि आपको लगता है कि ओवरहेड स्वीकार्य है, तो उनका उपयोग करें।
dsilva.vinicius
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.