24 மணிநேரத்தில் ரஸ்ட் விளையாடுதல்: தனிப்பட்ட வளர்ச்சி அனுபவம்
இந்த கட்டுரையில் ரஸ்டில் ஒரு சிறிய விளையாட்டை உருவாக்கும் எனது தனிப்பட்ட அனுபவத்தைப் பற்றி பேசுவேன். வேலை செய்யும் பதிப்பை உருவாக்க சுமார் 24 மணிநேரம் ஆனது (நான் பெரும்பாலும் மாலை அல்லது வார இறுதி நாட்களில் வேலை செய்தேன்). விளையாட்டு முடிவடையவில்லை, ஆனால் அனுபவம் பலனளிக்கும் என்று நான் நினைக்கிறேன். புதிதாக விளையாட்டை உருவாக்கும்போது நான் கற்றுக்கொண்டவற்றையும் சில அவதானிப்புகளையும் பகிர்ந்து கொள்கிறேன்.
நாங்கள் நினைவூட்டுகிறோம்:"Habr" இன் அனைத்து வாசகர்களுக்கும் - "Habr" விளம்பரக் குறியீட்டைப் பயன்படுத்தி எந்த Skillbox படிப்பிலும் சேரும்போது 10 ரூபிள் தள்ளுபடி.
ஏன் துரு?
நான் இந்த மொழியைத் தேர்ந்தெடுத்தேன், ஏனெனில் இதைப் பற்றி நிறைய நல்ல விஷயங்களை நான் கேள்விப்பட்டேன், மேலும் இது விளையாட்டு வளர்ச்சியில் மேலும் மேலும் பிரபலமடைந்து வருவதைக் காண்கிறேன். விளையாட்டை எழுதுவதற்கு முன், ரஸ்டில் எளிமையான பயன்பாடுகளை உருவாக்குவதில் எனக்கு சிறிய அனுபவம் இருந்தது. விளையாட்டை எழுதும் போது எனக்கு ஒரு சுதந்திர உணர்வைக் கொடுக்க இது போதுமானதாக இருந்தது.
ஏன் விளையாட்டு மற்றும் என்ன வகையான விளையாட்டு?
விளையாட்டுகளை உருவாக்குவது வேடிக்கையானது! இன்னும் பல காரணங்கள் இருக்க வேண்டும் என்று நான் விரும்புகிறேன், ஆனால் "வீடு" திட்டங்களுக்கு எனது வழக்கமான வேலையுடன் மிகவும் நெருக்கமாக இல்லாத தலைப்புகளைத் தேர்வு செய்கிறேன். என்ன விளையாட்டு இது? சிட்டிஸ் ஸ்கைலைன்ஸ், ஜூ டைகூன், ப்ரிசன் ஆர்கிடெக்ட் மற்றும் டென்னிஸ் ஆகியவற்றை இணைத்து டென்னிஸ் சிமுலேட்டரை உருவாக்க விரும்பினேன். பொதுவாக, இது மக்கள் விளையாட வரும் டென்னிஸ் அகாடமியைப் பற்றிய விளையாட்டாக மாறியது.
தொழில்நுட்ப பயிற்சி
நான் ரஸ்ட்டைப் பயன்படுத்த விரும்பினேன், ஆனால் அதைத் தொடங்குவதற்கு எவ்வளவு அடிப்படை வேலைகள் தேவைப்படும் என்று எனக்குத் தெரியவில்லை. நான் பிக்சல் ஷேடர்களை எழுத விரும்பவில்லை மற்றும் இழுவை-என்-டிராப்பைப் பயன்படுத்த விரும்பவில்லை, அதனால் நான் மிகவும் நெகிழ்வான தீர்வுகளைத் தேடினேன்.
உங்களுடன் பகிர்ந்து கொள்ளும் பயனுள்ள ஆதாரங்களைக் கண்டேன்:
நான் பல ரஸ்ட் கேம் என்ஜின்களை ஆராய்ந்தேன், இறுதியில் பிஸ்டன் மற்றும் கெஸ்ஸைத் தேர்ந்தெடுத்தேன். முந்தைய திட்டத்தில் பணிபுரியும் போது நான் அவர்களை சந்தித்தேன். இறுதியில், நான் ஒரு சிறிய 2D கேமைச் செயல்படுத்துவதற்கு மிகவும் பொருத்தமானதாகத் தோன்றியதால், ggez ஐத் தேர்ந்தெடுத்தேன். புதிய டெவலப்பருக்கு (அல்லது முதன்முறையாக ரஸ்டுடன் பணிபுரியும் ஒருவருக்கு) பிஸ்டனின் மட்டு அமைப்பு மிகவும் சிக்கலானது.
விளையாட்டு அமைப்பு
திட்டத்தின் கட்டிடக்கலை பற்றி சிறிது நேரம் யோசித்தேன். முதல் படி "நிலம்", மக்கள் மற்றும் டென்னிஸ் மைதானங்களை உருவாக்குவது. நீதிமன்றத்தை சுற்றி மக்கள் காத்திருக்க வேண்டியுள்ளது. வீரர்கள் காலப்போக்கில் மேம்படுத்தும் திறன்களைக் கொண்டிருக்க வேண்டும். கூடுதலாக, புதிய நபர்களையும் நீதிமன்றங்களையும் சேர்க்க உங்களை அனுமதிக்கும் எடிட்டர் இருக்க வேண்டும், ஆனால் இது இனி இலவசம் அல்ல.
எல்லாவற்றையும் யோசித்துவிட்டு, நான் வேலைக்கு வந்தேன்.
விளையாட்டு உருவாக்கம்
ஆரம்பம்: வட்டங்கள் மற்றும் சுருக்கங்கள்
நான் gez இலிருந்து ஒரு உதாரணத்தை எடுத்து திரையில் ஒரு வட்டத்தைப் பெற்றேன். அற்புத! இப்போது சில சுருக்கங்கள். ஒரு விளையாட்டு பொருளின் யோசனையிலிருந்து விலகிச் செல்வது நல்லது என்று நினைத்தேன். இங்கே கூறப்பட்டுள்ளபடி ஒவ்வொரு பொருளும் வழங்கப்பட வேண்டும் மற்றும் புதுப்பிக்கப்பட வேண்டும்:
// the game object trait
trait GameObject {
fn update(&mut self, _ctx: &mut Context) -> GameResult<()>;
fn draw(&mut self, ctx: &mut Context) -> GameResult<()>;
}
// a specific game object - Circle
struct Circle {
position: Point2,
}
impl Circle {
fn new(position: Point2) -> Circle {
Circle { position }
}
}
impl GameObject for Circle {
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
let circle =
graphics::Mesh::new_circle(ctx, graphics::DrawMode::Fill, self.position, 100.0, 2.0)?;
graphics::draw(ctx, &circle, na::Point2::new(0.0, 0.0), 0.0)?;
Ok(())
}
}
இந்தக் குறியீட்டுத் துண்டு, நான் புதுப்பித்து, சமமான நல்ல லூப்பில் வழங்கக்கூடிய பொருட்களின் நல்ல பட்டியலை எனக்குக் கொடுத்தது.
mpl event::EventHandler for MainState {
fn update(&mut self, context: &mut Context) -> GameResult<()> {
// Update all objects
for object in self.objects.iter_mut() {
object.update(context)?;
}
Ok(())
}
fn draw(&mut self, context: &mut Context) -> GameResult<()> {
graphics::clear(context);
// Draw all objects
for object in self.objects.iter_mut() {
object.draw(context)?;
}
graphics::present(context);
Ok(())
}
}
main.rs அவசியமானது, ஏனெனில் இது குறியீட்டின் அனைத்து வரிகளையும் கொண்டுள்ளது. கோப்புகளைப் பிரிப்பதற்கும், அடைவு கட்டமைப்பை மேம்படுத்துவதற்கும் சிறிது நேரம் செலவிட்டேன். அதன் பிறகு தோன்றியது இதுதான்: வளங்கள் -> இங்குதான் அனைத்து சொத்துகளும் உள்ளன (படங்கள்)
மூல
- நிறுவனங்கள்
— game_object.rs
- வட்டம். ஆர்.எஸ்
— main.rs -> முக்கிய வளையம்
மக்கள், மாடிகள் மற்றும் படங்கள்
அடுத்த படியாக ஒரு நபர் விளையாட்டு பொருளை உருவாக்கி படங்களை ஏற்ற வேண்டும். அனைத்தும் 32*32 ஓடுகளின் அடிப்படையில் கட்டப்பட வேண்டும்.
டென்னிஸ் மைதானங்கள்
டென்னிஸ் மைதானங்கள் எப்படி இருக்கும் என்பதைப் படித்த பிறகு, அவற்றை 4*2 ஓடுகளால் உருவாக்க முடிவு செய்தேன். ஆரம்பத்தில், இந்த அளவிலான படத்தை உருவாக்குவது அல்லது 8 தனித்தனி ஓடுகளை ஒன்றாக இணைக்க முடிந்தது. ஆனால் இரண்டு தனித்துவமான ஓடுகள் மட்டுமே தேவை என்பதை நான் உணர்ந்தேன், அதற்கான காரணம் இங்கே.
மொத்தத்தில் இதுபோன்ற இரண்டு ஓடுகள் உள்ளன: 1 மற்றும் 2.
நீதிமன்றத்தின் ஒவ்வொரு பகுதியும் ஓடு 1 அல்லது ஓடு 2 ஆகியவற்றைக் கொண்டுள்ளது. அவை சாதாரணமாக அமைக்கப்படலாம் அல்லது 180 டிகிரி புரட்டலாம்.
அடிப்படை கட்டுமான (அசெம்பிளி) முறை
தளங்கள், நபர்கள் மற்றும் வரைபடங்களின் ரெண்டரிங் அடைய முடிந்ததும், அடிப்படை அசெம்பிளி பயன்முறையும் தேவை என்பதை உணர்ந்தேன். நான் அதை இவ்வாறு செயல்படுத்தினேன்: பொத்தானை அழுத்தும் போது, பொருள் தேர்ந்தெடுக்கப்பட்டது, மற்றும் கிளிக் அதை விரும்பிய இடத்தில் வைக்கிறது. எனவே, பொத்தான் 1 ஒரு நீதிமன்றத்தைத் தேர்ந்தெடுக்க உங்களை அனுமதிக்கிறது, மேலும் பொத்தான் 2 ஒரு வீரரைத் தேர்ந்தெடுக்க உங்களை அனுமதிக்கிறது.
ஆனால் 1 மற்றும் 2 என்றால் என்ன என்பதை நாம் இன்னும் நினைவில் வைத்திருக்க வேண்டும், எனவே எந்தப் பொருள் தேர்ந்தெடுக்கப்பட்டது என்பதை தெளிவுபடுத்த வயர்ஃப்ரேமைச் சேர்த்துள்ளேன். இப்படித்தான் தெரிகிறது.
கட்டிடக்கலை மற்றும் மறுசீரமைப்பு கேள்விகள்
இப்போது என்னிடம் பல விளையாட்டு பொருட்கள் உள்ளன: மக்கள், நீதிமன்றங்கள் மற்றும் தளங்கள். ஆனால் வயர்ஃப்ரேம்கள் வேலை செய்ய, ஒவ்வொரு பொருளுக்கும் பொருள்கள் விளக்கப் பயன்முறையில் உள்ளதா அல்லது ஒரு சட்டகம் வெறுமனே வரையப்பட்டதா என்பதைச் சொல்ல வேண்டும். இது மிகவும் வசதியானது அல்ல.
சில வரம்புகளை வெளிப்படுத்தும் வகையில் கட்டிடக்கலை மறுபரிசீலனை செய்யப்பட வேண்டும் என்று எனக்குத் தோன்றியது:
ஒரு உட்பொருளை ரெண்டர் செய்து தன்னைப் புதுப்பித்துக்கொள்வது ஒரு பிரச்சனையாகும், ஏனெனில் அந்த நிறுவனத்தால் அது என்ன வழங்க வேண்டும் என்பதை "தெரிந்துகொள்ள" முடியாது - ஒரு படம் மற்றும் வயர்ஃப்ரேம்;
தனிப்பட்ட நிறுவனங்களுக்கு இடையே பண்புகள் மற்றும் நடத்தை பரிமாற்றத்திற்கான கருவி இல்லாதது (உதாரணமாக, is_build_mode சொத்து அல்லது நடத்தை ரெண்டரிங்). ரஸ்டில் அதைச் செயல்படுத்த சரியான வழி இல்லை என்றாலும், பரம்பரையைப் பயன்படுத்துவது சாத்தியமாகும். எனக்கு உண்மையில் தேவைப்பட்டது தளவமைப்பு;
நீதிமன்றங்களுக்கு மக்களை நியமிக்க நிறுவனங்களுக்கிடையேயான தொடர்புக்கான ஒரு கருவி தேவைப்பட்டது;
நிறுவனங்கள் தாங்களாகவே தரவு மற்றும் தர்க்கத்தின் கலவையாக இருந்தன, அவை விரைவாக கட்டுப்பாட்டை இழந்தன.
மேலும் சில ஆராய்ச்சி செய்து கட்டிடக்கலையை கண்டுபிடித்தேன் ECS - நிறுவன கூறு அமைப்பு, இது பொதுவாக விளையாட்டுகளில் பயன்படுத்தப்படுகிறது. ECS இன் நன்மைகள் இங்கே:
தரவு தர்க்கத்திலிருந்து பிரிக்கப்படுகிறது;
பரம்பரைக்கு பதிலாக கலவை;
தரவு மையக் கட்டமைப்பு.
ECS மூன்று அடிப்படைக் கருத்துகளால் வகைப்படுத்தப்படுகிறது:
நிறுவனங்கள் - அடையாளங்காட்டி குறிப்பிடும் பொருளின் வகை (அது ஒரு வீரர், ஒரு பந்து அல்லது வேறு ஏதாவது இருக்கலாம்);
கூறுகள் - நிறுவனங்கள் அவற்றால் ஆனவை. எடுத்துக்காட்டு - ரெண்டரிங் கூறு, இருப்பிடங்கள் மற்றும் பிற. இவை தரவுக் கிடங்குகள்;
அமைப்புகள் - அவை பொருள்கள் மற்றும் கூறுகள் இரண்டையும் பயன்படுத்துகின்றன, மேலும் இந்தத் தரவை அடிப்படையாகக் கொண்ட நடத்தை மற்றும் தர்க்கத்தைக் கொண்டிருக்கின்றன. ஒரு உதாரணம் ரெண்டரிங் சிஸ்டம், இது ரெண்டரிங் கூறுகளுடன் அனைத்து நிறுவனங்களின் மூலமாகவும் திரும்பவும் ரெண்டரிங் செய்கிறது.
அதைப் படித்த பிறகு, ECS பின்வரும் சிக்கல்களைத் தீர்க்கிறது என்பது தெளிவாகியது:
நிறுவனங்களை முறையாக ஒழுங்கமைக்க பரம்பரைக்கு பதிலாக தளவமைப்பைப் பயன்படுத்துதல்;
கட்டுப்பாட்டு அமைப்புகள் மூலம் குறியீடு குழப்பத்திலிருந்து விடுபடுதல்;
வயர்ஃப்ரேம் லாஜிக்கை ஒரே இடத்தில் வைக்க is_build_mode போன்ற முறைகளைப் பயன்படுத்துகிறது - ரெண்டரிங் அமைப்பில்.
ECS ஐ நடைமுறைப்படுத்திய பிறகு இதுதான் நடந்தது.
வளங்கள் -> இங்குதான் அனைத்து சொத்துகளும் உள்ளன (படங்கள்)
மூல
- கூறுகள்
- பதவி.ஆர்.எஸ்
- நபர்.ஆர்.எஸ்
— tennis_court.rs
- தரை.ஆர்.எஸ்
- wireframe.rs
— mouse_tracked.rs
- வளங்கள்
—சுட்டி.RS
- அமைப்புகள்
- rendering.rs
- மாறிலிகள்.ஆர்.எஸ்
— utils.rs
— world_factory.rs -> உலக தொழிற்சாலை செயல்பாடுகள்
— main.rs -> முக்கிய வளையம்
நீதிமன்றங்களுக்கு ஆட்களை நியமிக்கிறோம்
ECS வாழ்க்கையை எளிதாக்கியுள்ளது. இப்போது நிறுவனங்களுக்கு தரவைச் சேர்ப்பதற்கும் அந்தத் தரவின் அடிப்படையில் தர்க்கத்தைச் சேர்ப்பதற்கும் ஒரு முறையான வழி இருந்தது. இது, நீதிமன்றங்களுக்கிடையில் மக்கள் விநியோகத்தை ஒழுங்கமைப்பதை சாத்தியமாக்கியது.
நான் என்ன செய்தேன்:
நபருக்கு ஒதுக்கப்பட்ட நீதிமன்றங்கள் பற்றிய தரவு சேர்க்கப்பட்டது;
டென்னிஸ் கோர்ட்டில் விநியோகிக்கப்பட்ட நபர்களைப் பற்றிய தரவு சேர்க்கப்பட்டது;
கோர்ட்சூசிங் சிஸ்டம் சேர்க்கப்பட்டது, இது மக்களையும் நீதிமன்றங்களையும் பகுப்பாய்வு செய்யவும், கிடைக்கக்கூடிய நீதிமன்றங்களைக் கண்டறியவும் மற்றும் அவர்களுக்கு வீரர்களை விநியோகிக்கவும் உங்களை அனுமதிக்கிறது;
ஒரு PersonMovementSystem ஐச் சேர்த்தது, இது நீதிமன்றங்களுக்கு ஒதுக்கப்பட்ட நபர்களைத் தேடுகிறது, மேலும் அவர்கள் அங்கு இல்லை என்றால், அவர்கள் இருக்க வேண்டிய இடத்திற்கு மக்களை அனுப்புகிறது.
சுருக்கமாக
இந்த எளிய விளையாட்டில் வேலை செய்வதை நான் மிகவும் ரசித்தேன். மேலும், நான் அதை எழுத ரஸ்ட்டைப் பயன்படுத்தியதில் மகிழ்ச்சி அடைகிறேன், ஏனெனில்:
துரு உங்களுக்குத் தேவையானதைத் தருகிறது;
இது சிறந்த ஆவணங்களைக் கொண்டுள்ளது, துரு மிகவும் நேர்த்தியானது;
நிலைத்தன்மை குளிர்ச்சியாக உள்ளது;
C++ இல் நான் அடிக்கடி செய்த குளோனிங், நகலெடுத்தல் அல்லது பிற ஒத்த செயல்களை நீங்கள் நாட வேண்டியதில்லை;
விருப்பங்களைப் பயன்படுத்துவது மிகவும் எளிதானது மற்றும் பிழைகளை நன்றாகக் கையாளுகிறது;
திட்டத்தை தொகுக்க முடிந்தால், அது 99% நேரம் வேலை செய்கிறது, அது சரியாக இருக்க வேண்டும். நான் பார்த்ததில் கம்பைலர் பிழைச் செய்திகள் சிறந்தவை என்று நினைக்கிறேன்.
ரஸ்டில் கேம் டெவலப்மெண்ட் இப்போதுதான் தொடங்குகிறது. ஆனால் அனைவருக்கும் ரஸ்ட்டைத் திறக்க ஏற்கனவே ஒரு நிலையான மற்றும் மிகப் பெரிய சமூகம் செயல்பட்டு வருகிறது. எனவே, மொழியின் எதிர்காலத்தை நான் நம்பிக்கையுடன் பார்க்கிறேன், எங்கள் பொதுவான வேலையின் முடிவுகளை எதிர்நோக்குகிறேன்.