एसडीएल गेम फ्रेमवर्क श्रृंखला का अनुवाद। भाग 5 - एसडीएल एनिमेशन

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

अंतिम पाठ में, हमने लोकप्रिय टिक-टैक-टो खेल बनाने की कोशिश की। मुझे आशा है कि आप में से अधिकांश ने गेम को सफलतापूर्वक लॉन्च करने की कोशिश की है, हो सकता है कि कोई व्यक्ति लिखित कोड को संशोधित करने और सुधारने में भी कामयाब रहा हो (और किसी को यह सब बहुत अच्छा लगता है)। भले ही यह नहीं है, कोशिश करो, कोशिश करो, और अंत में आप सफल होंगे।

इस ट्यूटोरियल में, हम SDL का उपयोग करके गुल्लक में एनीमेशन जोड़कर अपने कौशल को उन्नत करने का प्रयास करेंगे। पहले की तरह, हम पिछले पाठों पर निर्माण करेंगे (लेकिन TicTacToe पर नहीं, यह एक अलग परियोजना थी)। मुझे लगता है कि यह शुरू करने का समय है।

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

क्रमशः 2 नई CAnimation.h और CAnimation.cpp फ़ाइलें बनाएँ। अंततः, जब हम CEntity क्लास बनाते हैं, तो यह CAnimation से वारिस हो जाएगा , लेकिन अब हम केवल एक ऑब्जेक्ट का परीक्षण करेंगे, जिसे हम थोड़ी देर बाद बनाएंगे। और शुरू होने से पहले, आइए, हम CApp.h में ( # अधिमानतः "CEvent.h" से पहले) #include "CAnimation.h" समावेश निर्देश जोड़ दें।

चलो कुछ कोड बनाते हैं!

CAnimation.h खोलें, और निम्न पंक्तियाँ जोड़ें:
CAnimation.h
#ifndef _CANIMATION_H_ #define _CANIMATION_H_ #include <SDL.h> class CAnimation { private: int CurrentFrame; int FrameInc; private: int FrameRate; //Milliseconds long OldTime; public: int MaxFrames; bool Oscillate; public: CAnimation(); void OnAnimate(); public: void SetFrameRate(int Rate); void SetCurrentFrame(int Frame); int GetCurrentFrame(); }; #endif 


और CAnimation.cpp में हम इसे लिखते हैं:
CAnimation.cpp
 #include "CAnimation.h" CAnimation::CAnimation() { CurrentFrame = 0; MaxFrames = 0; FrameInc = 1; FrameRate = 100; //Milliseconds OldTime = 0; Oscillate = false; } void CAnimation::OnAnimate() { if(OldTime + FrameRate > SDL_GetTicks()) { return; } OldTime = SDL_GetTicks(); CurrentFrame += FrameInc; if(Oscillate) { if(FrameInc > 0) { if(CurrentFrame >= MaxFrames) { FrameInc = -FrameInc; } }else{ if(CurrentFrame <= 0) { FrameInc = -FrameInc; } } }else{ if(CurrentFrame >= MaxFrames) { CurrentFrame = 0; } } } void CAnimation::SetFrameRate(int Rate) { FrameRate = Rate; } void CAnimation::SetCurrentFrame(int Frame) { if(Frame < 0 || Frame >= MaxFrames) return; CurrentFrame = Frame; } int CAnimation::GetCurrentFrame() { return CurrentFrame; } 


मुझे लगता है कि यह एक छोटी सी बात के लायक है कि यह कोड आखिर करता क्या है। गेम देव में, एनीमेशन का एक मुख्य तत्व है जिसे हमें संभालना होगा - एनीमेशन का वर्तमान फ्रेम। इस पाठ में हम जिस छवि का उपयोग करेंगे, उसे देखें। जैसा कि आप देख सकते हैं, हमारे पास एक छवि में 8 ड्रैगन फ़्रेम हैं। हम इसकी क्रम संख्या 1.2, ... द्वारा वर्तमान फ्रेम का उल्लेख करेंगे और इसे आकर्षित करेंगे।



याद रखें, दूसरे पाठ में, हमने एक छवि का हिस्सा बनाने के लिए एक फ़ंक्शन बनाया? यह इसे लागू करने के लिए बनी हुई है, हमारे एनीमेशन फ्रेम और वॉइला के साथ मिलकर!

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

 CSurface::OnDraw(Surf_Display, Surf_Image, 0, 0, Ezhik.GetCurrentFrame() * 64, 0, 64, 64); 

जब CurrentFrame 1 से बढ़ जाता है, तो हम छवि (फ्रेम आकार) में दाईं ओर 64 पिक्सेल स्थानांतरित करते हैं, और इस फ्रेम को खींचते हैं।

जैसा कि आप अनुमान लगा सकते हैं, मैक्सफ्रेम हमें बताता है कि हमारे पास एनीमेशन के कितने फ्रेम हैं। और अंत में, हमें यह जानने की जरूरत है कि हम प्रति सेकंड कितने फ्रेम खींचते हैं, या बल्कि, कितनी जल्दी यह एनीमेशन प्रदर्शित किया जाएगा (हाँ, हाँ, वही कुख्यात एफपीएस)। प्रतिपादन आवृत्ति का निर्धारण OnAnimate विधि में क्रमादेशित है:

 if(OldTime + FrameRate > SDL_GetTicks()) { return; } 

एसडीएल चलने के समय और वांछित फ्रेम दर के बाद से पुराने समय को जोड़ना, हम इसकी तुलना उस समय से कर सकते हैं जो यह निर्धारित करता है कि एसडीएल (वर्तमान) कितनी देर से चल रहा है। मैं विकास कर रहा हूं: मान लें कि हमने अभी अपना कार्यक्रम शुरू किया है। SDL_GetTicks 0 देता है, और OldTime स्वाभाविक रूप से भी बराबर होता है। 0. यह मान लें कि वांछित फ्रेम दर 1 फ्रेम प्रति सेकंड है। इस प्रकार फ़्रेमरेट = 1000 (मिलीसेकंड)। तो, 0 + 1000 0 से अधिक है? हां, यानी हमें इस बीट को छोड़ना होगा और अगले एक के लिए इंतजार करना होगा। लेकिन अगले उपाय पर 0 + 1000 SDL_GetTicks से कम है, इसका मतलब यह होना चाहिए कि 1 सेकंड बीत चुका है। इस प्रकार, हम फ्रेम के मूल्य को बढ़ाते हैं, और फिर OldTime मान को वर्तमान समय में रीसेट करते हैं, और पहले चेक शुरू करते हैं। मुझे लगता है कि अब यह अधिक स्पष्ट है कि यह कैसे काम करता है।

और अब मैं Oscillate और FrameInc के बारे में बात करूँगा । ऐसा नहीं है कि मैं आपको यह सब, बल्कि विपरीत जोड़कर भ्रमित करना चाहता हूं, इसलिए मैं दिखाऊंगा कि यह क्यों आवश्यक है। सामान्य तौर पर, जब ओस्सिलेट को सही पर सेट किया जाता है , तो एनीमेशन वर्ग फ्रेम को बढ़ा देगा जब तक कि अधिकतम संख्या में फ्रेम नहीं पहुंच जाता है, और फिर इसे कम करें। यदि हमारे पास 10 फ़्रेम थे, उदाहरण के लिए, तो हम कुछ इस तरह का निरीक्षण करेंगे: 0 1 2 3 4 5 6 6 7 8 9 8 7 7 6 5 4 3 2 1 2 ... (करंट फ़्रेम)। हम सभी रास्ते 0 से 9 तक जाते हैं और फिर रिवर्स ऑर्डर में नीचे जाते हैं। सब कुछ बेहद सरल है! अगले पाठ में, मैं आपको यह सब इस्तेमाल करने का एक दिलचस्प तरीका दिखाऊँगा। यह कैसे काम करता है? चलो OnAnimate पर करीब से नज़र डालें

हम ओल्डटाइम और इसके उद्देश्य से अवगत हैं, लेकिन बाकी कोड के बारे में क्या? आइए Oscillate value की जाँच करते हैं। अंदर, हम सिर्फ यह देखने के लिए जांच करते हैं कि क्या CurrentFrame अपने अधिकतम फ्रेम तक पहुंच गया है या नहीं । यदि हां, तो CurrentFrame को 0 पर रीसेट करें।

मुझे लगता है कि Oscillate को सच में सेट करने से हमारे पास एक चिकना एनीमेशन डिस्प्ले होगा! आपको क्या लगता है? आइए फ्रेमएएनसी के उद्देश्य को देखेंफ़्रेमइन्क का मान 1 या -1 के बराबर सेट होता है, यह इस बात पर निर्भर करता है कि हमें एक दिशा या किसी अन्य (फ़्रेम में वृद्धि या वृद्धि) के माध्यम से जाने की आवश्यकता है। यही है, अगर FrameInc 0 से अधिक है, तो हम फ़्रेम बढ़ाना शुरू करते हैं, अन्यथा हम एक decrement का उपयोग करते हैं। इस प्रकार, हम वैकल्पिक रूप से या तो 0 या MaxFrames मान तक पहुंचते हैं, जो कि मेरे दिमाग में , बहुत अधिक सुंदर है (कम से कम CurrentFrame का कोई हार्ड रीसेट नहीं है)।

फिनिश लाइन

अब यह सब एक साथ डाल दो! आपको CApp.h में CAnimation class ऑब्जेक्ट बनाने की आवश्यकता है:

 CAnimation Anim_Yoshi; 

CAF_OnInit के अंदर, MaxFrames का मान सेट करें:

 Anim_Yoshi.MaxFrames = 8; 

यदि आपको फ्रेम 0 से 7 तक के एनीमेशन की आवश्यकता है और इसके विपरीत, सेट करें:

 Anim_Yoshi.Oscillate = true; 

आइए CAo_OnLoop के अंदर Yoji को एनिमेटेड बनाएं :

 Anim_Yoshi.OnAnimate(); 

और निश्चित रूप से, एनीमेशन का आनंद लेने के लिए, आपको इसे CApp_OnRender में जोड़कर देखना होगा:

 CSurface::OnDraw(Surf_Display, Surf_Test, 290, 220, Anim_Yoshi.GetCurrentFrame() * 64, 0, 64, 64); 

खैर, यह बात है! हमारे अद्यतन परियोजना को संकलित करें और चलाएं! इस लेख से चित्र डाउनलोड करना न भूलें, क्योंकि एक कॉलम में मूल फ्रेम जो कि, IMHO, बदसूरत दिखता है। और कुछ और अंक। चूंकि चित्र .PNG है, इसलिए आपको IMG_Load (पिछले लेख में मैंने इस फ़ंक्शन के बारे में लिखा है) का उपयोग करने की आवश्यकता है और लाइब्रेरी को -lSDL_image स्विच के साथ प्रोजेक्ट से कनेक्ट करें । इसके अलावा, योगी के साथ इस कष्टप्रद गुलाबी रंग को बंद करने का प्रयास करें (आप पिछले लेखों में यह कैसे करें यह भी देख सकते हैं)। GameDeveloper की कड़ी मेहनत में आपको शुभकामनाएँ! मुझे उम्मीद है कि ये लेख मदद करेगा ...

स्रोत कोड लिंक:


सभी पाठों के लिंक:

Source: https://habr.com/ru/post/In169197/


All Articles