Научете се да програмирате XNA игри за Windows Phone 7 "Mango"

научете

Морската битка, която ще напишем, не е играта, която мнозина са играли в детството на карирана хартия. Това е игра, която беше достъпна в слот машини, където трябваше да уцелите плаващ кораб с няколко изстрела. Нашата игра също ще има кораб, плаващ в горната част на екрана и снаряди, които могат да бъдат изстреляни от долната част на екрана, като го докоснете.

Архитектурата на XNA приложение е много различна от класическото Windows или уеб приложение. Не използва събитиен модел, защото не е много подходящ за решаване на проблеми в реално време – а ние искаме играта да се развива пред очите ни в реално време, със скорост поне 25 кадъра в секунда! Следователно играта има много прост програмен модел -игрови цикъл. В началото на играта (или нивото на играта) се извиква специалната функцияLoadContent за зареждане на основните ресурси (графични и звукови елементи), след което методитеUpdate (за актуализиране на състоянието на играта в зависимост от действията на потребителя с входните устройства) иDraw (за изчертаване на състоянието на играта на екрана) се извикват последователно в цикъла. По този начин, за да напишете игра, трябва да извършите няколко основни действия:

  1. Създайте елементи за графичен и звуков дизайн за играта и ги поставете в проекта. Инструментите на Microsoft Expression са много подходящи за създаване на графични елементи. Графичните елементи могат да бъдат 2D спрайтове или 3D модели.
  2. Опишете променливи за съхраняване на всички необходими елементи и заменете методаLoadContent, за да ги заредите в паметта.
  3. Разберете как ще изглежда състоянието на играта - т.е.набор от променливи и структури от данни, които ще описват играта във всеки даден момент. Състоянието може да бъде много просто (както в нашия пример, координатите на кораба и снаряда) или може да се състои от много независими взаимодействащи обекти или агенти със собствен интелект и логика.
  4. Обработвайте действията на потребителя с устройства за въвеждане и програмирайте логиката за промяна на състоянието на играта в методаАктуализиране.
  5. Програмирайте показването на състоянието на екрана в методаDraw. Тук отново може да се използва 2D или 3D графика, в зависимост от стила на играта.
  6. Ако играта е по-сложна, съдържа няколко нива и т.н. - може да е полезно да подобрите обектния модел, за да отделите всяко ниво в отделен клас - тогава за всяко ниво ще трябва частично да повторите описаните по-горе стъпки
  7. Играйте, наслаждавайте се, споделяйте играта с други (това включва стъпки като създаване на инсталатор, разпространение на играта чрез Windows Mobile Marketplace, XBox Indie Games и др.).

graphics.PreferredBackBufferW > graphics.PreferredBackBufferHeight = 800; * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Обърнете внимание - в създаденото решение има два проекта: самата игра и ресурси на играта (Съдържание) - изображения, звуци и др. Самата игра има два класа - Program.cs е необходим за стартиране на играта, а Game1.cs съдържа основната логика на играта (функции LoadContent/Update/Draw) и именно този клас ще модифицираме.

Графичното съдържание в нашия случай ще се състои от три елемента - изображения на кораб и експлозия, които ще вземем от колекцията клипарти на Microsoft Office и изображение на снаряд - червена линия, която може да бъде начертана в Paint. Получените графични файловенека го добавим към проекта Content на нашата игра (използвайки менюто Add Existing Item) - резултатът може да се види на фигурата по-горе.

След това описваме променливите, отговорни за състоянието на играта. Ще трябва да съхраняваме графични изображения на кораба, ракетата и експлозията - те ще бъдат от типа Texture2D, координатите и скоростта на кораба (скоростта е необходима, за да зададем посоката), както и координатите на ракетата - това ще бъдат обекти от типа Vector2. Освен това, за да нарисувате експлозия, ще ви е необходима променливата explode - тя ще отброява броя кадри, по време на които се показва експлозия вместо кораб.

Texture2D кораб, ракета, експлозия; Vector2 ship_pos = нов Vector2(100, 100); Vector2 ship_dir = нов Vector2(3, 0); Вектор2 rock_pos = Вектор2.Нула;

int експлозия = 0; * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Методът LoadContent за зареждане на съдържанието на играта ще изглежда доста прост (описанието на функцията и първият ред бяха генерирани автоматично при създаването на проекта, трябваше само да добавим три реда, за да заредим ресурсите, които описахме):

защитена отмяна void LoadContent() spriteBatch = нов SpriteBatch(GraphicsDevice); изпращане = Съдържание.Зареждане

( "Кораб" ); ракета = Съдържание.Зареждане

("Ракета"); експлозия = Съдържание.Зареждане

> * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Методът на рисуване също е доста прост:

protected override void Draw(GameTime gameTime) GraphicsDevice.Clear(Color.White); spriteBatch.Begin(); ако (разрушаване > 0) spriteBatch.Draw(експлозия, ship_pos, Color.White); else spriteBatch.Draw(ship, ship_pos,Color.White); ако (rock_pos != Vector2.Zero)< spriteBatch.Draw(ракета, rock_pos, Color.Red); > spriteBatch.End(); база .Draw(gameTime); > * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Тук трябва да се отбележи една тънкост - когато рисуваме спрайтове на екрана, рисуваме картини на „порции“, наречениSpriteBatch. Съответно отваряме такава „транзакция за рисуване“ с извикване на spriteBatch.Begin() и завършваме с извикване на spriteBatch.End(), между които има извиквания на spriteBatch.Draw() или DrawString(..). В нашия случай рисуваме или кораб, или изображение на експлозия - в зависимост от променливата за експлозия, и също показваме ракета, ако е изстреляна и лети към кораба - това се задава от ненулевата стойност на координатния вектор rock_pos на ракетата.

Сега нека да преминем към метода Update. Ще го разгледаме на части. Първата част е отговорна за начертаването на експлозията: когато променливата на флага за експлозия е различна от нула, единствената задача на нашата игра е да начертае експлозията. Затова просто намаляваме брояча на кадрите, по време на които се показва експлозията, и когато достигне нула, връщаме кораба в първоначалната му позиция, така че играта да започне отново:

защитена замяна void Update(GameTime gameTime) if (explode > 0) explode--; ако (взрив == 0) ship_pos.X = 0; dir_ship.X = 3; > база .Update(gameTime); връщане; > . база .Update(gameTime); > * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Обърнете внимание, че в края на метода Update се извиква методът Update на базовия клас.

Следният кодов фрагмент отговаря за движението на кораба отляво надясно:

ship_pos += ship_dir; if (ship_pos.X + ship.Width >= 480 ship_pos.X * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Ето ни тукизрично използвайте разделителната способност на екрана - на практика, разбира се, не трябва да правите това, по-добре е да зададете константи в началото на програмата или да използвате променливи, които се инициализират по време на играта, в зависимост от конкретното устройство.

var tc = TouchPanel.GetState(); ако (tc.Count>0) rock_pos.X = tc[0].Position.X; скала_поз.Y = 750; > * Този изходен код беше маркиран с инструмента за открояване на изходния код.

Следва кодът, отговорен за движението на ракетата и тестването на сблъсъка на ракетата с кораба:

if (rock_pos != Vector2.Zero) rock_pos += нов Vector2(0, -7); if (rock_pos.Y >= 0 && rock_pos.Y = ship_pos.X && rock_pos.X if (rock_pos.Y == 0) rock_pos = Vector2.Zero; > * Този изходен код беше маркиран с инструмента за открояване на изходния код.

За да преместим ракетата, ние просто добавяме стойността на скоростта като 2D вектор на всеки цикъл на игра. Сблъсъкът се определя „ръчно“ по координати (за по-сложни фигури има смисъл да се използват други функции за откриване на пресичане от XNA) - в случай на поражение се задава променливата за експлозия, което означава, че ще бъде показана експлозия вместо кораба за следващите няколко кадъра. Ако ракетата достигне горната граница на екрана, движението й спира (задават се нулеви координати).

За да придадете на играта максимална достоверност, има смисъл да отразявате образа на кораба, когато той плава наляво (така че да не плава „назад“). За да направим това, леко ще променим кода за показване на кораба, като добавим възможността да го отразяваме:

if (explode == 0) spriteBatch.Draw(ship, ship_pos, null, Color.White,0f, Vector2.Zero,1.0f, ship_dir.X>0? SpriteEffects.FlipHorizontally:SpriteEffects.None,0f); > друго spriteBatch.Draw(експлозия, ship_pos, Color.White);

* Този изходен код беше подчертан с инструмента за открояване на изходния код.

Това е всичко, което е необходимо, за да напишете проста игра. За да го направите по-привлекателен, струва си да нарисувате красив графичен фон, върху който ще се разгръща стрелбата - за това е достатъчно да нарисувате съответното изображение в началото на spriteBatch, така че всички следващи обекти да бъдат изчертани в горната част на картината. Можете също така да добавите брояч на посещения – в този случай, за да изчертаете низа, ще трябва да използвате метода spriteBatch.DrawString, а шрифтът, с който ще се показва низът, трябва да бъде поставен в ресурсите на проекта и зареден в метода LoadContent.

Можете да изтеглите изходния код за целия проект, за да го изследвате в свободното си време, или да го използвате като отправна точка за създаване на ваши собствени игри. Разбира се, този пример беше много прост и не е добър пример за това как игрите трябва да се пишат в действителност. Можете да намерите още много реалистични примери:

  • Отличен урок на английски за писане на 2D игра на create.msdn.com
  • Набор от англоезични XNA лаборатории, включително разработването на играта 2D Catapult Wars, която върши добра работа за структуриране на играта между екраните. Подобни лабораторни упражнения има в локализирания на български Windows Phone 7 Training Kit
  • За тези, които обичат да четат текста, има книга на Charles Petzold "Програмиране на Windows Phone 7" на български.
  • XNA видеоклипове на TechDays.ru
  • Общността XNADev.ru е българоезичен ресурс, в който не само ще намерите информация, но и ще можете да зададете въпрос във форумите и да получите квалифициран отговорот общността