Menu

Nakov.com logo

Thoughts on Software Engineering

Да си направим уеб игра: „Обстреляй плодовете!“

Наскоро разписах за моите студенти един постъпков самоучител (tutorial) как да си направят уеб базирана игра със C#, Visual Studio и ASP.NET MVC. Споделям, защото се получи доста приятна игричка. Самоучителят е подходящ за начинаещи с базови умения по C#. Не са необходими предварителни познания по уеб технологии, единствено начални познания по писане на код – променливи, проверки, цикли, C#, HTML. Този самоучител отнема половин-един час.

Целта е да се разработи ASP.NET MVC уеб приложение – игра, в която играчът стреля по плодове, подредени в таблица. Успешно уцелените плодове изчезват, а играчът получава точки за всеки уцелен плод. При уцелване на динамит, плодовете се взривяват и играта свършва (като във Fruit Ninja).

Стрелбата се извършва по колони, отгоре надолу или отдолу нагоре, а местоположението на удара (колоната под обстрел) се задава чрез скролер (scroll bar). Заради неточността на скролера, играчът не е съвсем сигурен по коя колона ще стреля. Така при всеки изстрел има шанс да не улучи и това прави играта по-интересна (подобно на прашката в Angry Birds).


Следват стъпките за създаване на играта, започвайки от нулата.

Създайте уеб приложение във Visual Studio

Във Visual Studio създайте ново ASP.NET MVC уеб приложение с език C#. Добавете нов проект от [Solution Explorer] à [Add] à [New Project…] . Дайте смислено име, например “Fruits-Web-Game“:

Изберете тип на уеб приложението “MVC“:

Създайте контролите за играта

Целта е да добавите скролиращи ленти (scroll bars), с които се играчът се прицелва, и бутон за старт на нова игра. Редактирайте файла Views/Home/Index.cshtml. Изтрийте всичко и въведете кода от картинката:

Този код създава уеб форма <form> със скролер (поле) “position” за задаване на число в интервала [0…100] и бутон [Fire Top] за изпращане на данните от формата към сървъра. Действието, което ще обработи данните, се казва “/Home/FireTop“, което означава метод “FireTop” в контролер “Home“, който се намира във файла “HomeController.cs“. Следват още две подобни форми с бутони [Fire Bottom] и [New Game].

Подготвяне на плодовете

Сега трябва да подготвите плодовете за рисуване в изгледа. Добавете кода от картинката в контролера Controllers/HomeController.cs:

Горният код дефинира полета за брой редове, брой колони, за таблицата с плодовете (игралното поле), за натрупаните от играча точки и информация дали играта е активна или е свършила (поле gameOver). Игралното поле е с рамери 9 колони на 3 реда и съдържа за всяко поле текст какво има в него: apple, banana, orange, kiwi, empty или dynamite.

Главното действие Index() подготвя игралното поле за чертане като записва във ViewBag структурата елементите на играта и извиква изгледа, който ги чертае в страницата на играта в уеб браузъра като HTML.

Генерирайте случайни плодове

За да генерирате случайни плодове, трябва да напишете метод GenerateRandomFruits() с кода от картинката по-долу. Този код записва в таблицата (матрицата) fruits имена на различни картинки и така изгражда игралното поле. Във всяка клетка от таблицата се записва една от следните стойности: apple, banana, orange, kiwi, empty или dynamite. След това, за да се нарисува съответното изображение в изгледа, към текста от таблицата ще се долепи “.png” и така ще се получи името на файла с картинката, която да се вмъкне в HTML страницата като част от игралното поле. Попълването на игралното поле (9 колони с по 3 реда) става в изгледа Index.cshtml с два вложени for-цикъла (за ред и за колона).

За да се генерират случайни плодове за всяка клетка се генерира случайно число между 0 и 8 (вж. класа Random() в .NET). Ако числото e 0 или 1, се слага apple, ако е между 2 и 3, се слага banana и т.н. Ако числото е 8, се поставя dynamite. Така плодовете се появяват 2 пъти по-често отколкото динамита. Ето и кода:

Добавяне на картинките за играта

От [Solution Explorer] направете папка “images” в коренната директория на проекта. Използвайте менюто [Add] à [New Folder].

Сега добавете картинките за играта (те са предоставени в архива Fruit-Game-WebApp-Images.zip). Копирайте ги от Windows Explorer и ги поставете в папката “images” в [Solution Explorer] във Visual Studio с copy / paste.

Чертане на плодовете в Index.cshtml

За да начертаете игралното поле с подовете, трябва да завъртите два вложени цикъла (за редовете и за колоните). Всеки ред се състои от 9 на брой картинки, всяка от които съдържа apple, banana или друг плод или празно (empty) или динамит (dynamite). Картинките се чертаят като се отпечата HTML таг за вмъкване на картинка от вида на <img src=”/images/apple.png” />. Девет картинки се подреждат една след друга на всеки от редовете, а след тях се преминава на нов ред с <br />. Това се повтаря три пъти за трите реда. Накрая се отпечатват точките на играча. Ето как изглежда кодът за чертане на игралното поле и точките:

Обърнете внимание на жълтите символи @ – те служат за превключване между езика C# и езика HTML и идват от Razor синтаксиса за рисуване на динамични уеб страници.

Промяна на текстовете в _Layout.cshtml

Нагласете текстовете във файла /Views/Shared/_Layout.cshtml. Заменете “My ASP.NET Application” с по-подходящи текстове, например “Fruits“:

Стартиране и тестване на играта

Стартирайте проекта с [Ctrl+F5] и му се порадвайте. Очаква се да бъде генерирано случайно игрово поле с плодове с размери 9 на 3 и да се визуализира в уеб страницата чрез поредица картинки:

Сега играта е донякъде направена: игралното поле се генерира случайни и се визуализира успешно (ако не сте допуснали грешка някъде). Остава да се реализира същината на играта: стрелянето по плодовете.

Имплементиране на действията: нова игра, стрелба отгоре, стрелба отдолу

Добавете действията [New Game] и [Fire Top] / [Fire Top] в контролера “HomeController.cs“:

Горният код дефинира три действия:

  • Reset() – стартира нова игра, като генерира новo случайно игрално поле с плодове и експлозиви, нулира точките на играча и прави играта валидна (gameOver = false). Това действие е доста просто и може да се тества веднага с [Ctrl+F5], преди да се напишат другите.
  • FireTop(position) – стреля по ред 0 на позиция position (число от 0 до 100). Извиква се стреляне в посока надолу (+1) от ред 0 (най-горния). Самото стреляне е по-сложно като логика и ще бъде разгледано след малко.
  • FireBottom(position) – стреля по ред 2 на позиция position (число от 0 до 100). Извиква се стреляне в посока нагоре (-1) от ред 2 (най-долния).
  • Имплементирайте “стрелянето” – метода Fire(position, startRow, step):

Стрелянето работи по следния начин: първо се изчислява номера на колоната col, към която играчът се е прицелил. Входното число от скролера (между 0 и 100) се намалява до число между 0 и 8 (за всяка от 9-те колони). Номерът на реда row е или 0 (ако изстрелът е отгоре) или броят редове минус едно (ако изстрелът е отдолу). Съответно посоката на стрелба (стъпката) е 1 (надолу) или -1 (нагоре).

За да се намери къде изстрелът поразява плод или динамит, се преминава в цикъл през всички клетки от игралното в прицелената колона и от първия до последния атакуван ред. Ако се срещне плод, той изчезва (замества се с empty) и се дават точки на играча. Ако се срещне dynamite, играта се отбелязва като свършила.

Оставаме на по-запалените да имплементират по-сложно поведение, например да се дават различни точки при уцелване на различен плод, да се реализира анимация с експлозия (това не е твърде лесно), да се взимат точки при излишно стреляне в празна колона и подобни.

Тествайте играта

Тествайте какво работи до момента като стартирате с [Ctrl+F5]:

  • Нова игра à бутонът за нова игра трябва да генерира ново игрално поле със случайно разположени плодове и експлозиви и да нулира точките на играча.
  • Стреляне отгоре à стрелянето отгоре трябва да премахва най-горният плод в уцелената колона или да предизвиква край на играта при динамит. Всъщност при край на играта все още нищо няма да се случва, защото в изгледа този случай още не се разглежда.
  • Стреляне отдолу à стрелянето отдолу трябва да премахва най-долния плод в уцелената колона или да прекратява играта при уцелване на динамит.

Край на играта – имплементация

Имплементирайте “Край на играта“. За момента при край на играта нищо не се случа. Ако играчът уцели динамит, в контролера се отбелязва, че играта е свършила (gameOver = true), но този факт не се визуализира по никакъв начин. За да заработи свършването на играта, е необходимо да добавим няколко проверки в изгледа:

Кодът по-горе проверява дали е свършила играта и показва съответно контролите за стреляне и игралното поле (при активна игра) или картинка с експлодирали плодове при край на играта.

Тестване отново

След промяната в кода на изгледа стартирайте с [Ctrl+F5] и тествайте играта отново:

Този път при уцелване на динамит, трябва да се появи дясната картинка и да се позволява единствено действието “нова игра” (бутонът [New Game]).

Изтеглете сорс кода на играта

Ако сте нетърпеливи, може да изтеглите наготово цялата игра и да я стартирате с [Ctrl+F5]. Изтеглете сорс кода: Fruits-Web-Game.zip.

Comments (8)

8 Responses to “Да си направим уеб игра: „Обстреляй плодовете!“”

  1. Martin G. says:

    Бе трудничко ми се струва, но ще се пробвам само за тръпката… Ще пиша пак с резултати

  2. Gamemorph says:

    Их че интересно. Понеже съм старото поколение и още се мъча с новите технологии, не вдянах това ESP.NET някаква платформа с този език ли е? Не е ХТМЛ 5, не ми изглежда жаба, C++ видях някъде, но научквам просто 🙂 Или може би е комплекс от тез наща, което е доста сложничко наистина, в сравнение с глупавия флаш поне 🙂

    • Zdravko says:

      .Net е цяла платформа създадена от Майкрософт и C#, ASP.Net са част от нея за уеб програминг. Специално тук няма нито С++, нито Джава

  3. Tonya Belezireva says:

    Страхотно! За учениците в 12-ти клас “Системен програмист”, за които MVC е толкова сложно и неразбираемо е направо забавление! И за мен, учителката – облекчение! Огромно БЛАГОДАРЯ! Отново ми помогнахте! 🙂

    • Programisti ot 12 klas says:

      Изключително мъчителна задача аз да не съм някой програмист в НАСА . Плодовете трябва да се намират в пазара краснодар ж.к. Възраждане , а бомбите в граничната служба . Образовайте се
      return(“Ebi si maikata”)

      • pointer says:

        Стига рева, а се стегни. Задачата е изключително лесна. Не знам колко трябва да е малък умствения ти капацитет, за да не я разбереш. Това, че Наков не може да приложе принципите на обекто ориентирания език сигурно я прави “трудна” за разбиране.

RSS feed for comments on this post. TrackBack URL

Leave a Reply to Martin G.