Ћекции.ќрг


ѕоиск:




 атегории:

јстрономи€
Ѕиологи€
√еографи€
ƒругие €зыки
»нтернет
»нформатика
»стори€
 ультура
Ћитература
Ћогика
ћатематика
ћедицина
ћеханика
ќхрана труда
ѕедагогика
ѕолитика
ѕраво
ѕсихологи€
–елиги€
–иторика
—оциологи€
—порт
—троительство
“ехнологи€
“ранспорт
‘изика
‘илософи€
‘инансы
’ими€
Ёкологи€
Ёкономика
Ёлектроника

 

 

 

 


√лава 3. –азработка гаджета рабочего стола с использованием технологии Silverlight




3.1 —оздание Silverlight приложени€ дл€ гаджета ЂShooterї

√аджет (Sidebar Gadget) Ц название класса вспомогательных мини-программ Ц графических модулей, которые размещаютс€ в рабочем пространстве родительской программы и служат дл€ украшени€ рабочего пространства, развлечени€, решени€ отдельных рабочих задач или быстрого получени€ информации из интернета без помощи Web-браузера.

ƒл€ создани€ гаджета необходимо установить программное обеспечение:

ü Microsoft Visual Studio 2010

ü Silverlight4 Tools

ü Silverlight4 SDK

ѕосле установки Microsoft Visual Studio, а также всех необходимых компонент можно создавать Silverlight-приложение.

1. ¬ыбираем Ђ—оздать проектї

2. ќткроетс€ диалоговое окно —оздани€ проекта. —ледует убедитьс€, что в верхнем правом углу диалога выбран пункт.NET Framework4, и в списке “ипы проекта выбираем ѕриложение Silverlight.

3. ѕосле нажати€ кнопки ЂOKї Visual Studio запустит ћастер нового приложени€ Silverlight. Ётот мастер предлагает несколько вариантов создани€ и управлени€ Silverlight-приложением. ¬се Silverlight-приложени€ создаютс€ как пользовательские элементы управлени€, экземпл€ры которых затем могут быть созданы и размещены на странице. ѕринимаем настройки по умолчанию.
ћастер создаст новое решение Visual Studio, содержащее элемент управлени€ Silverlight.

“еперь можно приступать непосредственно к разработке.

ќбща€ иде€ игры

—оздаем игровое поле и размещаем на нем спрайты Ц класс, содержащий базовые объекты игры: корабль, пришельцы, снар€ды. ƒл€ каждого из них нам надо знать его координаты и как он выгл€дит.  оординаты мы будем отслеживать с помощью Point, а свойство типа Canvas будем использовать дл€ отображени€ XAML каждого объекта. ”правл€ть движением спрайтов будем с помощью класса Vector. Ќачать надо с выбора клавиш, которыми будет управл€тьс€ движение. «атем нам надо будет отслеживать их нажатие и выполн€ть соответствующие действи€. ¬ каждом цикле надо отслеживать, не столкнулась ли та или ина€ ракета с одним из пришельцев и не вылетела ли за пределы пол€, не коснулась ли бомба нашего корабл€ и не исчезла ли с экрана, а также нет ли нового выстрела пришельцев по нашему кораблю.

¬се это будет в теле цикла игры. ƒл€ каждой коллекции мы вызываем методы, просматривающие ее содержимое и выполн€ющие действи€ в зависимости от координат и столкновений спрайтов. ѕосле выполнени€ цикла каждой основной коллекции, мы проходим по соответствующей ей коллекции с удаленными элементами, удал€ем ненужные изображени€ с экрана и из основной коллекции. ¬ конце провер€ем, не настало ли врем€ пришельцам сбросить очередные бомбы.

Ѕолее подробное описание и программный код игры представлены в приложении [17].

«адачей €вл€етс€ создание виджета, поэтому в папке, где хранитс€ приложение открываем: Bin\Debug и содержимое этой папки добавл€ем в ZIP архив. ” получившегос€ архива мен€ем расширение с.zip на.gadget. √аджет готов. ¬ыполн€ем его установку на компьютер и размещаем на рабочий стол.


«аключение

Silverlight €вл€етс€ следующим шагом в направлении к улучшению взаимодестви€ с пользователем через веб. ÷ель Silverlight - обеспечить в веб-приложени€х точность отображени€ и качество пользовательского интерфейса доступное в настольных приложени€х, позвол€€ веб-разработчикам и дизайнерам реализовывать в создаваемых решени€х особые требовани€ заказчиков. Silverlight заполн€ет технологический вакуум между дизайнерами и разработчиками, предоставл€€ им общий формат дл€ работы. Ётот формат обрабатываетс€ браузером и основываетс€ на XML, что упрощает создание шаблонов и автоматическое формирование представлени€. “аким форматом €вл€етс€ XAML - Extensible Application Markup Language (расшир€емый €зык разметки приложений).

Microsoft Silverlight - это подключаемый модуль, который может использоватьс€ в разных браузерах и на разных платформах, разработанный дл€ обеспечени€ возможности создани€ сложных сценариев воспроизведени€ мультимедиа и создани€ насыщенных интерактивных интернет-приложений с использованием современных технологий.

¬ ходе исследовани€ изучена литература описывающа€ технологию Silverlight. Ѕольшинство литературы представлено на английском €зыке, а именно Silverlight 4: Problem Ц Design Ц Solution, автор Nick Lecrenski, Microsoft Silverlight 4 Data and Services Cookbook от Gill Cleeren, Kevin Dockx. Ќа русском €зыке представлена переведенна€ книга Ћоуренса ћорони - ¬ведение в MicrosoftЃ SilverlightЩ 3. Ќайдено несколько блогов, российских попул€ризаторов Silverlight, в которых описываютс€ новые введени€ в данной технологии. ќсобенно интересным €вл€етс€ блог ћихаила „ерномордикова.

¬ исследовании вы€влено, что гаджет рабочего стола - это небольшие инструменты (программы), выполн€ющие одну определенную функцию и требующие дл€ своей работы специальной среды Ч виджет-движка (widget engine). ќни могут показывать на рабочем столе вашего компьютера последние новости, слайд-шоу из фотографий, позвол€ть делать заметки на виртуальных стикерах, вести учЄт рабочего времени и многое другое.

¬ исследовании были изучены особенности строени€ гаджета рабочего стола операционной системы Windows 7. ¬ы€влено, что простейший гаджет это zip архив с расширением.gadget состо€щий из двух файлов: файл манифест, который включает в себ€ все настройки и информацию о гаджете, описанную на €зыке XML, и файл в котором описываетс€ внешний вид гаджета, его основна€ функциональность, а так же поведение при определенных действи€х пользовател€. ƒополнительно у гаджета могут быть файл настроек, файлы картинок и др.

¬ ходе работы был создан гаджет рабочего стола Ђshooterї. ќсобое внимание удел€лось применению технологии Silverlight дл€ создани€ гаджета рабочего стола, рассмотрен способ создани€, приведен код получившегос€ приложени€, таким образом цель исследовани€ была достигнута.


 

 

—писок литературы

1. Ѕайдачный —.—. Silverlight 4: —оздание насыщенных Web-приложений Ц ћ.: —ќЋќЌ-ѕ–≈——, 2010.

2. Ѕлог ћихаила „ерномордикова [Ёлектронный ресурс]. - –ежим доступа: http://blogs.msdn.com/b/mikcher/

3. ∆урнал MSDN Magazine [Ёлектронный ресурс]. - –ежим доступа: http://msdn.microsoft.com/ru-ru/magazine/cc163370.aspx

4.  рис јндерсон, ќсновы Windows Presentation Foundation. ѕер. с англ. ј. —линкина Ч ћ.: ƒћ ѕресс, 2008.

5. Ћеонтьев ¬.ѕ. Ќовейший самоучитель.  омпьютер + интернет 2013. Цћ.: ќЋћј ћедиа √рупп, 2013.

6. Ћоуренс ћорони. ¬ведение в Microsoft Silverlight 3. Ч 2-е изд. Ч R.: Microsoft Press, 2009.

7. ћэтью ћак-ƒональд. Silverlight 3 с примерами на C# дл€ профессионалов = Pro Silverlight 3 in C#. Ч 3-е изд. Ч ћ.: ¬иль€мс, 2010.

8. Ќастройки гаджетов [Ёлектронный ресурс]. - –ежим доступа: http://volginartem.wordpress.com/2011/02/14

9. Ќик –ендольф, ƒэвид √арднер, ћайкл ћинутилло,  рис јндерсон Visual Studio 2010 дл€ профессионалов Ч ћ.: Ђƒиалектикаї, 2011.

10. –аздел ЂMicrosoft Visual Studioї на сайте ћайкрософт [Ёлектронный ресурс]. - –ежим доступа: http://msdn.microsoft.com/ru-ru/vstudio/default.aspx

11. –азрабатываем свой Sidebar gadget [Ёлектронный ресурс]. - –ежим доступа: http://habrahabr.ru/post/71958/

12. —вободна€ энциклопеди€ [Ёлектронный ресурс]. - –ежим доступа: http://ru.wikipedia.org/wiki/Adobe_Flash

13. —вободна€ энциклопеди€ [Ёлектронный ресурс]. - –ежим доступа: http://ru.wikipedia.org/wiki/HTML5

14. —вободна€ энциклопеди€ [Ёлектронный ресурс]. - –ежим доступа: http://ru.wikipedia.org/wiki/Silverlight

15. —вободна€ энциклопеди€ [Ёлектронный ресурс]. - –ежим доступа: http://ru.wikipedia.org/wiki/¬иджет

16. —оздание гаджетов дл€ Windows Sidebar [Ёлектронный ресурс]. - –ежим доступа: http://designformasters.info/posts/windows-sidebar-gadget/

17. —оздание простой игры на Silverlight [Ёлектронный ресурс]. - –ежим доступа: http://blogs.msdn.com/b/rucoding4fun/archive/2009/07/30/e-silverlight.aspx

 


 

ѕриложение

 омпоновка экрана. ƒобавим полотно на сетку внутри Page.xaml. ≈го фон сделаем черным и назовем gameRoot.

<UserControl x:Class="SimpleShooter.Page"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="400" Height="300">

<Grid x:Name="LayoutRoot">

<Canvas x:Name="gameRoot" Width="500" Height="400" Background="Black">

</Canvas>

</Grid>

</UserControl>

«атем добавим элементы управлени€ дл€ объектов игры и отображени€ данных. “акже добавим в проект пользовательские элементы управлени€ Info, LivesRemaining, Score и WaveInfo. ќни включают текстовые блоки дл€ вывода данных о состо€нии игры. ћы же оставили простое полотно с непосредственным указанием координат Canvas.Top и Canvas.Left. —вои элементы управлени€ поместили в Page.xaml, задав дл€ каждого x:Name.   этому моменту каждый элемент управлени€ содержал лишь TextBlock.

<UserControl x:Class="SimpleShooter.Page"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:SimpleShooter="clr-namespace:SimpleShooter"

Width="500" Height="400">

<Grid x:Name="LayoutRoot">

<Canvas x:Name="gameRoot" Width="500" Height="400" Background="Black">

<SimpleShooter:RemainingLives x:Name="ctlLives" Canvas.Top="380" Canvas.Left="10" />

<SimpleShooter:Score x:Name="ctlScore" Canvas.Top="10" Canvas.Left="10" />

<SimpleShooter:WaveInfo x:Name="ctlWaveInfo" Canvas.Left="440" Canvas.Top="10" />

<SimpleShooter:Info x:Name="ctlInfo" Canvas.Top="10"/>

</Canvas>

</Grid>

</UserControl>

 

ƒобавим к нашему экрану звездное поле. ƒл€ этого напишем функцию генерации случайных чисел, а также другую, котора€ будет случайным образом располагать эллипсы на нашем базовом полотне. Ќам потребуетс€ наследование от System.Security.Cryptography:

public partial class Page: UserControl

{

public Page()

{

InitializeComponent();

GenerateStarField(350);

}

void GenerateStarField(int numberOfStars)

{

for (int i = 0; i < numberOfStars; i++)

{

Ellipse star = new Ellipse();

double size = GetRandInt(10, 800) *.01;

star.Width = size;

star.Height = size;

star.Opacity = GetRandInt(1, 5) *.1;

star.Fill = new SolidColorBrush(Colors.White);

int x = GetRandInt(0, (int)Math.Round(gameRoot.Height, 0));

int y = GetRandInt(0, (int)Math.Round(gameRoot.Width, 0));

star.SetValue(Canvas.TopProperty, (double)x);

star.SetValue(Canvas.LeftProperty, (double)y);

gameRoot.Children.Add(star);

}

}

 

public int GetRandInt(int min, int max)

{

Byte[] rndBytes = new Byte[10];

RNGCryptoServiceProvider rndC = new RNGCryptoServiceProvider();

rndC.GetBytes(rndBytes);

int seed = BitConverter.ToInt32(rndBytes, 0);

Random rand = new Random(seed);

return rand.Next(min, max);

}

}

 

“еперь у нас есть функци€ GenerateStarField. ќбратите внимание на то, что каждый эллипс добавл€етс€ к коллекции Children нашего базового полотна gameRoot, а также на способ задани€ координат этих эллипсов посредством свойств Top и Left. “еперь у нас есть фон и базова€ структура экрана нашей игры.

ƒалее мы добавим в нашу программу классы, представл€ющие спрайты и векторы:

public abstract class Sprite

{

public double Width { get; set; }

public double Height { get; set; }

public Vector Velocity { get; set; }

public Canvas SpriteCanvas { get; set; }

private Point _position;

public Point Position

{

get

{

return _position;

}

set

{

_position = value;

SpriteCanvas.SetValue(Canvas.TopProperty, _position.Y - (Height / 2));

SpriteCanvas.SetValue(Canvas.LeftProperty, _position.X - (Width / 2));

}

}

 

public Sprite(Double width, Double height, Point position)

{

Width = width;

Height = height;

 

SpriteCanvas = RenderSpriteCanvas();

 

SpriteCanvas.Width = width;

SpriteCanvas.Height = height;

// ѕримечание: поскольку в установщике дл€ Position используютс€ и Height, и Width, важно, что это следует после их установки.


 

Position = position;

}

public abstract Canvas RenderSpriteCanvas();

public Canvas LoadSpriteCanvas(string xamlPath)

{

System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream(xamlPath);

return (Canvas)XamlReader.Load(new System.IO.StreamReader(s).ReadToEnd());

}

public virtual void Update(TimeSpan elapsedTime)

{

Position = (Position + Velocity * elapsedTime.TotalSeconds);

}

}

 ласс Sprite будет содержать такие базовые объекты игры, как корабль, пришельцы и снар€ды. ƒл€ каждого из них нам надо знать местонахождение и как он выгл€дит.  оординаты мы будем отслеживать с помощью Point, а свойство типа Canvas будем использовать дл€ отображени€ XAML каждого объекта. Ќачальные параметры этих свойств задаютс€ в конструкторе, а в каждом производном классе будет реализован метод RenderSpriteCanvas. Ётот метод позволит производному классу устанавливать содержимое полотна, управл€€ внешним видом спрайта. ” нас есть также класс, описывающий векторы, с помощью которого мы будем управл€ть движением спрайтов.

public struct Vector

{

public double X;

public double Y;

public Vector(double x, double y)

{

X = x;

Y = y;

}

public double Length

{

get

{

return Math.Sqrt(LengthSquared);

}

}

 

public double LengthSquared

{

get

{

return X * X + Y * Y;

}

}

public void Normalize()

{

double length = Length;

X /= length;

Y /= length;

}

public static Vector operator -(Vector vector)

{

return new Vector(-vector.X, -vector.Y);

}

public static Vector operator *(Vector vector, double scalar)

{

return new Vector(scalar * vector.X, scalar * vector.Y);

}

public static Point operator +(Point point, Vector vector)

{

return new Point(point.X + vector.X, point.Y + vector.Y);

}

static public Vector CreateVectorFromAngle(double angleInDegrees, double length)

{

double x = Math.Sin(DegreesToRadians(180 - angleInDegrees)) * length;

double y = Math.Cos(DegreesToRadians(180 - angleInDegrees)) * length;

return new Vector(x, y);

}

static public double DegreesToRadians(double degrees)

{

double radians = ((degrees / 360) * 2 * Math.PI);

return radians;

}

}

“еперь можем реализовать конкретный спрайт с помощью класса Ship. ƒобавьте в свой проект класс с именем Ship и файл Ship.xaml. Ќе забудьте установить свойства Ship.xaml в ЂEmbedded Resourceї. Ќам потребуетс€ наследование от класса Sprite:

public class Ship: Sprite

{

public Ship(double width, double height, Point firstPosition)

: base(width, height, firstPosition)

{

}

public override Canvas RenderSpriteCanvas()

{

return LoadSpriteCanvas("SimpleShooter.Sprites.Ship.xaml");

}

}

ѕри создании экземпл€ра Ship вызываетс€ конструктор его базового класса, Sprite. ¬ классе Ship также реализован метод RenderSpriteCanvas и определен XAML (просто белый квадрат) дл€ загрузки в полотно данного спрайта. “еперь мы можем добавить спрайт к нашей главной странице. ¬ этой несложной игре у нас есть всего один корабль (остальные Ч пришельцы), так что добавим к странице свойство и функцию, с помощью которой будет создаватьс€ экземпл€р корабл€:

<Canvas x:Name="LayoutRoot" Width="30" Height="30"

xmlns="http://schemas.microsoft.com/client/2007"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

<Rectangle Height="30" Width="30" Fill="White" />

</Canvas>

 

void InitializeGame()

{

PlayerShip = new Ship(10, 10, new Point(100, 300));

gameRoot.Children.Add(PlayerShip.SpriteCanvas);

}

Ётот метод мы можем вызывать из конструктора страницы, и при запуске проекта в левой нижней части страницы будет по€вл€тьс€ белый квадрат, представл€ющий наш корабль. ≈сли посмотреть внимательно, можно заметить, что размер страницы равен 500×400, а метод InitializeGame располагает корабль на рассто€нии 100 пикселов от левой границы полотна gameRoot и на 300 пикселов от его верхней границы.

Ќастало врем€ привести некоторые предметы в движение. Ќачать надо с выбора клавиш, которыми будет управл€тьс€ движение. «атем нам надо будет отслеживать их нажатие и выполн€ть соответствующие действи€. ќбработчик клавиатуры улавливает все событи€ нажати€ и отпускани€ клавиш. Ёто позвол€ет нам узнать о нажатии некоторой клавиши в любой момент. ÷икл игры Ч это просто непрерывный цикл. ¬ него входит раскадровка, котора€ запускаетс€ и тут же останавливаетс€.  ласс генерирует событие и раскадровка запускаетс€ снова. ѕодписчики событи€ Update предоставл€ют значение, указывающее интервал времени в миллисекундах с момента последнего обновлени€. Ёто значение может использоватьс€ в векторах дл€ реализации плавного движени€ спрайтов. Ќам надо добавить в класс Page экземпл€ры KeyHandler и GameLoop. »зменим конструкторы InitializeGame и Page, а также добавим обработчик дл€ GameLoop:

public Page()

{

InitializeComponent();

keyHandler = new KeyHandler(this);

GenerateStarField(350);

InitializeGame();

}

 

void InitializeGame()

{

gameLoop = new GameLoop(this);

gameLoop.Update += new GameLoop.UpdateHandler(gameLoop_Update);

 

PlayerShip = new Ship(10, 10, new Point(100, 360));

gameRoot.Children.Add(PlayerShip.SpriteCanvas);

 

gameLoop.Start();

}

 

void gameLoop_Update(TimeSpan elapsed)

{

// ќчистим текущий вектор, чтобы спрайт не двигалс€, когда не нажаты те или иные клавиши

PlayerShip.Velocity = new Vector(0, 0);

if (keyHandler.IsKeyPressed(Key.Left))

{

PlayerShip.Velocity = Vector.CreateVectorFromAngle(270, 125);

}

if (keyHandler.IsKeyPressed(Key.Right))

{

PlayerShip.Velocity = Vector.CreateVectorFromAngle(90, 125);

}

PlayerShip.Update(elapsed);

}

“еперь у нас есть работающий цикл игры. ≈сли запустить приложение и щелкнуть элемент управлени€ Silverlight, чтобы он получил фокус, то те≠перь мы сможем управл€ть кораблем кнопками со стрелками. ≈сть, правда, одна проблема Ч мы можете совсем сместить корабль за пределы экрана. „тобы исправить ситуацию, добавим в класс, описывающий корабль, свой≠ства MinX и MaxX и переопределим метод Update, который он наследует от Sprite. Ќадо также прибавить эти свойства дл€ минимального и максимального значений в методе InitializeGame класса Page после создани€ экземпл€ра Ship:

public class Ship: Sprite

{

public double MaxX { get; set; }

public double MinX { get; set; }

 

public Ship(double width, double height, Point firstPosition)

: base(width, height, firstPosition)

{

 

}

 

public override Canvas RenderSpriteCanvas()

{

return LoadSpriteCanvas("SimpleShooter.Sprites.Ship.xaml");

}

 

public override void Update(System.TimeSpan elapsedTime)

{

// ѕроверить, что к этой точке можно переместитьс€

if (Position.X > MaxX)

{

Position = new Point(MaxX, Position.Y);

Velocity = new Vector(0, 0);

}

if (Position.X < MinX)

{

Position = new Point(MinX, Position.Y);

Velocity = new Vector(0, 0);

}

base.Update(elapsedTime);

}

}

” нас есть все необходимое дл€ добавлени€ других спрайтов, таких как пришельцы и снар€ды. —начала добавим производные от Sprite классы: Alien, Missle и Bomb, а также Alien.xaml, Missle.xaml и Bomb.xaml (дл€ всех этих.xaml-файлов должен быть установлен параметр Embedded Resources). Ёти xaml-файлы аналогичны Ship.xaml и отличаютс€ лишь размерами и цветом. —делаем захватчиков (Aliens) и их бомбы красными, уменьшив длину и ширину бомб и ракет до п€ти. ‘айлы xaml очень похожи, а классы имеют несколько особенностей.  лассы Bomb и Missile отличаютс€ лишь загружаемыми xaml. ¬от класс Bomb:

public class Bomb: Sprite

{

public double MaxX { get; set; }

public double MinX { get; set; }

 

public Bomb(double width, double height, Point firstPosition)

: base(width, height, firstPosition)

{

 

}

 

public override Canvas RenderSpriteCanvas()

{

return LoadSpriteCanvas("SimpleShooter.Sprites.Bomb.xaml");

}

 

public override void Update(System.TimeSpan elapsedTime)

{

base.Update(elapsedTime);

}

}

ƒобавим класс Alien (пришелец), аналогичный классу Ship. ќба эти класса требуют дополнительных возможностей. ѕрежде всего, они должны уметь стрел€ть один в другого. Alien будет сбрасывать бомбы:

public class Alien: Sprite

{

public double fireRateMilliseconds = 2000;

public double fireVelocity = 250;

public double wayPointMin;

public double wayPointMax;

public double speed = 100;

public bool spawnWait;

public DateTime spawnComplete;

public double MaxX { get; set; }

public double MinX { get; set; }

 

public Alien(double width, double height, Point firstPosition)

: base(width, height, firstPosition)

{

 

}

 

public void CheckDirection()

{

if (Position.X > wayPointMax)

{

Velocity = Vector.CreateVectorFromAngle(270, speed);

}

if (Position.X < wayPointMin)

{

Velocity = Vector.CreateVectorFromAngle(90, speed);

}

}

 

public override Canvas RenderSpriteCanvas()

{

return LoadSpriteCanvas("SimpleShooter.Sprites.Alien.xaml");

}

public override void Update(TimeSpan elapsedTime)

{

CheckDirection();

base.Update(elapsedTime);

}

 

public Bomb Fire()

{

Bomb bomb = new Bomb(5, 5, Position);

bomb.Velocity = Vector.CreateVectorFromAngle(180, fireVelocity);

return bomb;

}

}

Ќам необходим механизм отслеживани€ столкновений снар€дов с другими спрайтами. ƒобавим в класс спрайта метод обнаружени€ столкновений. Ѕудем использовать зону, определ€емую радиусом CollisionRadius, измер€емым от центра спрайта. ƒл€ простоты будем считать радиус равным половине ширины спрайта. — помощью вектора, созданного из этих двух точек, мы сможем определ€ть, не превышает ли сумма этих двух радиусов длины нашего вектора. ≈сли это так, значит было столкновение:

public static bool Collides(Sprite s1, Sprite s2)

{

Vector v = new Vector((s1.Position.X) - (s2.Position.X), (s1.Position.Y) - (s2.Position.Y));

if (s1.CollisionRadius + s2.CollisionRadius > v.Length)

{

return true;

}

else

{

return false;

}

}

“еперь мы можем расширить наш цикл игры возможност€ми, превосход€щими отслеживание движени€ нашего корабл€. ѕрежде всего, добавим обработку дополнительных клавиш, не только стрелок. ƒл€ стрельбы будет использоватьс€ клавиша пробела. ƒобавим перечисление, описывающее состо€ни€ игры. “акже добавим класс, реализующий стрельбу. ќн будет достаточно простым, с большим потенциалом усовершенствовани€:

public enum GameState

{

Ready = 0,

Running = 1,

Paused = 2,

BetweenWaves = 3,

GameOver = 4

}

 

if (keyHandler.IsKeyPressed(Key.Space))

{

switch (status)

{

case GameState.Ready:

break;

case GameState.Running:

EntityFired(PlayerShip);

break;

case GameState.Paused:

break;

case GameState.BetweenWaves:

status = GameState.Running;

ctlInfo.GameInfo = "";

StartWave();

break;

case GameState.GameOver:

break;

default:

break;

}

}

 

void EntityFired(Sprite shooter)

{

Debug.WriteLine(shooter);

switch (shooter.ToString())

{

case "SimpleShooter.Ship":

if (missles.Count == 0)

{

Missle missle = ((Ship)shooter).Fire();

missles.Add(missle);

gameRoot.Children.Add(missle.SpriteCanvas);

 

}

break;

case "SimpleShooter.Alien":

Bomb bomb = ((Alien)shooter).Fire();

bombs.Add(bomb);

gameRoot.Children.Add(bomb.SpriteCanvas);

break;

default:

break;

}

}

„тобы состо€ние игры было проще отслеживать, добавим к нашим элементам управлени€ открытые свойства. Ќапример, добавим свойство Lives в элемент управлени€ ReamainingLives, причем установщик этого свойства будет обновл€ть TextBlock этого элемента управлени€, чтобы пользователь видел, сколько осталось жизней. јналогично поступим с остальными трем€ элементами управлени€:

public partial class RemainingLives: UserControl

{

private int _lives;

public int Lives

{

get { return _lives; }

set

{

_lives = value;

string livesString = string.Empty;

for (int i = 0; i < _lives - 1; i++)

{

livesString = string.Format("{0}{1}", livesString, "A");

}

txtRemainingLives.Text = livesString;

}

}

 

public RemainingLives()

{

InitializeComponent();

}

}

ѕришло врем€ добавить в наш основной класс и другие вещи. ¬ цикле игры нам придетс€ иметь дело со множеством объектов. ” нас будет свой корабль, некоторое число пришельцев, сколько-то бомб, а также наши ракеты, которые можно будет выпускать по одной с помощью метода EntityFired. ¬ каждом цикле надо отслеживать, не столкнулась ли та или ина€ ракета с одним из пришельцев и не вылетела ли за пределы пол€, не коснулась ли бомба нашего корабл€ и не исчезла ли с экрана, а также нет ли нового выстрела пришельцев по нашему кораблю. ¬ классе Page уже есть свойство Ship, но Aliens (пришельцы), Bombs (бомбы) и Missiles (ракеты) должны быть коллекци€ми. Ќапример, просматрива€ по очереди бомбы, нам будет удобно удал€ть те из них, которые попали в корабль или вышли за пределы игрового пол€. ѕоскольку мы собираемс€ производить итерацию этих коллекций, мы не можем удал€ть из них элементы в цикле. ≈сть множество решений этой задачи, но мы поступим просто: введем коллекции с удаленными элементами, соответствующие основным коллекци€м Bomb, Alien и Missile. ¬ дальнейшем, в цикле игры удал€емые элементы будут добавл€тьс€ в коллекцию с удаленными элементами и оставатьс€ в основной коллекции:

List<Alien> aliens;

List<Alien> aliensRemove;

List<Alien> alienShooters;

List<Bomb> bombs;

List<Bomb> bombsRemove;

List<Missle> missles;

List<Missle> misslesRemove;

Ќам также потребуетс€ класс дл€ отслеживани€ волн пришельцев, которые мы будем посылать по одной.  роме того, добавим коллекцию дл€ хранени€ этих волн. ¬ каждой волне будет отслеживатьс€ число пришельцев, по€вившихс€ за раз, общее число пришельцев в волне, количество пришельцев, сбросивших бомбы, а также частоту, с которой они могут метать бомбы.

public class WaveData

{

public WaveData(int count, double fireRate, int atOnce, int fireatonce)

{

EnemyCount = count;

fireRateMilliseconds = fireRate;

enemiesAtOnce = atOnce;

fireAtOnce = fireatonce;

waveEmpty = false;

}

public int EnemyCount { get; set; }

public double fireRateMilliseconds { get; set; }

public int enemiesAtOnce { get; set; }

public int fireAtOnce { get; set; }

public bool waveEmpty { get; set; }

}

Ќам надо установить инициализационный метод нашей игры, все коллекции дл€ спрайтов и добавить последовательно усложн€ющиес€ волны. ¬се это будет в теле цикла игры. ƒл€ каждой коллекции мы вызываем методы, просматривающие ее содержимое и выполн€ющие действи€ в зависимости от координат и столкновений спрайтов. ѕосле выполнени€ цикла каждой основной коллекции, мы проходим по соответствующей ей коллекции с удаленными элементами, удал€ем ненужные изображени€ с экрана и из основной коллекции. ¬ конце провер€ем, не настало ли врем€ пришельцам сбросить очередные бомбы:

void gameLoop_Update(TimeSpan elapsed)

{

// ќчистим текущий вектор, чтобы спрайт не двигалс€, когда не нажаты те или иные клавиши

PlayerShip.Velocity = new Vector(0, 0);

if (keyHandler.IsKeyPressed(Key.Left))

{

PlayerShip.Velocity = Vector.CreateVectorFromAngle(270, 125);

}

if (keyHandler.IsKeyPressed(Key.Right))

{

PlayerShip.Velocity = Vector.CreateVectorFromAngle(90, 125);

}

if (keyHandler.IsKeyPressed(Key.Space))

{

switch (status)

{

case GameState.Ready:

break;

case GameState.Running:

EntityFired(PlayerShip);

break;

case GameState.Paused:

break;

case GameState.BetweenWaves:

status = GameState.Running;

ctlInfo.GameInfo = "";

StartWave();

break;

case GameState.GameOver:

break;

default:

break;

}

}

PlayerShip.Update(elapsed);

 

BombLoop(elapsed);

MissleLoop(elapsed);

AlienLoop(elapsed);

 

foreach (Alien alien in aliensRemove)

{

aliens.Remove(alien);

gameRoot.Children.Remove(alien.SpriteCanvas);

AlienShot(alien);

}

aliensRemove.Clear();

 

foreach (Missle missle in misslesRemove)

{

missles.Remove(missle);

gameRoot.Children.Remove(missle.SpriteCanvas);

}

misslesRemove.Clear();

 

if (nextShot <= DateTime.Now)

{

nextShot = DateTime.Now.AddMilliseconds(enemyShootMilliseonds).AddMilliseconds(elapsed.Milliseconds * -1);

 

shotsThisPass = shotsAtOnce;

if (shotsThisPass > aliens.Count)

{

shotsThisPass = aliens.Count;

}

 

if (aliens.Count > 0)

{

foreach (Alien alien in aliens)

{

alienShooters.Add(alien);

}

}

 

while (alienShooters.Count > shotsThisPass)

{

alienShooters.RemoveAt(GetRandInt(0, alienShooters.Count - 1));

}

 

foreach (Alien alien in alienShooters)

{

EntityFired(alien);

}

 

alienShooters.Clear();

}

}





ѕоделитьс€ с друзь€ми:


ƒата добавлени€: 2015-11-23; ћы поможем в написании ваших работ!; просмотров: 609 | Ќарушение авторских прав


ѕоиск на сайте:

Ћучшие изречени€:

—тремитесь не к успеху, а к ценност€м, которые он дает © јльберт Ёйнштейн
==> читать все изречени€...

1998 - | 1924 -


© 2015-2024 lektsii.org -  онтакты - ѕоследнее добавление

√ен: 0.384 с.