<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Программы для apple iPhone &#187; Разработка программ для iPhone</title>
	<atom:link href="/category/develop/feed/" rel="self" type="application/rss+xml" />
	<link>http://iphone-gps.ru</link>
	<description>новости и тесты программ для iphone</description>
	<lastBuildDate>Thu, 24 Aug 2017 11:02:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)</title>
		<link>http://iphone-gps.ru/2015/03/23/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-4-poslednyaya/</link>
		<comments>http://iphone-gps.ru/2015/03/23/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-4-poslednyaya/#comments</comments>
		<pubDate>Mon, 23 Mar 2015 14:05:58 +0000</pubDate>
		<dc:creator>Vadim Nefedov</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=40232</guid>
		<description><![CDATA[
Ну вот мы и подошли к последней, заключительной части нашего урока. В предыдущих частях: части 1, части 2, части 3, мы создали физику игры, подключили графическую оболочку и научили нашего героя реагировать на наклон устройства. Осталось совсем немного &#8211; сделать подсчет очков и дописать кое-какие мелочи по коду. В результате у нас получится настоящая игра, [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2015/03/pro0.jpg"  width="400" height="270" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /></p>
<p>Ну вот мы и подошли к последней, заключительной части нашего урока. В предыдущих частях: <a href="/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/">части 1</a>, <a href="/2015/03/03/delaem-igru-dlya-iphone-v-stile-mega-jump-%E2%80%93-chast-2/">части 2</a>, <a href="/2015/03/16/delaem-igru-dlya-iphone-v-stile-mega-jump-%E2%80%93-chast-3/">части 3</a>, мы создали физику игры, подключили графическую оболочку и научили нашего героя реагировать на наклон устройства. Осталось совсем немного &#8211; сделать подсчет очков и дописать кое-какие мелочи по коду. В результате у нас получится настоящая игра, готовая для размещения в App Store&#8230;</p>
<h3>Создание HUD</h3>
<p>Перед тем как начать считать очки, мы должны обеспечить их отображение на экране HUD, чтобы игрок мог видеть набранные баллы и количество звезд.<br />
В левом верхнем углу сцены на нашем HUD будет отображаться общее число собранных звезд, а текущий счет &#8211; в правом верхнем углу. Для этого нам нужно создать два лейбла класса <strong>SKLabelNodes</strong>.</p>
<p>Создайте следующие свойства в файле <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723217">
<td class="code" id="p87232code17">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Labels for score and stars</span>
<span style="color: #a61390;">var</span> lblScore<span style="color: #002200;">:</span> SKLabelNode<span style="color: #002200;">!</span>
<span style="color: #a61390;">var</span> lblStars<span style="color: #002200;">:</span> SKLabelNode<span style="color: #002200;">!</span></pre>
</td>
</tr>
</table>
</div>
<p>Чтобы скомпоновать HUD, добавьте следующий код в метод <strong>init(size:)</strong> класса <strong>GameScene.swift</strong> сразу перед строкой, которая инициализирует <strong>MotionManager</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723218">
<td class="code" id="p87232code18">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Build the HUD</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Stars</span>
<span style="color: #11740a; font-style: italic;">// 1</span>
<span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Star&quot;</span><span style="color: #002200;">&#41;</span>
star.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">25</span>, y<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.height<span style="color: #002200;">-</span><span style="color: #2400d9;">30</span><span style="color: #002200;">&#41;</span>
hudNode.addChild<span style="color: #002200;">&#40;</span>star<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// 2</span>
lblStars <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
lblStars.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">30</span>
lblStars.fontColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
lblStars.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">50</span>, y<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.height<span style="color: #002200;">-</span><span style="color: #2400d9;">40</span><span style="color: #002200;">&#41;</span>
lblStars.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Left
&nbsp;
<span style="color: #11740a; font-style: italic;">// 3</span>
lblStars.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;X %d&quot;</span>, GameState.sharedInstance.stars<span style="color: #002200;">&#41;</span>
hudNode.addChild<span style="color: #002200;">&#40;</span>lblStars<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Score</span>
<span style="color: #11740a; font-style: italic;">// 4</span>
lblScore <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
lblScore.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">30</span>
lblScore.fontColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
lblScore.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width<span style="color: #002200;">-</span><span style="color: #2400d9;">20</span>, y<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.height<span style="color: #002200;">-</span><span style="color: #2400d9;">40</span><span style="color: #002200;">&#41;</span>
lblScore.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Right
&nbsp;
<span style="color: #11740a; font-style: italic;">// 5</span>
lblScore.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;0&quot;</span>
hudNode.addChild<span style="color: #002200;">&#40;</span>lblScore<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p><strong>Рассмотрим детально этот блок кода:</strong></p>
<p>1. Сначала мы добавили графику для звезды в левом верхнем углу сцены, чтобы показать игроку, что стоящее рядом с ней число — это количество собранных звезд.</p>
<p>2. Рядом со звездой, мы размещаем <strong>SKLabelNode</strong>, в котором текст выровнен по левому краю.</p>
<p>3. Мы отобразили на лейбле количество звезд, взятого из класса <strong>GameState</strong>.</p>
<p>4. Мы добавили в правый верхний угол сцены лейбл <strong>SKLabelNode</strong> с текстом, выровненным по правому краю.</p>
<p>5. Мы отобразили на этом лейбле ноль, так как в настоящее время никакого счета ещё нет.</p>
<p>Постройте и запустите. Вы увидите два лейбла в верхней части экрана.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-1.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-1-220x387.png"  width="220" height="387" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<h3>Начисление очков</h3>
<p>Наконец пришло время, чтобы начать начислять игроку очки за его тяжкий труд. В Uber Jump набрать очки можно двумя способами: подниматься вверх по сцене и собирать звезды.</p>
<p>Для того, чтобы настроить получение очков за звезды, откройте <strong>GameObjectNode.swift</strong> и просто добавьте следующий код в нижнюю часть метода <strong>collisionWithPlayer</strong> класса <strong>StarNode</strong> сразу перед оператором <strong>return</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723219">
<td class="code" id="p87232code19">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Award score</span>
GameState.sharedInstance.score<span style="color: #002200;">!</span> <span style="color: #002200;">+=</span> <span style="color: #002200;">&#40;</span>starType <span style="color: #002200;">==</span> .Normal ? <span style="color: #2400d9;">20</span> <span style="color: #002200;">:</span> <span style="color: #2400d9;">100</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>И это всё! Мы добавляем 20 очков к счету за обычную звезду и 100 очков за звезду специального типа.</p>
<p>Чтобы отобразить обновленный счет, давайте вернёмся к методу <strong>didBeginContact</strong> в <strong>GameScene.swift</strong>. Напомним, что в первой части этого урока в этом методе мы устанавливали значение <strong>true</strong> для флага с именем <strong>updateHUD</strong> в случае необходимости изменять отображаемые в HUD значения.</p>
<p>Заключите следующие две строчки кода между фигурных скобок условия <strong>if updateHUD {…}</strong> внутри этого метода (сейчас там должен быть комментарий с текстом «TODO: Update HUD in Part 2»):</p>
<div class="codebox">
<table>
<tr id="p8723220">
<td class="code" id="p87232code20">
<pre class="swift" style="font-family:monospace;">lblStars.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;X %d&quot;</span>, GameState.sharedInstance.stars<span style="color: #002200;">&#41;</span>
lblScore.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;%d&quot;</span>, GameState.sharedInstance.score<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите. Нажмите, чтобы начать игру. По мере того как вы будете собирать звезды, ваш счет станет увеличиваться.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-2.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-2-220x388.png"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<p>Чтобы понимать, когда именно нужно начислять очки за путешествие вверх по экрану, вы должны хранить самую высокую точку по оси Y, которой достиг герой в течение текущей игры. Мы будем использовать эти данные, чтобы увеличивать счет только тогда, когда герой добирается до новой наивысшей точки, а не присуждать очки постоянно, пока игрок прыгает вверх и вниз по экрану.</p>
<p>Добавьте следующее свойство класса в файл <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723221">
<td class="code" id="p87232code21">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Max y reached by player</span>
<span style="color: #a61390;">var</span> maxPlayerY<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span></pre>
</td>
</tr>
</table>
</div>
<p>Узел героя начинает движение, когда его координата по оси Y равна 80, поэтому вы должны присвоить свойству <strong>maxPlayerY</strong> значение 80, если ,конечно, не хотите дать игроку 80 очков только за то, что начал игру. ;]</p>
<p>Добавьте следующую строчку в метод <strong>init(size:)</strong> класса <strong>GameScene.swift</strong> сразу после строки, которая устанавливает цвет фона:</p>
<div class="codebox">
<table>
<tr id="p8723222">
<td class="code" id="p87232code22">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Reset</span>
maxPlayerY <span style="color: #002200;">=</span> <span style="color: #2400d9;">80</span></pre>
</td>
</tr>
</table>
</div>
<p>Чтобы начислять игроку очки за перемещение вверх экрана, откройте начало метода <strong>update</strong>: и добавьте следующие строки:</p>
<div class="codebox">
<table>
<tr id="p8723223">
<td class="code" id="p87232code23">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// New max height ?</span>
<span style="color: #11740a; font-style: italic;">// 1</span>
<span style="color: #a61390;">if</span> <span style="color: #a61390;">Int</span><span style="color: #002200;">&#40;</span>player.position.y<span style="color: #002200;">&#41;</span> &gt; maxPlayerY<span style="color: #002200;">!</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 2</span>
  GameState.sharedInstance.score<span style="color: #002200;">!</span> <span style="color: #002200;">+=</span> <span style="color: #a61390;">Int</span><span style="color: #002200;">&#40;</span>player.position.y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span> maxPlayerY<span style="color: #002200;">!</span>
  <span style="color: #11740a; font-style: italic;">// 3</span>
  maxPlayerY <span style="color: #002200;">=</span> <span style="color: #a61390;">Int</span><span style="color: #002200;">&#40;</span>player.position.y<span style="color: #002200;">&#41;</span>
  <span style="color: #11740a; font-style: italic;">// 4</span>
  lblScore.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;%d&quot;</span>, GameState.sharedInstance.score<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p><strong>Этот код лучше рассмотреть детально:</strong></p>
<p>1. Во-первых, нужно проверить, поднялся ли узел героя выше максимальной отметки, которой достигал в пределах данного цикла игры.</p>
<p>2. Если да, то мы добавляем к счету разницу между текущей высотой и максимальной.</p>
<p>3. Теперь мы устанавливаем новое максимальное значение y.</p>
<p>4. Наконец, мы обновляем лейбл, отображающий счет, в соответствии с новым значением.</p>
<p>Постройте и запустите. Нажмите, чтобы начать. Начните играть и вы увидите, как ваш счет будет увеличиваться по мере продвижения вверх.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-3.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-3-220x390.png"  width="220" height="390" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<p>Теперь обратим внимание на подсчет звезд. Мы должны увеличивать его каждый раз, когда узел игрока пересекается со звездой, поэтому откройте <strong>GameObjectNode.swift</strong> и добавьте следующий код в метод <strong>collisionWithPlayer</strong> класса <strong>StarNode</strong> сразу после строки, которая начисляет очки:</p>
<div class="codebox">
<table>
<tr id="p8723224">
<td class="code" id="p87232code24">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Award stars</span>
GameState.sharedInstance.stars<span style="color: #002200;">!</span> <span style="color: #002200;">+=</span> <span style="color: #002200;">&#40;</span>starType <span style="color: #002200;">==</span> .Normal ? <span style="color: #2400d9;">1</span> <span style="color: #002200;">:</span> <span style="color: #2400d9;">5</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Это все, что нужно было сделать! Постройте и запустите. Нажмите, чтобы начать. Следите за увеличением количества звезд по мере того, как будете собирать их.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-4.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-4-220x388.png"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<p>Во время вашей игры вы могли заметить, что когда вы падаете, все пересекаемые героем игровые объекты всё ещё остаются в игре. &#8220;Эй!&#8221; Вы наверняка думаете: &#8220;Я достаточное много играл в Mega Jump, чтобы с уверенностью утверждать, что там такого не было!&#8221; Да верно, но это легко исправить.</p>
<p>Напомним, что мы добавляли метод под названием <strong>checkNodeRemoval</strong> в класс <strong>GameObjectNode</strong>, который проверяет, нужно ли удалять узел. Пришло время, чтобы вызвать этот метод в каждом кадре.</p>
<p>Добавьте следующий код в метод <strong>update</strong> класса <strong>GameScene.swift</strong>, сразу перед строкой, которая проверяет, превышает ли ордината позиции узла героя значение 200:</p>
<div class="codebox">
<table>
<tr id="p8723225">
<td class="code" id="p87232code25">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Remove game objects that have passed by</span>
foregroundNode.enumerateChildNodesWithName<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;NODE_PLATFORM&quot;</span>, usingBlock<span style="color: #002200;">:</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#40;</span>node, stop<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">in</span>
  <span style="color: #a61390;">let</span> platform <span style="color: #002200;">=</span> node <span style="color: #a61390;">as</span> PlatformNode
  platform.checkNodeRemoval<span style="color: #002200;">&#40;</span><span style="color: #a61390;">self</span>.player.position.y<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span>
&nbsp;
foregroundNode.enumerateChildNodesWithName<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;NODE_STAR&quot;</span>, usingBlock<span style="color: #002200;">:</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#40;</span>node, stop<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">in</span>
  <span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> node <span style="color: #a61390;">as</span> StarNode
  star.checkNodeRemoval<span style="color: #002200;">&#40;</span><span style="color: #a61390;">self</span>.player.position.y<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь мы перечисляем все платформы в узле переднего плана и вызываем метод <strong>checkNodeRemoval</strong> для каждой из них. Потом тоже самое делаем для звёзд.</p>
<p>Постройте и запустите. Нажмите, чтобы начать. Теперь, когда вы будете падать, то не почувствуете под ногами ничего, кроме чистого неба.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-5.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-5-220x390.jpg"  width="220" height="390" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<h3>Game Over!</h3>
<p>Игра заканчивается тогда, когда герой падает в нижнюю часть сцены или поднимается на вершину уровня. В этот момент нам нужно отобразить финальный счет и наивысший балл. Мы осуществим это посредством перехода к сцене конца игры.</p>
<p>Создайте новый <strong>Cocoa Touch Class</strong> с именем <strong>EndGameScene</strong> и сделайте его подклассом <strong>SKScene</strong>.</p>
<p><a href="/wp-content/uploads/2015/03/gm4-6.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-6-400x236.png"  width="400" height="236" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /> </a></p>
<p><strong>EndGameScene</strong> будет представлять из себя обычный экран, отображающий счет игрока, количество собранных звезд и наивысший балл. Мы добавим все узлы в метод <strong>init(size:)</strong>:, поэтому откройте <strong>EndGameScene.swift</strong> и замените всё содержимое файла на следующее:</p>
<div class="codebox">
<table>
<tr id="p8723226">
<td class="code" id="p87232code26">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">import</span> SpriteKit
&nbsp;
<span style="color: #a61390;">class</span> EndGameScene<span style="color: #002200;">:</span> <span style="color: #400080;">SKScene</span> <span style="color: #002200;">&#123;</span>
&nbsp;
  required <span style="color: #a61390;">init</span>?<span style="color: #002200;">&#40;</span>coder aDecoder<span style="color: #002200;">:</span> <span style="color: #400080;">NSCoder</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">super</span>.<span style="color: #a61390;">init</span><span style="color: #002200;">&#40;</span>coder<span style="color: #002200;">:</span> aDecoder<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #a61390;">override</span> <span style="color: #a61390;">init</span><span style="color: #002200;">&#40;</span>size<span style="color: #002200;">:</span> <span style="color: #400080;">CGSize</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">super</span>.<span style="color: #a61390;">init</span><span style="color: #002200;">&#40;</span>size<span style="color: #002200;">:</span> size<span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Stars</span>
    <span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Star&quot;</span><span style="color: #002200;">&#41;</span>
    star.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">25</span>, y<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.height<span style="color: #002200;">-</span><span style="color: #2400d9;">30</span><span style="color: #002200;">&#41;</span>
    addChild<span style="color: #002200;">&#40;</span>star<span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #a61390;">let</span> lblStars <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
    lblStars.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">30</span>
    lblStars.fontColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    lblStars.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">50</span>, y<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.height<span style="color: #002200;">-</span><span style="color: #2400d9;">40</span><span style="color: #002200;">&#41;</span>
    lblStars.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Left
    lblStars.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;X %d&quot;</span>, GameState.sharedInstance.stars<span style="color: #002200;">&#41;</span>
    addChild<span style="color: #002200;">&#40;</span>lblStars<span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Score</span>
    <span style="color: #a61390;">let</span> lblScore <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
    lblScore.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">60</span>
    lblScore.fontColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    lblScore.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">300</span><span style="color: #002200;">&#41;</span>
    lblScore.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Center
    lblScore.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;%d&quot;</span>, GameState.sharedInstance.score<span style="color: #002200;">&#41;</span>
    addChild<span style="color: #002200;">&#40;</span>lblScore<span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// High Score</span>
    <span style="color: #a61390;">let</span> lblHighScore <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
    lblHighScore.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">30</span>
    lblHighScore.fontColor <span style="color: #002200;">=</span> SKColor.cyanColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    lblHighScore.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">150</span><span style="color: #002200;">&#41;</span>
    lblHighScore.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Center
    lblHighScore.text <span style="color: #002200;">=</span> <span style="color: #a61390;">String</span><span style="color: #002200;">&#40;</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;High Score: %d&quot;</span>, GameState.sharedInstance.highScore<span style="color: #002200;">&#41;</span>
    addChild<span style="color: #002200;">&#40;</span>lblHighScore<span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Try again</span>
    <span style="color: #a61390;">let</span> lblTryAgain <span style="color: #002200;">=</span> SKLabelNode<span style="color: #002200;">&#40;</span>fontNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;ChalkboardSE-Bold&quot;</span><span style="color: #002200;">&#41;</span>
    lblTryAgain.fontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">30</span>
    lblTryAgain.fontColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    lblTryAgain.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">50</span><span style="color: #002200;">&#41;</span>
    lblTryAgain.horizontalAlignmentMode <span style="color: #002200;">=</span> SKLabelHorizontalAlignmentMode.Center
    lblTryAgain.text <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;Tap To Try Again&quot;</span>
    addChild<span style="color: #002200;">&#40;</span>lblTryAgain<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь много кода, но после всего того, что вы сделали в этом уроке, вас уже ничего не должно пугать.</p>
<p>По сути мы создаем три лейбла, которые будут служить для отображения количества собранных звезд, финального счета и наивысшего балла. Мы присваиваем им значения, взятые из синглтона <strong>GameState</strong>. Мы также добавляем лейбл, который подсказывает пользователю, что ему нужно коснуться экрана для начала новой игры.</p>
<p>Чтобы отслеживать, закончилась игра или нет, добавьте следующую булевую переменную в свойства класса <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723227">
<td class="code" id="p87232code27">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Game over dude!</span>
<span style="color: #a61390;">var</span> gameOver <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span></pre>
</td>
</tr>
</table>
</div>
<p>В конце игры нужно сохранить текущее состояние в синглтон <strong>GameState</strong> и осуществить переход к новой сцене. Добавьте следующий метод в <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723228">
<td class="code" id="p87232code28">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> endGame<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  gameOver <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #11740a; font-style: italic;">// Save stars and high score</span>
  GameState.sharedInstance.saveState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 3</span>
  <span style="color: #a61390;">let</span> reveal <span style="color: #002200;">=</span> SKTransition.fadeWithDuration<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">let</span> endGameScene <span style="color: #002200;">=</span> EndGameScene<span style="color: #002200;">&#40;</span>size<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size<span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">self</span>.view<span style="color: #002200;">!</span>.presentScene<span style="color: #002200;">&#40;</span>endGameScene, transition<span style="color: #002200;">:</span> reveal<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p><strong>Давайте рассмотрим его детально:</strong></p>
<p>1. Сначала мы устанавливаем переменной <strong>gameOver</strong> значение <strong>true</strong>.</p>
<p>2. Затем сообщаем синглтону <strong>GameState</strong>, чтоб он записал состояние игры в файл пользовательских настроек.</p>
<p>3. И, наконец, мы создаём экземпляр класса <strong>EndGameScene</strong> и делаем переход к нему путём затухания экрана в течение 0,5 секунд.</p>
<p>Метод <strong>endGame</strong> нужно вызывать, когда узел героя либо падает на дно экрана, либо достигает максимальной высоты уровня. Мы проверяем оба эти случая в методе <strong>update</strong> главной сцены.</p>
<p>Добавьте следующий код в тот же класс <strong>GameScene.swift</strong>, в конец метода <strong>update:</strong></p>
<div class="codebox">
<table>
<tr id="p8723229">
<td class="code" id="p87232code29">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// 1</span>
<span style="color: #11740a; font-style: italic;">// Check if we've finished the level</span>
<span style="color: #a61390;">if</span> <span style="color: #a61390;">Int</span><span style="color: #002200;">&#40;</span>player.position.y<span style="color: #002200;">&#41;</span> &gt; endLevelY <span style="color: #002200;">&#123;</span>
  endGame<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// 2</span>
<span style="color: #11740a; font-style: italic;">// Check if we've fallen too far</span>
<span style="color: #a61390;">if</span> <span style="color: #a61390;">Int</span><span style="color: #002200;">&#40;</span>player.position.y<span style="color: #002200;">&#41;</span> &lt; maxPlayerY <span style="color: #002200;">-</span> <span style="color: #2400d9;">800</span> <span style="color: #002200;">&#123;</span>
  endGame<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Взгляните на эти проверки:</p>
<p>Помните, мы загружали <strong>endLevelY</strong> из листа свойств? Это то значение координаты Y, при которой игрок должен заканчивать уровень.</p>
<p>Если узел героя падает более чем на 800 ниже максимальной отметки, которой он достиг, то игра заканчивается.</p>
<p>Прежде чем запустить игру для того, чтобы увидеть сцену конца игры, мы должны убедиться, что метод <strong>endGame</strong> не вызывается более одного раза. А это произойдёт, как только метод <strong>update()</strong> сработает в следующем кадре.</p>
<p>Добавьте следующую строку в начало метода Update () в GameScene.swift:</p>
<div class="codebox">
<table>
<tr id="p8723230">
<td class="code" id="p87232code30">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">if</span> gameOver <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Теперь при вызове метода <strong>update()</strong>, прежде чем сделать переход, он проверяет, закончилась ли игра.</p>
<p>Постройте и запустите. Нажмите, чтобы начать, поиграйте немного, а затем дайте «ультра прыгуну» упасть. Произойдёт переход на сцену конца игры.</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/03/gm4-7-220x390.png"  width="220" height="390" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 4 (последняя)" /></p>
<h3>Перезапуск</h3>
<p>Чтобы иметь возможность перезапустить игру, находясь на конечной сцене, мы должны модифицировать класс <strong>EndGameScene</strong> так, чтобы он по событию касания осуществлял переход обратно на основную сцену.</p>
<p>Откройте <strong>EndGameScene.swift</strong> и добавьте следующий метод в этот класс для обработки касаний:</p>
<div class="codebox">
<table>
<tr id="p8723231">
<td class="code" id="p87232code31">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> touchesBegan<span style="color: #002200;">&#40;</span>touches<span style="color: #002200;">:</span> <span style="color: #400080;">NSSet</span>, withEvent event<span style="color: #002200;">:</span> <span style="color: #400080;">UIEvent</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Transition back to the Game</span>
  <span style="color: #a61390;">let</span> reveal <span style="color: #002200;">=</span> SKTransition.fadeWithDuration<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">let</span> gameScene <span style="color: #002200;">=</span> GameScene<span style="color: #002200;">&#40;</span>size<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size<span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">self</span>.view<span style="color: #002200;">!</span>.presentScene<span style="color: #002200;">&#40;</span>gameScene, transition<span style="color: #002200;">:</span> reveal<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Этот код просто создаёт переход на новую сцену <strong>GameScene</strong> подобно тому, как он осуществлялся при первом запуске приложения.</p>
<p>Остался последний штрих и всё будет готово! Откройте <strong>GameScene.swift</strong>. В методе <strong>init(size:)</strong>, там где мы сбрасывали значение <strong>maxPlayerY</strong>, добавьте следующий код:</p>
<div class="codebox">
<table>
<tr id="p8723232">
<td class="code" id="p87232code32">
<pre class="swift" style="font-family:monospace;">GameState.sharedInstance.score <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
gameOver <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы обнуляем счёт в синглетоне <strong>GameState</strong>, а также сбрасываем флаг <strong>GameOver</strong>, чтобы игра могла начаться заново.</p>
<p>Постройте и запустите. Нажмите, чтобы начать и играйте. А теперь постарайтесь побить самый высокий балл! ;]</p>
<h3>Что можно сделать еще?</h3>
<p>Поздравляю, вы создали игру в стиле Mega Jump!</p>
<p>Под статьей вы найдете ссылку на готовый проект с полным кодом уроков.</p>
<p>В четырех частях мы охватили весь процесс создания игры на физическом движке. Вы многое узнали о том, как настроить обнаружения столкновений и как построить свою игровую логику для обработки столкновений.</p>
<p>Но вы можете сделать гораздо больше! Откройте файл конфигурации <strong>plist</strong> и подумайте о новых уровнях и возможностях, которые сможете реализовать. Просто скопируйте исходный <strong>plist</strong> и создавайте любое количество уровней, меняя конфигурацию внутри файла.</p>
<p>Сыграйте в Mega Jump и вдохновитесь! Сможете ли вы воплотить идеи, которые будут лучше, чем в оригинальной игре?</p>
<p>И последнее, но не менее важное: если вы хотите узнать больше о Sprite Kit, прочитайте книгу iOS Games by Tutorials, в которой вы узнаете, как сделать пять полных игр: от «зомби экшинов» до автомобильных гонок и перестрелок в космосе!</p>
<p>И, конечно, если у вас есть какие-либо вопросы или комментарии, то пожалуйста, присоединяйтесь к обсуждению.</p>
<p><strong>Скачать <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly95YWRpLnNrL2QvQVMzVWVJeEdmVFRKdA==/">готовый проект и код игры</a></strong>. </p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2015/03/23/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-4-poslednyaya/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Делаем игру для iPhone в стиле Mega Jump – Часть 3</title>
		<link>http://iphone-gps.ru/2015/03/16/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-3/</link>
		<comments>http://iphone-gps.ru/2015/03/16/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-3/#comments</comments>
		<pubDate>Mon, 16 Mar 2015 12:02:35 +0000</pubDate>
		<dc:creator>Vadim Nefedov</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=40230</guid>
		<description><![CDATA[
Добро пожаловать на третью часть урока, в котором мы создаем игру в стиле Mega Jump на Sprite Kit и Swift. В предыдущих части 1 и части 2 мы создали игру на движке Sprite Kit под названием Uber Jump.  Мы добавили графику, спрайт героя и некоторые элементы геймплея.
В третьей части мы будем использовать этот фундамент [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2015/03/gm0.jpg"  width="400" height="294" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /></p>
<p>Добро пожаловать на третью часть урока, в котором мы создаем игру в стиле Mega Jump на Sprite Kit и Swift. В предыдущих <a href="/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/">части 1</a> и <a href="/2015/03/03/delaem-igru-dlya-iphone-v-stile-mega-jump-%E2%80%93-chast-2/">части 2</a> мы создали игру на движке Sprite Kit под названием Uber Jump.  Мы добавили графику, спрайт героя и некоторые элементы геймплея.<br />
В третьей части мы будем использовать этот фундамент для построения полного уровня игры, включая систему подсчета очков. Мы также добавим поддержку акселерометра, чтобы наш «ультра прыгун» мог двигаться из стороны в сторону и вверх и вниз. Когда мы все закончим, вы будете иметь абсолютно полноценную игру, которую сможете потом расширять в разных направлениях. Как и первые части урока, этот материал потребует от вас знания <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS84NDQzNC9zcHJpdGUta2l0LXN3aWZ0LXR1dG9yaWFsLWJlZ2lubmVycw==/">основ Sprite Kit</a>. Итак, добро пожаловать на новый уровень!</p>
<h3>Продолжение</h3>
<p>Оригинал статьи на английском языке доступен <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS84NzIzMi9tYWtlLWdhbWUtbGlrZS1tZWdhLWp1bXAtc3ByaXRlLWtpdC1zd2lmdC1wYXJ0LTI=/">здесь</a>.</p>
<p>Скачайте <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly95YWRpLnNrL2QvQzE3S25JT3RlenZzNg==/">полную копию проекта</a> из первой части, если вы не делали его сами.<br />
Наш уровень будет содержать много звезд и платформ. Чтобы не структурировать данные вручную, <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly95YWRpLnNrL2QvRHVVbUQtYy1mSFBNZg==/">скачайте этот файл конфигурации</a> уровня, затем перетащите <strong>Level01.plist</strong> в ваш проект <strong>Xcode</strong>. Убедитесь, что поставлена галочка для опции “<strong>Destination: Copy items if needed</strong>”  и выбран таргет  <strong>UberJump</strong>.</p>
<p>Откройте <strong>Level01.plist</strong> и изучите его содержимое. По сути он состоит из трех элементов:</p>
<p>- <strong>EndY</strong> определяет высоту, которую герой должен достичь, чтобы закончить уровень.<br />
- <strong>Stars</strong> определяет положение всех звезд на уровне.<br />
- <strong>Platforms</strong> определяет положение всех платформ в уровне.</p>
<p>Элементы  Stars и Platforms  содержат в себе по два вложенных элемента:</p>
<p>- <strong>Patterns</strong> содержит ряд шаблонов для звезд и платформ.<br />
- <strong>Positions</strong> определяет месторасположение шаблонов звезд и платформ по всей площади уровня.</p>
<p><a href="/wp-content/uploads/2015/03/gm1.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm1-400x135.png"  width="400" height="135" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Для лучшего понимания структуры файла, откройте элемент <strong>Stars/Positions/Item 0</strong>.  Он содержит три вложенных элемента, в которых находится информация такого содержания: звезды нужно расположить крест-накрест в точке с координатами 160 и 240.</p>
<p><a href="/wp-content/uploads/2015/03/gm2.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm2-400x126.png"  width="400" height="126" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Теперь взгляните на <strong>Patterns/Cross</strong>, и вы увидите шаблон, содержащий пять элементов, в том числе координаты X и Y относительно позиции, заданной в <strong>Stars/Positions</strong>, а также тип звезды. Нормальный тип обозначен нулём, а специальный &#8211; единицей. </p>
<p><a href="/wp-content/uploads/2015/03/gm3.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm3-400x274.png"  width="400" height="274" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Это достаточно удобный способ многоразового использования шаблонов звезд и платформ без необходимости задавать позицию в коде для каждого отдельного объекта.</p>
<p><a href="/wp-content/uploads/2015/03/gm4.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm4-400x148.png"  width="400" height="148" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<h3>Загрузка уровня с данными</h3>
<p>Чтобы добавить возможность загрузки параметров уровня из файла <strong>Level01.plist</strong>, откройте <strong>GameScene.swift</strong> и добавьте к классу следующее свойство:</p>
<div class="codebox">
<table>
<tr id="p872321">
<td class="code" id="p87232code1">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Height at which level ends</span>
<span style="color: #a61390;">let</span> endLevelY <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span></pre>
</td>
</tr>
</table>
</div>
<p><strong>ЕndLevelY</strong> будет хранить высоту или ординату, которой игрок должен будет достичь, чтобы закончить уровень.<br />
Вставьте следующий код в метод <strong>init(size:)</strong>, сразу перед строчками, которые создают и добавляют платформу:</p>
<div class="codebox">
<table>
<tr id="p872322">
<td class="code" id="p87232code2">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Load the level</span>
<span style="color: #a61390;">let</span> levelPlist <span style="color: #002200;">=</span> <span style="color: #400080;">NSBundle</span>.mainBundle<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>.pathForResource<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;Level01&quot;</span>, ofType<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;plist&quot;</span><span style="color: #002200;">&#41;</span>
<span style="color: #a61390;">let</span> levelData <span style="color: #002200;">=</span> <span style="color: #400080;">NSDictionary</span><span style="color: #002200;">&#40;</span>contentsOfFile<span style="color: #002200;">:</span> levelPlist<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">!</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Height at which the player ends the level</span>
endLevelY <span style="color: #002200;">=</span> levelData<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;EndY&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">!</span>.integerValue<span style="color: #002200;">!</span></pre>
</td>
</tr>
</table>
</div>
<p>Этот код загружает данные из списка свойств в словарь с названием <strong>levelData</strong>, а потом берет оттуда значение свойства <strong>EndY</strong> и сохраняет его в переменную <strong>endLevelY</strong>.<br />
Теперь займемся звездами и платформами. Начнём с платформ: в методе <strong>init(size:)</strong>, замените следующие строки:</p>
<div class="codebox">
<table>
<tr id="p872323">
<td class="code" id="p87232code3">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add a platform</span>
<span style="color: #a61390;">let</span> platform <span style="color: #002200;">=</span> createPlatformAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">160</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">320</span><span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> .Normal<span style="color: #002200;">&#41;</span>
foregroundNode.addChild<span style="color: #002200;">&#40;</span>platform<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>этим кодом:</p>
<div class="codebox">
<table>
<tr id="p872324">
<td class="code" id="p87232code4">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add the platforms</span>
<span style="color: #a61390;">let</span> platforms <span style="color: #002200;">=</span> levelData<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Platforms&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSDictionary</span>
<span style="color: #a61390;">let</span> platformPatterns <span style="color: #002200;">=</span> platforms<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Patterns&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSDictionary</span>
<span style="color: #a61390;">let</span> platformPositions <span style="color: #002200;">=</span> platforms<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Positions&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span><span style="color: #002200;">&#93;</span>
&nbsp;
<span style="color: #a61390;">for</span> platformPosition <span style="color: #a61390;">in</span> platformPositions <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">let</span> patternX <span style="color: #002200;">=</span> platformPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;x&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
  <span style="color: #a61390;">let</span> patternY <span style="color: #002200;">=</span> platformPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;y&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
  <span style="color: #a61390;">let</span> pattern <span style="color: #002200;">=</span> platformPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;pattern&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSString</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Look up the pattern</span>
  <span style="color: #a61390;">let</span> platformPattern <span style="color: #002200;">=</span> platformPatterns<span style="color: #002200;">&#91;</span>pattern<span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span><span style="color: #002200;">&#93;</span>
  <span style="color: #a61390;">for</span> platformPoint <span style="color: #a61390;">in</span> platformPattern <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">let</span> x <span style="color: #002200;">=</span> platformPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;x&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
    <span style="color: #a61390;">let</span> y <span style="color: #002200;">=</span> platformPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;y&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
    <span style="color: #a61390;">let</span> type <span style="color: #002200;">=</span> PlatformType<span style="color: #002200;">&#40;</span>rawValue<span style="color: #002200;">:</span> platformPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;type&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">!</span>.integerValue<span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> positionX <span style="color: #002200;">=</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">!</span> <span style="color: #002200;">+</span> patternX<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> positionY <span style="color: #002200;">=</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>y<span style="color: #002200;">!</span> <span style="color: #002200;">+</span> patternY<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> platformNode <span style="color: #002200;">=</span> createPlatformAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> positionX, y<span style="color: #002200;">:</span> positionY<span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> type<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    foregroundNode.addChild<span style="color: #002200;">&#40;</span>platformNode<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь очень много всего происходит, но эти вещи достаточно просты. Мы загрузили словарь платформ (Platforms) из <strong>levelData</strong>, а затем запустили цикл позиций платформ из этого словаря. Для каждого элемента мы получили соответствующий шаблон и инициировали экземпляр <strong>PlatformNode</strong> нужного типа с заданными позициями X и Y. И, наконец, мы добавили все узлы платформ в узел переднего плана, который должен содержать все игровые объекты.<br />
Постройте и запустите. Вы увидите ряд из трех платформ, выровненных по горизонтали, которые имеют тип &#8220;<strong>Triple</strong>&#8221; , заданный в файле в <strong>Level01.plist</strong>.</p>
<p><a href="/wp-content/uploads/2015/03/gm5.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm5-220x386.png"  width="220" height="386" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Теперь сделайте то же самое для звезд. Внутри <strong>GameScene.swift</strong>, замените следующую строку в <strong>init(size:)</strong>:</p>
<div class="codebox">
<table>
<tr id="p872325">
<td class="code" id="p87232code5">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add a star</span>
<span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> createStarAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">160</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">220</span><span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> .Special<span style="color: #002200;">&#41;</span>
foregroundNode.addChild<span style="color: #002200;">&#40;</span>star<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>кодом:</p>
<div class="codebox">
<table>
<tr id="p872326">
<td class="code" id="p87232code6">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add the stars</span>
<span style="color: #a61390;">let</span> stars <span style="color: #002200;">=</span> levelData<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Stars&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSDictionary</span>
<span style="color: #a61390;">let</span> starPatterns <span style="color: #002200;">=</span> stars<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Patterns&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSDictionary</span>
<span style="color: #a61390;">let</span> starPositions <span style="color: #002200;">=</span> stars<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;Positions&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span><span style="color: #002200;">&#93;</span>
&nbsp;
<span style="color: #a61390;">for</span> starPosition <span style="color: #a61390;">in</span> starPositions <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">let</span> patternX <span style="color: #002200;">=</span> starPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;x&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
  <span style="color: #a61390;">let</span> patternY <span style="color: #002200;">=</span> starPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;y&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
  <span style="color: #a61390;">let</span> pattern <span style="color: #002200;">=</span> starPosition<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;pattern&quot;</span><span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #400080;">NSString</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Look up the pattern</span>
  <span style="color: #a61390;">let</span> starPattern <span style="color: #002200;">=</span> starPatterns<span style="color: #002200;">&#91;</span>pattern<span style="color: #002200;">&#93;</span> <span style="color: #a61390;">as</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span><span style="color: #002200;">&#93;</span>
  <span style="color: #a61390;">for</span> starPoint <span style="color: #a61390;">in</span> starPattern <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">let</span> x <span style="color: #002200;">=</span> starPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;x&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
    <span style="color: #a61390;">let</span> y <span style="color: #002200;">=</span> starPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;y&quot;</span><span style="color: #002200;">&#93;</span>?.floatValue
    <span style="color: #a61390;">let</span> type <span style="color: #002200;">=</span> StarType<span style="color: #002200;">&#40;</span>rawValue<span style="color: #002200;">:</span> starPoint<span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">&quot;type&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">!</span>.integerValue<span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> positionX <span style="color: #002200;">=</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">!</span> <span style="color: #002200;">+</span> patternX<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> positionY <span style="color: #002200;">=</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>y<span style="color: #002200;">!</span> <span style="color: #002200;">+</span> patternY<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    <span style="color: #a61390;">let</span> starNode <span style="color: #002200;">=</span> createStarAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> positionX, y<span style="color: #002200;">:</span> positionY<span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> type<span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span>
    foregroundNode.addChild<span style="color: #002200;">&#40;</span>starNode<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь всё в точности тоже самое, что мы сделали при создании платформ, но в этом случае мы используем словарь <strong>Stars</strong> вместо словаря <strong>Platforms</strong>.<br />
Постройте и запустите. Это уже становится похожим на настоящую игру!</p>
<p><a href="/wp-content/uploads/2015/03/gm6.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm6-220x390.png"  width="220" height="390" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<h3>Слой среднего плана </h3>
<p>В графическом плане можно сделать еще одну вещь, которая добавит игре иллюзию объема &#8211; это слой среднего плана. Он будет представлять собой узел, содержащий графику декораций.<br />
Добавьте следующий метод в <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p872327">
<td class="code" id="p87232code7">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createMidgroundNode<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; <span style="color: #400080;">SKNode</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Create the node</span>
  <span style="color: #a61390;">let</span> theMidgroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">var</span> anchor<span style="color: #002200;">:</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">!</span>
  <span style="color: #a61390;">var</span> xPosition<span style="color: #002200;">:</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">!</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #11740a; font-style: italic;">// Add some branches to the midground</span>
  <span style="color: #a61390;">for</span> index <span style="color: #a61390;">in</span> <span style="color: #2400d9;">0</span>...9 <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">var</span> spriteName<span style="color: #002200;">:</span> <span style="color: #a61390;">String</span>
    <span style="color: #11740a; font-style: italic;">// 2</span>
    <span style="color: #a61390;">let</span> r <span style="color: #002200;">=</span> arc4random<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">%</span> <span style="color: #2400d9;">2</span>
    <span style="color: #a61390;">if</span> r &gt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#123;</span>
      spriteName <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;BranchRight&quot;</span>
      anchor <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">1.0</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#41;</span>
      xPosition <span style="color: #002200;">=</span> <span style="color: #a61390;">self</span>.size.width
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
      spriteName <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;BranchLeft&quot;</span>
      anchor <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#41;</span>
      xPosition <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span>
    <span style="color: #002200;">&#125;</span>
    <span style="color: #11740a; font-style: italic;">// 3</span>
    <span style="color: #a61390;">let</span> branchNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> spriteName<span style="color: #002200;">&#41;</span>
    branchNode.anchorPoint <span style="color: #002200;">=</span> anchor
    branchNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> xPosition, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">500.0</span> <span style="color: #002200;">*</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>index<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    theMidgroundNode.addChild<span style="color: #002200;">&#40;</span>branchNode<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Return the completed midground node</span>
  <span style="color: #a61390;">return</span> theMidgroundNode
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Рассмотрим этот код подробнее:</p>
<p>1. Мы добавляем в <strong>midgroundNode</strong> десять веток, расположенных равномерно по всему уровню.<br />
2. Есть два различных изображения: на одном ветки растут из левой части экрана, на другом &#8211; из правой. Мы берем одно случайное из них.<br />
3. Мы располагаем ветки с интервалом в 500 точек по оси у в узле среднего плана.</p>
<p>Теперь добавим узел среднего плана на сцену, вставив следующий код в <strong>init(size:)</strong>, сразу после строки, которая добавляет фоновый узел:</p>
<div class="codebox">
<table>
<tr id="p872328">
<td class="code" id="p87232code8">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Midground</span>
midgroundNode <span style="color: #002200;">=</span> createMidgroundNode<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
addChild<span style="color: #002200;">&#40;</span>midgroundNode<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите.<br />
Смотрите! Появились ветви разного вида, а некоторые даже с розовыми бабочками!</p>
<p><a href="/wp-content/uploads/2015/03/gm7.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm7-220x388.png"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p><strong>Примечание: розовые бабочки появляются, если случайно выбранная ветвь является той, которая нарисована для правой стороны экрана. Изображение для левой ветви не содержит бабочек.</strong></p>
<p>Нажмите, чтобы начать игру, и вы увидите спрайт героя, взлетающего вверх экрана. Однако, когда «ультра прыгун» поднимается, игровой мир пока остается на месте.</p>
<p><a href="/wp-content/uploads/2015/03/gm8.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm8-220x389.png"  width="220" height="389" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Слои переднего, среднего и заднего плана должны двигаться вместе с узлом героя, чтобы удерживать его спрайт в центре экрана. С этим мы и собираемся разобраться в следующей главе.</p>
<h3>Параллакс</h3>
<p>Чтобы добавить в свою игру эффект параллакса, мы будем перемещать узлы переднего, среднего и заднего плана с различными скоростями по мере того, как герой будет путешествовать вверх и вниз по сцене. Sprite Kit в каждом кадре вызывает метод update() (обновление) для нашей сцены, поэтому это самое место, чтобы реализовать логику по обеспечению плавной анимации.</p>
<p>Откройте <strong>GameScene.swift</strong> и добавьте следующий метод:</p>
<div class="codebox">
<table>
<tr id="p872329">
<td class="code" id="p87232code9">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> update<span style="color: #002200;">&#40;</span>currentTime<span style="color: #002200;">:</span> <span style="color: #400080;">NSTimeInterval</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Calculate player y offset</span>
  <span style="color: #a61390;">if</span> player.position.y &gt; <span style="color: #2400d9;">200.0</span> <span style="color: #002200;">&#123;</span>
    backgroundNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, y<span style="color: #002200;">:</span> <span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>player.position.y <span style="color: #002200;">-</span> <span style="color: #2400d9;">200.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">/</span><span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    midgroundNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, y<span style="color: #002200;">:</span> <span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>player.position.y <span style="color: #002200;">-</span> <span style="color: #2400d9;">200.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">/</span><span style="color: #2400d9;">4</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    foregroundNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, y<span style="color: #002200;">:</span> <span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span>player.position.y <span style="color: #002200;">-</span> <span style="color: #2400d9;">200.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы проверяем, чтоб узел героя поднялся по экрану более чем 200 точек, потому что в противном случае мы не хотим перемещать фон. Если условие выполняется, мы двигаем три узла вниз с различными скоростями, чтобы создать эффект параллакса:</p>
<p>- Перемещаем узел переднего плана с той же скоростью, что и узел героя, фактически не давая герою выходить за пределы экрана.<br />
- Перемещаем узел среднего плана со скоростью, составляющей 25% от скорости узла героя, потому что этот слой должен быть дальше от зрителя.<br />
- Перемещаем фоновый узел со скоростью, составляющей 10% от скорости  узла героя, потому что он должен быть еще дальше.</p>
<p>Постройте и запустите. Нажмите, чтобы начать игру. Вы увидите, что все слои теперь перемещаются с героем, а различные скорости узлов фонового и среднего плана узлов производят очень приятный эффект параллакса.</p>
<p><a href="/wp-content/uploads/2015/03/gm9.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm9-220x386.png"  width="220" height="386" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<p>Отличная работа! Но ещё рано почивать на лаврах. Для того, чтобы допрыгнуть до звёзд, нужно сначала порыть землю.</p>
<h3>Движение с акселерометром</h3>
<p>Пришло время задействовать акселерометр. Движение вдоль вертикальной оси у нас отлажено хорошо, но что насчёт движения по горизонтальной оси? Так же, как в Mega Jump, пользователь будет управлять своим «ультра прыгуном» с помощью акселерометра.</p>
<p><strong>Примечание: чтобы тестировать акселерометр, вам нужно будет запускать игру на реальном устройстве. iPhone Simulator не отрабатывает акселерометр.</strong></p>
<p>Для обработки входных сигналов акселерометра потребуется библиотека <strong>Core Motion</strong>, поэтому в верхней части <strong>GameScene.swift</strong> добавьте следующую строчку:</p>
<div class="codebox">
<table>
<tr id="p8723210">
<td class="code" id="p87232code10">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">import</span> CoreMotion</pre>
</td>
</tr>
</table>
</div>
<p>Затем добавьте следующие свойства к классу <strong>GameScene</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723211">
<td class="code" id="p87232code11">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Motion manager for accelerometer</span>
<span style="color: #a61390;">let</span> motionManager<span style="color: #002200;">:</span> CMMotionManager <span style="color: #002200;">=</span> CMMotionManager<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Acceleration value from accelerometer</span>
<span style="color: #a61390;">var</span> xAcceleration<span style="color: #002200;">:</span> <span style="color: #400080;">CGFloat</span> <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы собираемся использовать <strong>MotionManager</strong> для доступа к данным акселерометра устройства, а также будем хранить последнее расчетное значение ускорения в переменной <strong>xAcceleration</strong>, которая нам понадобится позже при задании скорость узла героя по оси X.<br />
Чтобы создать экземпляр <strong>CMMotionManager</strong>, добавьте следующий код в метод <strong>init(size:)</strong> сразу после строки, которая добавляет <strong>tapToStartNode</strong> в <strong>HUD</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723212">
<td class="code" id="p87232code12">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// CoreMotion</span>
<span style="color: #11740a; font-style: italic;">// 1</span>
motionManager.accelerometerUpdateInterval <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.2</span>
<span style="color: #11740a; font-style: italic;">// 2</span>
motionManager.startAccelerometerUpdatesToQueue<span style="color: #002200;">&#40;</span><span style="color: #400080;">NSOperationQueue</span>.currentQueue<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, withHandler<span style="color: #002200;">:</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#40;</span>accelerometerData<span style="color: #002200;">:</span> CMAccelerometerData<span style="color: #002200;">!</span>, error<span style="color: #002200;">:</span> <span style="color: #400080;">NSError</span><span style="color: #002200;">!</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">in</span>
  <span style="color: #11740a; font-style: italic;">// 3</span>
  <span style="color: #a61390;">let</span> acceleration <span style="color: #002200;">=</span> accelerometerData.acceleration
  <span style="color: #11740a; font-style: italic;">// 4</span>
  <span style="color: #a61390;">self</span>.xAcceleration <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#40;</span>acceleration.x<span style="color: #002200;">&#41;</span> <span style="color: #002200;">*</span> <span style="color: #2400d9;">0.75</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">self</span>.xAcceleration <span style="color: #002200;">*</span> <span style="color: #2400d9;">0.25</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь очень много всего происходит, поэтому давайте окунёмся поглубже:</p>
<p>1. Свойство <strong>accelerometerUpdateInterval</strong> определяет количество секунд между обновлениями значений акселерометра. Значение 0,2 обеспечивает наиболее плавную частоту обновления.<br />
2. Мы запускаем акселерометр и задаём блок кода для выполнения во время каждого обновления значений акселерометра.<br />
3. Внутри блока мы получаем информацию, связанную с ускорением, из последних данных акселерометра, переданных в блок.<br />
4. Здесь мы вычисляем ускорение узла героя по оси X. Можно получить это значение непосредственно из данных акселерометра, но движение будет гораздо плавнее, если использовать значение, сложив три четверти ускорения акселерометра вдоль оси X и одну четверть текущего ускорения по той же оси.</p>
<p>Теперь, когда у нас есть значение ускорения по оси абсцисс, мы можем использовать его для задания горизонтальной скорости узла героя.<br />
Так как вы непосредственно будете управлять скоростью узла героя, важно, чтобы <strong>Sprite Kit</strong> в первую очередь обрабатывал физику. </p>
<p>У <strong>Sprite Kit</strong> есть метод, называемый <strong>didSimulatePhysics</strong>, который подойдёт для этой цели. <strong>Sprite Kit</strong> также будет вызвать этот метод один раз за кадр после того, как физика была просчитана и выполнена.<br />
Добавьте следующий метод в <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723213">
<td class="code" id="p87232code13">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> didSimulatePhysics<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #11740a; font-style: italic;">// Set velocity based on x-axis acceleration</span>
  player.physicsBody?.velocity <span style="color: #002200;">=</span> CGVector<span style="color: #002200;">&#40;</span>dx<span style="color: #002200;">:</span> xAcceleration <span style="color: #002200;">*</span> <span style="color: #2400d9;">400.0</span>, dy<span style="color: #002200;">:</span> player.physicsBody<span style="color: #002200;">!</span>.velocity.dy<span style="color: #002200;">&#41;</span>
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #11740a; font-style: italic;">// Check x bounds</span>
  <span style="color: #a61390;">if</span> player.position.x &lt; <span style="color: #002200;">-</span><span style="color: #2400d9;">20.0</span> <span style="color: #002200;">&#123;</span>
    player.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">+</span> <span style="color: #2400d9;">20.0</span>, y<span style="color: #002200;">:</span> player.position.y<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>player.position.x &gt; <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">+</span> <span style="color: #2400d9;">20.0</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    player.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">20.0</span>, y<span style="color: #002200;">:</span> player.position.y<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь происходит несколько вещей:</p>
<p>1. Мы изменяем горизонтальную составляющую значения скорости узла героя, используя значение <strong>xAcceleration</strong>. Далее умножаем её на 400, потому что масштаб акселерометра не соответствует масштабу реальной физики и, увеличивая значение, мы получаем более реалистичный эффект. Значение скорости по оси Y мы оставляем без изменений, потому что акселерометр на него никоем образом не влияет.<br />
2. В Mega Jump, когда герой выходит за пределы экрана слева или справа, он потом возвращается с противоположной стороны. Мы используем то же поведение здесь, проверяя границы экрана и оставляя границу в 20 точек за пределами экрана.</p>
<p>Постройте и запустите на вашем устройстве. Используйте акселерометр, чтобы поднять спрайт героя насколько высоко, насколько сможете!</p>
<p><a href="/wp-content/uploads/2015/03/gm10.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/gm10-220x390.jpg"  width="220" height="390" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 3" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 3" /> </a></p>
<h3>Система подсчета очков</h3>
<p>В целом наша игра Uber Jump будет включать в себя три вида информации, имеющей отношение к герою:</p>
<p>1. Текущий счет. Счёт будет начинаться с нуля. Чем выше герой добирается, тем больше очков добавляется к вашему счету. Вы также будете получать очки за каждую собранную звезду.<br />
2. Наивысший балл. В конце каждого цикла игры всегда будут финальные очки. Uber Jump будет записывать самые высокие значения в файл с настройками пользователя (<strong>user defaults</strong>), для чтобы игрок знал рекорды, которые нужно побить.<br />
3. Звезды. В отличие от текущего счета, который будет сбрасывается в начале каждой игры, звезды героя будут накапливаться от игры к игре. В будущей версии Uber Jump вы можете сделать из звезд специальную валюту игры, за которую пользователи смогут покупать  обновления и дополнительные опции. Мы не будем этого делать в рамках текущего урока, но добавим такую возможность на случай, если вы захотите это сделать по своему усмотрению.</p>
<p>Мы собираемся сохранять текущий счет, наивысший балл и количество собранных звезд в классе синглетоне под названием <strong>GameState</strong>. Этот класс в свою очередь будет записывать наивысший балл и количество звезд в файл на устройстве для того, чтобы значения хранились между запусками игры.</p>
<p>Создайте новый <strong>iOS/Source/Swift File</strong>  с именем <strong>GameState</strong>. Добавьте следующее описание класса и свойства в <strong>GameState.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723214">
<td class="code" id="p87232code14">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">class</span> GameState <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">var</span> score<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span>
  <span style="color: #a61390;">var</span> highScore<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span>
  <span style="color: #a61390;">var</span> stars<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span>
&nbsp;
  <span style="color: #a61390;">class</span> <span style="color: #a61390;">var</span> sharedInstance<span style="color: #002200;">:</span> GameState <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">struct</span> Singleton <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">static</span> <span style="color: #a61390;">let</span> instance <span style="color: #002200;">=</span> GameState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> Singleton.instance
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Заданные три свойства будут предоставлять доступ к текущему счету, наивысшему баллу и к количеству звезд. Переменная класса <strong>sharedInstance</strong> будет давать доступ к единственному экземпляру класса <strong>GameState</strong>.<br />
Нам также необходим метод для инициализации <strong>GameState</strong>, который будет обнулять текущий счет, а также загружать наивысший балл (если такой существует) и количество звезд из файла с настройками пользователя.<br />
Добавьте следующий метод инициализации для <strong>GameState.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723215">
<td class="code" id="p87232code15">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">init</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Init</span>
  score <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
  highScore <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
  stars <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Load game state</span>
  <span style="color: #a61390;">let</span> defaults <span style="color: #002200;">=</span> <span style="color: #400080;">NSUserDefaults</span>.standardUserDefaults<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
  highScore <span style="color: #002200;">=</span> defaults.integerForKey<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;highScore&quot;</span><span style="color: #002200;">&#41;</span>
  stars <span style="color: #002200;">=</span> defaults.integerForKey<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;stars&quot;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Использование класса <strong>NSUserDefaults</strong> является простым способом для хранения небольшого количества данных на устройстве. Он предназначен для пользовательских настроек, но в этом примере он служит для хранения наивысшего балла и количества звезд. В реальном приложении, вы скорее всего захотите использовать что-то более надежное, чем <strong>NSUserDefaults</strong>, чтобы никто не смог с легкостью поменять хранимые там данные и  записать себе больше звезд чем он заработал!</p>
<p><strong>Примечание: Для получения более подробной информации по хранению данных игры, посмотрите урок <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS82MzIzNS9ob3ctdG8tc2F2ZS15b3VyLWdhbWUtZGF0YS10dXRvcmlhbC1wYXJ0LTEtb2YtMg==/">How to Save your Game Data</a>.</strong></p>
<p>Для хранения заданных значений нам понадобится метод в <strong>GameState</strong>. Добавьте следующий метод в <strong>GameState.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723216">
<td class="code" id="p87232code16">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> saveState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Update highScore if the current score is greater</span>
  highScore <span style="color: #002200;">=</span> <span style="color: #a61390;">max</span><span style="color: #002200;">&#40;</span>score, highScore<span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Store in user defaults</span>
  <span style="color: #a61390;">let</span> defaults <span style="color: #002200;">=</span> <span style="color: #400080;">NSUserDefaults</span>.standardUserDefaults<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
  defaults.setInteger<span style="color: #002200;">&#40;</span>highScore, forKey<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;highScore&quot;</span><span style="color: #002200;">&#41;</span>
  defaults.setInteger<span style="color: #002200;">&#40;</span>stars, forKey<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;stars&quot;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #400080;">NSUserDefaults</span>.standardUserDefaults<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>.synchronize<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Вот класс <strong>GameState</strong>, который синхронизируется с хранилищем на устройстве. </p>
<p><strong>У нас получился почти работающий проект, в следующей финальной части, мы доведем все до ума получим настоящее игровое приложение!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2015/03/16/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Делаем игру для iPhone в стиле Mega Jump – Часть 2</title>
		<link>http://iphone-gps.ru/2015/03/03/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-2/</link>
		<comments>http://iphone-gps.ru/2015/03/03/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-2/#comments</comments>
		<pubDate>Tue, 03 Mar 2015 19:13:57 +0000</pubDate>
		<dc:creator>Vadim Nefedov</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=39735</guid>
		<description><![CDATA[
Мы продолжаем учебный курс по созданию игры для iPhone на Sprite Kit и Swift. В первой части у нас получилось создать игровую сцену на которой находится наш герой, и даже заставить его подчиняться законам гравитации. В этом уроке мы научим гороя взаимодействовать с внешним миром, ловить &#8220;звезды&#8221; и подпрыгивать на платформах&#8230;
&#8220;Нажмите, чтобы начать&#8221;
Оригинал статьи на [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2015/03/game0.jpg"  width="400" height="387" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /></p>
<p>Мы продолжаем учебный курс по созданию игры для iPhone на Sprite Kit и Swift. В <a href="/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/">первой части</a> у нас получилось создать игровую сцену на которой находится наш герой, и даже заставить его подчиняться законам гравитации. В этом уроке мы научим гороя взаимодействовать с внешним миром, ловить &#8220;звезды&#8221; и подпрыгивать на платформах&#8230;</p>
<h3>&#8220;Нажмите, чтобы начать&#8221;</h3>
<p>Оригинал статьи на английском языке можно прочитать <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS84NzIzMS9tYWtlLWdhbWUtbGlrZS1tZWdhLWp1bXAtc3ByaXRlLWtpdC1zd2lmdC1wYXJ0LTE=/">здесь</a>.<br />
Теперь, когда гравитация в игре работает, нужно сделать физическое тело героя неподвижным до тех пор, пока пользователь не решит начать игру. Внутри файла <strong>GameScene.swift</strong> найдите строку в методе <strong>createPlayer</strong>, которая устанавливает свойство <strong>dynamic</strong> физическому телу объекта <strong>playerNode</strong>. Измените его значение на <strong>false</strong>, так как показано здесь:</p>
<div class="codebox">
<table>
<tr id="p8723112">
<td class="code" id="p87231code12">
<pre class="swift" style="font-family:monospace;">playerNode.physicsBody?.dynamic <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы собираемся написать код, который позволит пользователю начать игру нажав на экран. И об этом его нужно предупредить какой-нибудь надписью. Например: &#8220;Tap to start&#8221; (Нажмите, чтобы начать). Давайте разместим эту инструкцию на экране.</p>
<p>Поскольку инструкции будут располагаться в слое HUD, создайте его первым. В методе <strong>init(size:)</strong> сразу после места, где вы добавили узел переднего плана на сцену, вставьте следующий код:</p>
<div class="codebox">
<table>
<tr id="p8723113">
<td class="code" id="p87231code13">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// HUD</span>
hudNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
addChild<span style="color: #002200;">&#40;</span>hudNode<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Графические ресурсы включают в себя изображение, на которое нужно нажать для начала игры. По этому добавьте следующую переменную к свойствам в верхней часть <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723114">
<td class="code" id="p87231code14">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Tap To Start node</span>
<span style="color: #a61390;">let</span> tapToStartNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;TapToStart&quot;</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Чтобы отобразить созданный узел, добавьте следующий код в метод <strong>init(size:)</strong> сразу после строки, которая добавляет узел героя:</p>
<div class="codebox">
<table>
<tr id="p8723115">
<td class="code" id="p87231code15">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Tap to Start</span>
tapToStartNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">180.0</span><span style="color: #002200;">&#41;</span>
hudNode.addChild<span style="color: #002200;">&#40;</span>tapToStartNode<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите, чтобы увидеть надпись &#8220;Tap to start&#8221; чуть выше спрайта героя:</p>
<p><a href="/wp-content/uploads/2015/03/07-TapToStart.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/07-TapToStart-220x387.png"  width="220" height="387" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<p>Для обработки касаний и для начала игры, добавьте следующий метод в класс <strong>GameScene.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723116">
<td class="code" id="p87231code16">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> touchesBegan<span style="color: #002200;">&#40;</span>touches<span style="color: #002200;">:</span> <span style="color: #400080;">NSSet</span>, withEvent event<span style="color: #002200;">:</span> <span style="color: #400080;">UIEvent</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #11740a; font-style: italic;">// If we're already playing, ignore touches</span>
  <span style="color: #a61390;">if</span> player.physicsBody<span style="color: #002200;">!</span>.dynamic <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">return</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #11740a; font-style: italic;">// Remove the Tap to Start node</span>
  tapToStartNode.removeFromParent<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 3</span>
  <span style="color: #11740a; font-style: italic;">// Start the player by putting them into the physics simulation</span>
  player.physicsBody?.dynamic <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 4</span>
  player.physicsBody?.applyImpulse<span style="color: #002200;">&#40;</span>CGVector<span style="color: #002200;">&#40;</span>dx<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, dy<span style="color: #002200;">:</span> <span style="color: #2400d9;">20.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Давайте рассмотрим этот метод детально:</p>
<p>1. Мы должны убедится в том, что узел героя стал динамическим. Если это так, то просто игнорируем событие касания.</p>
<p>2. Удаляем узел с надписью &#8220;Tap to start&#8221;.</p>
<p>3. Делаем физическое тело узла героя динамическим для того, чтобы физический движок мог влиять на него.</p>
<p>4. Сообщаем узлу героя начальный импульс, направленный вверх, чтобы он начал движение.</p>
<p>Постройте и запустите. При нажатии на экран, надпись «Tab to start» исчезнет, а спрайт героя подбросится вверх, но ненадолго &#8211; сила тяжести берет своё.</p>
<h3>Игровые объекты: дотянуться до звезд!</h3>
<p>Чтобы вашему герою было чем заняться, кроме как просто прыгать вверх, самое время добавить &#8220;звезды&#8221;. Звезды играют важную роль в Uber Jump: именно их игрок должен собирать для перехода на следующий уровень.</p>
<p>Для начала вам достаточно будет создать в игре одну звезду и заставить её полностью функционировать, а в следующей части урока мы завершим уже весь уровень.</p>
<p>По сценарию игры Uber Jump, как и Mega Jump, когда спрайт героя поднимается на определенное расстояние выше звезды, платформы или любого другого объекта, этот объект удаляется со сцены. Так как и узлы и звезды и платформы попадают под это условие, имеет смысл создать подкласс <strong>SKNode</strong> для всех игровых объектов.</p>
<p>Создайте новый класс <strong>Cocoa Touch Class</strong> с названием <strong>GameObjectNode</strong> и сделайте его подклассом <strong>SKNode</strong>. Убедитесь, что в качестве языка установлен <strong>Swift</strong>.</p>
<p><a href="/wp-content/uploads/2015/03/game2.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game2-400x236.png"  width="400" height="236" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<p>Класс <strong>GameObjectNode</strong> будет включать в себя следующий функционал:</p>
<p>1. Удаление из сцены того объекта, от которого узел героя отдалился на расстояние, больше чем заданное.</p>
<p>2. Обнаружение столкновений между узлом героя и объектом. Этот метод вернет булевое значение, которое будет уведомлять, произошло ли пересечение героя с каким-либо объектом игры, которое приведет к необходимости обновления слоя HUD. Например, если игрок набрал очки.</p>
<p>Замените код в <strong>GameObjectNode.swift</strong> на следующий:</p>
<div class="codebox">
<table>
<tr id="p8723117">
<td class="code" id="p87231code17">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">import</span> SpriteKit
&nbsp;
<span style="color: #a61390;">class</span> GameObjectNode<span style="color: #002200;">:</span> <span style="color: #400080;">SKNode</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">func</span> collisionWithPlayer<span style="color: #002200;">&#40;</span>player<span style="color: #002200;">:</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; <span style="color: #a61390;">Bool</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">false</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #a61390;">func</span> checkNodeRemoval<span style="color: #002200;">&#40;</span>playerY<span style="color: #002200;">:</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> playerY &gt; <span style="color: #a61390;">self</span>.position.y <span style="color: #002200;">+</span> <span style="color: #2400d9;">300.0</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">self</span>.removeFromParent<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы вызываем метод <strong>collisionWithPlayer</strong> всякий раз, когда узел героя сталкивается с объектом, а также вызываем <strong>checkNodeRemoval</strong> в каждом кадре, чтоб была возможность сразу удалить ненужный узел со сцены.</p>
<p>В классе <strong>GameObjectNode</strong> метод <strong>collisionWithPlayer</strong> представляет из себя просто заглушку. Мы зададим полный метод отдельно в каждом из подклассов, которые будут созданы для ваших игровых объектов.</p>
<p>Метод <strong>checkNodeRemoval</strong> проверяет, переместился ли узел героя на расстояние более чем 300 точек от этого узла. Если это так, то метод удаляет узел из его родительского узла и, таким образом, убирает его со сцены.</p>
<h3>Класс звезды</h3>
<p>Теперь, когда у нас есть базовый класс для интерактивных узлов игры, мы можем создать класс для звезд. Чтобы не усложнять, добавим все подклассы <strong>GameObjectNode</strong> сразу в файл <strong>GameObjectNode.swift</strong>. Добавьте следующий код после класса <strong>GameObjectNode</strong>.</p>
<div class="codebox">
<table>
<tr id="p8723118">
<td class="code" id="p87231code18">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">class</span> StarNode<span style="color: #002200;">:</span> GameObjectNode <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> collisionWithPlayer<span style="color: #002200;">&#40;</span>player<span style="color: #002200;">:</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; <span style="color: #a61390;">Bool</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Boost the player up</span>
    player.physicsBody?.velocity <span style="color: #002200;">=</span> CGVector<span style="color: #002200;">&#40;</span>dx<span style="color: #002200;">:</span> player.physicsBody<span style="color: #002200;">!</span>.velocity.dx, dy<span style="color: #002200;">:</span> <span style="color: #2400d9;">400.0</span><span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Remove this Star</span>
    <span style="color: #a61390;">self</span>.removeFromParent<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// The HUD needs updating to show the new stars and score</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">true</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Столкновение со звездой подбрасывает узел героя вверх по оси ординат. Вы можете спросить: &#8220;почему для этого мы не используем силу или импульс физического движка?&#8221;</p>
<p>Если бы мы задействовали силу или импульс, нужный эффект был бы не всегда. Например, если узел героя двигается вниз экрана и врезается в звезду, то сила воздействия на героя будет гораздо меньше, чем когда он двигается вверх.</p>
<p>Следующая диаграмма очень наглядно это показывает:</p>
<p><a href="/wp-content/uploads/2015/03/game3.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game3-400x100.png"  width="400" height="100" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<p>Решение данной проблемы заключается в непосредственном изменении скорости узла игрока. Как известно, вектор скорости складывается из горизонтальной и вертикальной составляющих.</p>
<p>Скорость по оси X не должна изменяться, так как на неё влияет только акселерометр, который мы реализуем позже. В вышеуказанном способе при столкновении мы устанавливаем   фиксированное значение скорости вертикальной проекции &#8211; 400. Чтобы столкновение имело одинаковые последствия независимо от того, что делал игрок перед тем как столкнуться со звездой.</p>
<p>Откройте <strong>GameScene.swift</strong> и добавьте следующий метод:</p>
<div class="codebox">
<table>
<tr id="p8723119">
<td class="code" id="p87231code19">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createStarAtPosition<span style="color: #002200;">&#40;</span>position<span style="color: #002200;">:</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; StarNode <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #a61390;">let</span> node <span style="color: #002200;">=</span> StarNode<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">let</span> thePosition <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> position.x <span style="color: #002200;">*</span> scaleFactor, y<span style="color: #002200;">:</span> position.y<span style="color: #002200;">&#41;</span>
  node.position <span style="color: #002200;">=</span> thePosition
  node.name <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;NODE_STAR&quot;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #a61390;">var</span> sprite<span style="color: #002200;">:</span> <span style="color: #400080;">SKSpriteNode</span>
  sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Star&quot;</span><span style="color: #002200;">&#41;</span>
  node.addChild<span style="color: #002200;">&#40;</span>sprite<span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 3</span>
  node.physicsBody <span style="color: #002200;">=</span> SKPhysicsBody<span style="color: #002200;">&#40;</span>circleOfRadius<span style="color: #002200;">:</span> sprite.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 4</span>
  node.physicsBody?.dynamic <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span>
&nbsp;
  <span style="color: #a61390;">return</span> node
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Код, представленный выше, должен быть вам уже знаком:</p>
<p>1. Мы создаем экземпляр класса <strong>StarNode </strong>и устанавливаем его позицию.</p>
<p>2. Затем добавляем графику звезды, используя <strong>SKSpriteNode</strong>.</p>
<p>3. Добавляем к узлу физическое тело в форме круга, которое нам понадобится для обнаружения столкновений с другими объектами игры.</p>
<p>4. Наконец, мы делаем физическое тело статическим, потому что не хотим, чтобы гравитация или любые другие физические симуляции влияли на звезды.</p>
<p>Теперь добавьте следующий код в метод <strong>init(size:)</strong>, сразу перед тем местом, где мы создали узел героя. Мы хотим, чтобы звезды размещались позади игрока, но тоже находились на узле переднего плана, поэтому мы должны добавить их раньше, чем узел игрока.</p>
<div class="codebox">
<table>
<tr id="p8723120">
<td class="code" id="p87231code20">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add a star</span>
<span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> createStarAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">160</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">220</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
foregroundNode.addChild<span style="color: #002200;">&#40;</span>star<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите игру. Нажмите на кнопку начала игры и посмотрите, как спрайт героя будет сталкиваться со звездой.</p>
<p><a href="/wp-content/uploads/2015/03/game4.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game4-220x388.jpg"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<p>Наш Ульта прыгун ударился головой об звезду. Это было не по плану! Как вы думаете, почему так произошло? Попробуйте догадаться.</p>
<p>А вот решение:</p>
<p>Физический движок обрабатывает столкновения между героем и узлами звезд. Физическое тело узла героя пересекает физическое тело узла звезды, которое является статическим и, следовательно, неподвижным. Узел звезды останавливает движение узла игрока.</p>
<h3>Обнаружение столкновений и битовые маски</h3>
<p>Для обнаружения столкновений между героем и узлами звезд, нам нужно получить событие столкновения и вызвать метод <strong>collisionWithPlayer</strong> класса <strong>GameObjectNode</strong>.</p>
<p>Самое время рассмотреть тему пересечения битовых масок в <strong>Sprite Kit</strong>.</p>
<p>Для сообщения физическим телам информации о столкновениях существуют три свойства, связанные с битовыми масками, которые вы можете использовать, чтобы определить способ взаимодействия физического тела с другими физическими телами игры.</p>
<p>1. <strong>categoryBitMask</strong> определяет категорию столкновения, к которой относится физическое тело.</p>
<p>2. <strong>collisionBitMask</strong> устанавливает категорию столкновения тел, с которыми данное тело будет пересекаться. Здесь слово &#8220;пересекаться&#8221; означает, что объекты будут именно сталкиваться друг с другом. Например, играя в качестве стрелка от третьего лица, вам будет нужно, чтобы спрайт героя сталкивался с вражескими спрайтами, но проходил сквозь спрайты других игроков.</p>
<p>3. <strong>contactTestBitMask</strong> сообщает движку Sprite Kit, чтобы он уведомлял вас, когда данное физическое тело вступает в контакт с физическими телами, принадлежащими к одной из указанных вами категорий. Например, в нашей игре мы хотим, чтобы Sprite Kit сообщал нам, когда спрайт игрока касается звезды или платформы. Используя правильные сочетания настроек для contactTestBitMask и collisionBitMask, можно запрограммировать Sprite Kit так, чтобы объекты проходили друг сквозь друга, а он уведомлял вас, когда это происходит. Таким образом мы можем инициировать события.</p>
<p>Первое, что нужно сделать, это задать свои категории. Откройте <strong>GameObjectNode.swift</strong> и добавьте следующую структуру над определениями классов:</p>
<div class="codebox">
<table>
<tr id="p8723121">
<td class="code" id="p87231code21">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">struct</span> CollisionCategoryBitmask <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">static</span> <span style="color: #a61390;">let</span> Player<span style="color: #002200;">:</span> UInt32 <span style="color: #002200;">=</span> 0x00
  <span style="color: #a61390;">static</span> <span style="color: #a61390;">let</span> Star<span style="color: #002200;">:</span> UInt32 <span style="color: #002200;">=</span> 0x01
  <span style="color: #a61390;">static</span> <span style="color: #a61390;">let</span> Platform<span style="color: #002200;">:</span> UInt32 <span style="color: #002200;">=</span> 0x02
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Вернитесь в <strong>GameScene.swift</strong>. Чтобы задать поведение героя во время столкновений, добавьте следующий код в нижнюю часть метода <strong>createPlayer</strong>, сразу перед оператором <strong>return</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723122">
<td class="code" id="p87231code22">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// 1</span>
playerNode.physicsBody?.usesPreciseCollisionDetection <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
<span style="color: #11740a; font-style: italic;">// 2</span>
playerNode.physicsBody?.categoryBitMask <span style="color: #002200;">=</span> CollisionCategoryBitmask.Player
<span style="color: #11740a; font-style: italic;">// 3</span>
playerNode.physicsBody?.collisionBitMask <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
<span style="color: #11740a; font-style: italic;">// 4</span>
playerNode.physicsBody?.contactTestBitMask <span style="color: #002200;">=</span> CollisionCategoryBitmask.Star | CollisionCategoryBitmask.Platform</pre>
</td>
</tr>
</table>
</div>
<p>Давайте повнимательней рассмотрим этот блока кода:</p>
<p>1. Так как эта игра на быстрое движение, Sprite Kit должен использовать точное обнаружение столкновений для физического тела узла героя. Ведь весь сюжет Uber Jump строится на этих столкновениях. Поэтому нам нужно, чтобы они фиксировались настолько точно, насколько возможно! (будет задействовано несколько циклов процессора)</p>
<p>2. Мы назначаем категорию битовой маски физического тела. Она относится к категории <strong>CollisionCategoryPlayer</strong>.</p>
<p>3. Приравняв <strong>collisionBitMask</strong> к нулю, мы сообщаем Sprite Kit, что не хотим, чтобы он имитировал какие-либо столкновения узла игрока. Это потому, что мы собираемся обрабатывать эти столкновения сами!</p>
<p>4. Мы сообщаем Sprite Kit, что хотим получать уведомления, когда узел героя будет касаться каких-либо звезд или платформ.</p>
<p>Теперь настроим узел звезды. Добавьте следующий код в нижней части метода <strong>createStarAtPosition</strong> перед оператором <strong>return</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723123">
<td class="code" id="p87231code23">
<pre class="swift" style="font-family:monospace;">node.physicsBody?.categoryBitMask <span style="color: #002200;">=</span> CollisionCategoryBitmask.Star
node.physicsBody?.collisionBitMask <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span></pre>
</td>
</tr>
</table>
</div>
<p>Здесь всё аналогично настройке узла героя. Мы назначаем категорию звезды и обнуляем свойство <strong>collisionBitMask</strong>, поэтому она не будет ни с чем сталкиваться. Однако здесь мы не назначаем <strong>contactTestBitMask</strong>, это значит, что Sprite Kit не будет уведомлять нас, когда какой-либо объект будет касаться звезды. Мы ведь уже поручили Sprite Kit отправлять уведомления при соприкосновении героя со звездой, а кроме звезды он ни с чем соприкасаться не будет, поэтому нет никакой необходимости отправлять уведомления со стороны звезды.</p>
<p>Sprite Kit посылает уведомления о контактах выбранных нами узлов, вызывая метод <strong>didBeginContact</strong> делегата <strong>SKPhysicsContactDelegate</strong>. В качестве делегата физического мира установите саму сцену, добавив протокол <strong>SKPhysicsContactDelegate</strong> к определению класса <strong>GameScene</strong>. Это должно выглядеть примерно так:</p>
<div class="codebox">
<table>
<tr id="p8723124">
<td class="code" id="p87231code24">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">class</span> GameScene<span style="color: #002200;">:</span> <span style="color: #400080;">SKScene</span>, SKPhysicsContactDelegate <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Layered Nodes</span>
  ...</pre>
</td>
</tr>
</table>
</div>
<p>Теперь назначьте сцену делегатом для получения контактных уведомлений, добавив следующую строку в <strong>init(size:)</strong>, сразу после строки, которая устанавливает гравитацию:</p>
<div class="codebox">
<table>
<tr id="p8723125">
<td class="code" id="p87231code25">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Set contact delegate</span>
physicsWorld.contactDelegate <span style="color: #002200;">=</span> <span style="color: #a61390;">self</span></pre>
</td>
</tr>
</table>
</div>
<p>И, наконец, добавьте следующий метод в <strong>GameScene.swift</strong> для обработки событий столкновений:</p>
<div class="codebox">
<table>
<tr id="p8723126">
<td class="code" id="p87231code26">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> didBeginContact<span style="color: #002200;">&#40;</span>contact<span style="color: #002200;">:</span> SKPhysicsContact<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #a61390;">var</span> updateHUD <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #a61390;">let</span> whichNode <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>contact.bodyA.node <span style="color: #002200;">!=</span> player<span style="color: #002200;">&#41;</span> ? contact.bodyA.node <span style="color: #002200;">:</span> contact.bodyB.node
  <span style="color: #a61390;">let</span> other <span style="color: #002200;">=</span> whichNode <span style="color: #a61390;">as</span> GameObjectNode
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 3</span>
  updateHUD <span style="color: #002200;">=</span> other.collisionWithPlayer<span style="color: #002200;">&#40;</span>player<span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Update the HUD if necessary</span>
  <span style="color: #a61390;">if</span> updateHUD <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// 4 TODO: Update HUD in Part 2</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Давайте рассмотрим этот код поподробнее:</p>
<p>1. Мы инициализируем флаг <strong>updateHUD</strong>, который будем использовать в конце метода, чтобы обновлять HUD во время этих столкновений и подсчитывать очки.</p>
<p>2. <strong>SKPhysicsContact</strong> не гарантирует, какое физическое тело выступит в роли bodyA, а какое в роли bodyB. Но мы знаем, что все столкновения в этой игре будут между узлом героя и узлом <strong>GameObjectNode</strong>. Поэтому эта строка определяет, какой из них не является узлом героя.</p>
<p>3. После того, как мы определили, какой объект не является узлом героя, мы вызываем метод <strong>collisionWithPlayer:</strong> в классе <strong>GameObjectNode</strong>.</p>
<p>4. Здесь мы обновляем HUD, если это требуется. Реализацию HUD мы будем делать во второй части урока, поэтому здесь кроме комментария пока ничего нет.</p>
<p>Постройте и запустите игру. Нажмите, чтобы начать. При столкновении звезда подбрасывает спрайт героя на определенную высоту, а затем удаляется со сцены. Хорошая работа!</p>
<p><a href="/wp-content/uploads/2015/03/game5.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game5-220x387.jpg"  width="220" height="387" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<p>Ну что, было проделано много тяжелой работы! Возьмем заслуженный перерыв. В следующем разделе нам предстоит добавить новый типы звезды <strong>uber star</strong>, а также звуковой эффект.</p>
<p>Примечание: Если вы хотите узнать больше об определении контактов и столкновений в Sprite Kit, то изучите руководство &#8220;<a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS9zdG9yZS9pb3MtZ2FtZXMtYnktdHV0b3JpYWxz/">iOS Games by Tutorials</a>&#8220;, в котором содержится три больших главы по физике движка.</p>
<h3>Несколько видов звезд</h3>
<p>Uber Jump будет содержать два вида звезд: те, которые добавляют одно очко и специальные звезды, добавляющие сразу пять очков. Звезда каждого типа будет иметь свою графику. Идентифицировать тип звезды нам поможет коллекция в классе <strong>StarNode</strong>.</p>
<p>В верхнюю часть <strong>GameObjectNode.swift</strong> добавьте следующую коллекцию:</p>
<div class="codebox">
<table>
<tr id="p8723127">
<td class="code" id="p87231code27">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">enum</span> StarType<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">case</span> Normal <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
  <span style="color: #a61390;">case</span> Special
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Для хранения типа звезды, добавьте следующее свойство в верхнюю часть класса <strong>StarNode</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723128">
<td class="code" id="p87231code28">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">var</span> starType<span style="color: #002200;">:</span> StarType<span style="color: #002200;">!</span></pre>
</td>
</tr>
</table>
</div>
<p>Теперь при создании звезды нам нужно будет указывать её тип, поэтому в <strong>GameScene.swift</strong> добавьте параметр <strong>starType</strong> к сигнатуре метода <strong>createStarAtPosition:</strong>, чтобы это выглядело так:</p>
<div class="codebox">
<table>
<tr id="p8723129">
<td class="code" id="p87231code29">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createStarAtPosition<span style="color: #002200;">&#40;</span>position<span style="color: #002200;">:</span> <span style="color: #400080;">CGPoint</span>, ofType type<span style="color: #002200;">:</span> StarType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; StarNode <span style="color: #002200;">&#123;</span></pre>
</td>
</tr>
</table>
</div>
<p>Внутри <strong>createStarAtPosition(position: ofType:)</strong>, замените три строчки кода (которые создают и добавляют <strong>SKSpriteNode</strong>) на следующие:</p>
<div class="codebox">
<table>
<tr id="p8723130">
<td class="code" id="p87231code30">
<pre class="swift" style="font-family:monospace;">node.starType <span style="color: #002200;">=</span> type
<span style="color: #a61390;">var</span> sprite<span style="color: #002200;">:</span> <span style="color: #400080;">SKSpriteNode</span>
<span style="color: #a61390;">if</span> type <span style="color: #002200;">==</span> .Special <span style="color: #002200;">&#123;</span>
  sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;StarSpecial&quot;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
  sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Star&quot;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span>
node.addChild<span style="color: #002200;">&#40;</span>sprite<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Сначала мы установили тип звезды. Затем, проверяем тип при создании спрайта, чтобы добавить соответствующую картинку.</p>
<p>Осталось только указать тип звезды при её создании. В методе <strong>init(size:)</strong> класса <strong>GameScene.swift</strong> найдите строку, в которой вызываем <strong>createStarAtPosition</strong> и измените его следующим образом:</p>
<div class="codebox">
<table>
<tr id="p8723131">
<td class="code" id="p87231code31">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">let</span> star <span style="color: #002200;">=</span> createStarAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">160</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">220</span><span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> .Special<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Назначаем нашей звезде тип <strong>StarType.Special</strong>.</p>
<p>Постройте запустите. Наша звезда стала розовой! Позже мы добавим систему подсчета очков и различия в типах звезд станут более понятными.</p>
<p><a href="/wp-content/uploads/2015/03/game6.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game6-220x388.jpg"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<h3>Звон! Добавление звукового эффекта</h3>
<p>Было бы неплохо, если бы столкновение героя со звездой сопровождалось звуковым сигналом. Скачайте звуковой эффект для звезды отсюда и перетащите файл в наш проект Xcode. Убедитесь, что указана опция “<strong>Destination: Copy items if needed</strong>” и что выбран таргет UberJump.</p>
<p>Для воспроизведения звуков в Sprite Kit используется <strong>SKAction</strong>. Откройте <strong>GameObjectNode.swift</strong> и добавьте следующее свойство класса выше <strong>StarNode:</strong></p>
<div class="codebox">
<table>
<tr id="p8723132">
<td class="code" id="p87231code32">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">let</span> starSound <span style="color: #002200;">=</span> <span style="color: #400080;">SKAction</span>.playSoundFileNamed<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;StarPing.wav&quot;</span>, waitForCompletion<span style="color: #002200;">:</span> <span style="color: #a61390;">false</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Теперь осталось только воспроизвести звуковой эффект во время столкновения героя со звездой.</p>
<p>В методе <strong>collisionWithPlayer()</strong> класса <strong>StarNode</strong> замените <strong>self.removeFromParent()</strong> на:</p>
<div class="codebox">
<table>
<tr id="p8723133">
<td class="code" id="p87231code33">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Play sound</span>
runAction<span style="color: #002200;">&#40;</span>starSound, completion<span style="color: #002200;">:</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Remove this Star</span>
  <span style="color: #a61390;">self</span>.removeFromParent<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#125;</span><span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Код запускает <strong>SKAction</strong>, воспроизводит звуковой файл и удаляет звезду, когда действие закончено.</p>
<p>Постройте и запустите. Как только спрайт героя столкнётся со звездой, вы услышите звенящий звук.</p>
<h3>Игровые объекты: платформы</h3>
<p>Наш следующая задача &#8211; добавление платформы. Мы создадим для платформ новый подкласс класса <strong>GameObjectNode</strong>. Как и в случае со звездами, нам понадобятся два типа платформ: платформы одного типа должны быть неразрушимыми, а другие должны исчезать в тот момент, когда герой спрыгивает с них.</p>
<p>В <strong>GameObjectNode.swift</strong> добавьте следующую коллекцию над определением класса <strong>GameObjectNode</strong>, чтобы задать два типа платформ:</p>
<div class="codebox">
<table>
<tr id="p8723134">
<td class="code" id="p87231code34">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">enum</span> PlatformType<span style="color: #002200;">:</span> <span style="color: #a61390;">Int</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">case</span> Normal <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
  <span style="color: #a61390;">case</span> Break
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Далее нам нужно создать класс <strong>PlatformNode</strong>. Добавьте следующий код в <strong>GameObjectNode.swift</strong>:</p>
<div class="codebox">
<table>
<tr id="p8723135">
<td class="code" id="p87231code35">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">class</span> PlatformNode<span style="color: #002200;">:</span> GameObjectNode <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">var</span> platformType<span style="color: #002200;">:</span> PlatformType<span style="color: #002200;">!</span>
&nbsp;
  <span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> collisionWithPlayer<span style="color: #002200;">&#40;</span>player<span style="color: #002200;">:</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; <span style="color: #a61390;">Bool</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// 1</span>
    <span style="color: #11740a; font-style: italic;">// Only bounce the player if he's falling</span>
    <span style="color: #a61390;">if</span> player.physicsBody?.velocity.dy &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// 2</span>
      player.physicsBody?.velocity <span style="color: #002200;">=</span> CGVector<span style="color: #002200;">&#40;</span>dx<span style="color: #002200;">:</span> player.physicsBody<span style="color: #002200;">!</span>.velocity.dx, dy<span style="color: #002200;">:</span> <span style="color: #2400d9;">250.0</span><span style="color: #002200;">&#41;</span>
&nbsp;
      <span style="color: #11740a; font-style: italic;">// 3</span>
      <span style="color: #11740a; font-style: italic;">// Remove if it is a Break type platform</span>
      <span style="color: #a61390;">if</span> platformType <span style="color: #002200;">==</span> .Break <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">self</span>.removeFromParent<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
      <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// 4</span>
    <span style="color: #11740a; font-style: italic;">// No stars for platforms</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">false</span>
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Давайте подробней остановим своё внимание на этом коде:</p>
<p>1. В соответствии со сценарием игры, узел героя должен отскакивать от платформы только при падении, т.е тогда, когда он имеет отрицательное значение dy своей скорости (свойство velocity). Эта проверка также позволяет узлу героя не пересекаться с платформами, двигаясь вверх по экрану.</p>
<p>2. Мы сообщаем узлу героя скорость, направленную вверх, чтобы он отскочил от платформы. Это делается также, как раньше мы это сделали для звезд, но с меньшим значением. Звезды ведь круче, не так ли?</p>
<p>3. Если платформа относится к типу <strong>platformType.Break</strong>, то мы удаляем её со сцены.</p>
<p>4. Ультра прыгун не получает очки ни когда спрыгивает с платформы, ни когда запрыгивает на нее, поэтому нет никакой необходимости обновлять HUD.</p>
<p>Для добавления платформы для сцену откройте <strong>GameScene.swift</strong> и впишите следующий метод:</p>
<div class="codebox">
<table>
<tr id="p8723136">
<td class="code" id="p87231code36">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createPlatformAtPosition<span style="color: #002200;">&#40;</span>position<span style="color: #002200;">:</span> <span style="color: #400080;">CGPoint</span>, ofType type<span style="color: #002200;">:</span> PlatformType<span style="color: #002200;">&#41;</span> <span style="color: #002200;">-</span>&gt; PlatformNode <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #a61390;">let</span> node <span style="color: #002200;">=</span> PlatformNode<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">let</span> thePosition <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> position.x <span style="color: #002200;">*</span> scaleFactor, y<span style="color: #002200;">:</span> position.y<span style="color: #002200;">&#41;</span>
  node.position <span style="color: #002200;">=</span> thePosition
  node.name <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">&quot;NODE_PLATFORM&quot;</span>
  node.platformType <span style="color: #002200;">=</span> type
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #a61390;">var</span> sprite<span style="color: #002200;">:</span> <span style="color: #400080;">SKSpriteNode</span>
  <span style="color: #a61390;">if</span> type <span style="color: #002200;">==</span> .Break <span style="color: #002200;">&#123;</span>
    sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;PlatformBreak&quot;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
    sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">&#40;</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">&quot;Platform&quot;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#125;</span>
  node.addChild<span style="color: #002200;">&#40;</span>sprite<span style="color: #002200;">&#41;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">// 3</span>
  node.physicsBody <span style="color: #002200;">=</span> SKPhysicsBody<span style="color: #002200;">&#40;</span>rectangleOfSize<span style="color: #002200;">:</span> sprite.size<span style="color: #002200;">&#41;</span>
  node.physicsBody?.dynamic <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span>
  node.physicsBody?.categoryBitMask <span style="color: #002200;">=</span> CollisionCategoryBitmask.Platform
  node.physicsBody?.collisionBitMask <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>
&nbsp;
  <span style="color: #a61390;">return</span> node
<span style="color: #002200;">&#125;</span></pre>
</td>
</tr>
</table>
</div>
<p>Этот метод очень похож на <strong>createStarAtPosition (_: OfType : )</strong>, но обратите внимание на следующие основные моменты:</p>
<p>1. Мы создаем экземпляр <strong>PlatformNode</strong> и задаем его позицию, имя и тип.</p>
<p>2. Выбираем соответствующее изображение для <strong>SKSpriteNode</strong> в зависимости от типа платформы.</p>
<p>3. Создаем физику платформы, в том числе тип столкновений.</p>
<p>Теперь, чтобы добавить платформу, вставьте следующий код в метод <strong>init(size:)</strong>, сразу перед строчкой, которая создает звезду:</p>
<div class="codebox">
<table>
<tr id="p8723137">
<td class="code" id="p87231code37">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add a platform</span>
<span style="color: #a61390;">let</span> platform <span style="color: #002200;">=</span> createPlatformAtPosition<span style="color: #002200;">&#40;</span><span style="color: #400080;">CGPoint</span><span style="color: #002200;">&#40;</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">160</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">320</span><span style="color: #002200;">&#41;</span>, ofType<span style="color: #002200;">:</span> .Normal<span style="color: #002200;">&#41;</span>
foregroundNode.addChild<span style="color: #002200;">&#40;</span>platform<span style="color: #002200;">&#41;</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите игру. Нажмите, чтобы начать и посмотрите, как спрайт героя зарядится энергией от звезды, а затем подпрыгнет на платформе!</p>
<p><a href="/wp-content/uploads/2015/03/game7.png" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2015/03/game7-220x388.png"  width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump – Часть 2" alt="Делаем игру для iPhone в стиле Mega Jump – Часть 2" /> </a></p>
<h3>Куда идти дальше?</h3>
<p>Отлично! Как вы уже поняли, создание игры подобной Mega Jump &#8211; это не так уж и сложно. С помощью Uber Jump мы изучили все базовые основы, которые сможем использовать далее, на пути к созданию отличной игры.</p>
<p>В конце статьи вы можете скачать проект Xcode содержащий всё, что мы изучали в этом курсе.</p>
<p>В следующей части мы задействуем акселерометр для управления перемещением героя по оси Х. А также будем загружать ряд свойств из внешнего файла plist и добавим систему подсчёта очков. Много всего интересного ещё предстоит.</p>
<p>Если у вас есть какие-либо вопросы, мысли или предложения для будущих уроков, пожалуйста, оставьте ниже свой комментарий.</p>
<p><strong>Продолжение через неделю&#8230;.</strong><br />
Скачать <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly95YWRpLnNrL2QvQzE3S25JT3RlenZzNg==/">Исходник Xcode</a>.<br />
Скачать <a class="frands" href="https://yadi.sk/d/CuKm-KRhedjgx">графические ресурсы для урока</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2015/03/03/delaem-igru-dlya-iphone-v-stile-mega-jump-%e2%80%93-chast-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Делаем игру для iPhone в стиле Mega Jump &#8211; Часть 1</title>
		<link>http://iphone-gps.ru/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/</link>
		<comments>http://iphone-gps.ru/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/#comments</comments>
		<pubDate>Mon, 16 Feb 2015 11:30:59 +0000</pubDate>
		<dc:creator>Vadim Nefedov</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=39052</guid>
		<description><![CDATA[
Сделать мега популярную игру под iOS совсем несложно, и мы это докажем в этой серии уроков  . Этой статьей мы начинаем серию материалов по созданию игры для iPhone.
Мы будем использовать Sprite Kit и Swift на любительском уровне, чтобы создать что-то подобное Mega Jump. Это довольно популярная игра, выполненная в стиле аркады с вертикальными прыжками. [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2015/02/nj0.jpg" width="400" height="270" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></p>
<p>Сделать мега популярную игру под iOS совсем несложно, и мы это докажем в этой серии уроков <img itemprop="image" src='/wp-includes/images/smilies/icon_smile.gif' alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" class='wp-smiley' title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /> . Этой статьей мы начинаем серию материалов по созданию игры для iPhone.<br />
Мы будем использовать Sprite Kit и Swift на любительском уровне, чтобы создать что-то подобное <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL2lqdWljZS5ydS8=/">Mega Jump</a>. Это довольно популярная игра, выполненная в стиле аркады с вертикальными прыжками. Аналогом ее также можно назвать <a href="/2012/06/15/doodle-jump-rodom-iz-detstva/">Doodle Jump</a>. На видео ниже можно посмотреть, как игровой процесс выглядит на устройстве&#8230;<br />
<span id="more-39052"></span></p>
<div class="otbivka"></div>
<p><iframe width="400" height="300" src="https://www.youtube.com/embed/5KbrxEvURU8" frameborder="0" allowfullscreen></iframe></p>
<p>По мере того как мы будем создавать игру, вы научитесь использовать возможности Sprite Kit, такие как: обнаружение столкновений, управление акселерометром, переходы между сценами. Если вы совсем не знакомы с движком Sprite Kit, то можете ознакомится с ним в статье  Рэя Sprite <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS84NDQzNC9zcHJpdGUta2l0LXN3aWZ0LXR1dG9yaWFsLWJlZ2lubmVycw==/">Kit Tutorial for Beginners</a>, а потом приступить к этой серии уроков. Но если вы уверенны в себе, тогда вперёд!</p>
<p>С оригиналом статьи на английском, можно ознакомиться <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS84NzIzMS9tYWtlLWdhbWUtbGlrZS1tZWdhLWp1bXAtc3ByaXRlLWtpdC1zd2lmdC1wYXJ0LTE=/">здесь</a>.</p>
<p><strong>Примечание: Для игры вам понадобится <a href="/2013/03/16/razrabotka-prilozhenij-dlya-iphone-registraciya-v-ios-developer-program/">платный аккаунт разработчика</a>. И если вы намерены использовать этот урок в полной мере, то и устройство для тестирования.</strong></p>
<h3>Начало</h3>
<p>Мы собираемся создать игру подобную Mega Jump. Как гласит известная пословица: &#8220;как Вы яхту назовёте, так она и поплывет&#8221;. Чтобы игра стала по-настоящему яркой, она должна иметь яркое, запоминающееся название.<br />
&#8220;Uber&#8221; &#8211; это ещё лучше, чем &#8220;mega&#8221;, поэтому давайте назовём ее &#8220;Uber Jump&#8221; <img itemprop="image" src='/wp-includes/images/smilies/icon_smile.gif' alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" class='wp-smiley' title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /> . </p>
<p>По сути игра в духе Mega Jump является физической игрой: главный герой подбрасывается вверх экрана и с этого момента он должен бороться с силой тяжести, чтобы продержаться максимально долго. </p>
<p>По мере того, как герой собирает монеты, он поднимается все выше, а платформы обеспечивают временную передышку на его пути. Наша игра Uber Jump будет иметь такую же модель: сначала мы подбросим нашего персонажа вверх, а затем будем применять к нему постоянную силу тяжести. На своём пути он будет собирать звезды, которые помогут ему подниматься вверх, отвечая за движение вдоль ось Y. Если пропустить слишком много звезд, то герой неизбежно упадете вниз.</p>
<p>Акселерометр будет управлять движением игрока вдоль ось X. Наклоняя устройства в право или влево можно задать направление движение героя по горизонтали. </p>
<p>Результат будет состоять из динамической составляющей (так как вы будете прикладывать две силы к игроку), а также из кинематической (так как вы непосредственно будете изменять его скорость). Так что скучать не придется!</p>
<p><a href="/wp-content/uploads/2015/02/h1.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h1-220x388.png" width="220" height="388" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Для начала Вам нужно создать новый Xcode проект с движком Sprite Kit. Запустите Xcode, выберите <span class="blue"><strong>File \ New \ Project</strong></span>, затем <span class="blue"><strong>IOS \ Application \ SpriteKit Game</strong></span> шаблон и нажмите кнопку &#8220;Далее&#8221; (Next).</p>
<p><a href="/wp-content/uploads/2015/02/h2.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h2-400x236.png" width="400" height="236" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>В поле с названием продукта введите UberJump, в качестве языка выберите Swift, во вкладке с устройствами укажите iPhone, а затем нажмите кнопку &#8220;Далее&#8221;.</p>
<p><a href="/wp-content/uploads/2015/02/h3.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h3-400x236.png" width="400" height="236" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Выберите место для хранения проекта и нажмите кнопку &#8220;Создать&#8221;. Перед тем, как приступить к делу, нужно сделать некоторые предварительные настройки. Найдите файл <strong>GameScene.sks</strong> в навигаторе. Он нам не понадобится, поэтому выделите его и нажмите кнопку &#8220;Удалить&#8221;. Когда появится окно оповещения, нажмите &#8220;Переместить в корзину&#8221;.</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/h4.png" width="261" height="288" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></p>
<p>Теперь откройте <strong>GameViewController.swift</strong> и удалите расширение <strong>unarchiveFromFile SKNode</strong> в верхней части файла, так как нам не понадобится никакой посторонний код. Затем замените метод <strong>viewDidLoad</strong> следующим : </p>
<style>
.codebox{background:#F0F0F0; margin: 30px 0px; padding: 0px 20px;}
</style>
<div class="codebox">
<table>
<tr id="p872311">
<td class="code" id="p87231code1">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">override</span> <span style="color: #a61390;">func</span> viewDidLoad<span style="color: #002200;">(</span><span style="color: #002200;">)</span> <span style="color: #002200;">{</span>
  <span style="color: #a61390;">super</span>.viewDidLoad<span style="color: #002200;">(</span><span style="color: #002200;">)</span>
 
  <span style="color: #a61390;">let</span> skView <span style="color: #002200;">=</span> <span style="color: #a61390;">self</span>.view <span style="color: #a61390;">as</span> SKView
 
  skView.showsFPS <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
  skView.showsNodeCount <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
 
  <span style="color: #a61390;">let</span> scene <span style="color: #002200;">=</span> GameScene<span style="color: #002200;">(</span>size<span style="color: #002200;">:</span> skView.bounds.size<span style="color: #002200;">)</span>
  scene.scaleMode <span style="color: #002200;">=</span> .AspectFit
 
  skView.presentScene<span style="color: #002200;">(</span>scene<span style="color: #002200;">)</span>
<span style="color: #002200;">}</span></pre>
</td>
</tr>
</table>
</div>
<p>Нажмите <strong>Build</strong>, затем <strong>Run</strong>, чтобы убедится, что на данный момент всё работает.</p>
<p><a href="/wp-content/uploads/2015/02/h5.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h5-220x361.png" width="220" height="361" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Не беспокойтесь о том, что текстовый лейбл &#8220;Hello, World&#8221; усечён. Вы сможете найти его в файле <strong>GameScene.swift</strong> и заменить на то, что нужно. Но сперва необходимо сделать последнюю вещь по настройке. Так как наша игра будет использовать акселерометр, мы должны быть уверены, что поворот устройства не переключит приложение в ландшафтный режим.</p>
<p>В навигаторе Xcode (там , где сейчас выбран Ваш проект) выберите пункт <strong>UberJump</strong>, перейдите на вкладку <strong>General</strong> в настройках и найдите раздел <strong>Deployment Info</strong>. Убедитесь, что портретная ориентация является единственной доступной для устройства.</p>
<p><a href="/wp-content/uploads/2015/02/h6.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h6-400x243.png" width="400" height="243" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Мы подготовили проект к тому, чтобы начать добавление компонентов игры. Начнем с картинок.</p>
<h3>Импортирование графики</h3>
<p>Скачайте графические ресурсы (ссылка на скачивание в конце статьи) для этого проекта и перетащите их мышкой в Xcode. Убедитесь, что выбрана опция &#8220;<strong>Destination: Copy items if needed</strong>&#8221; и пункт <strong>UberJump</strong>.</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/h7.png" width="261" height="324" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></p>
<p>Иллюстрации разделены на фоновые (папка Backgrounds) и игровые (папка Assets.atlas). Фоновые представляют собой плитки, которые будут перелистываться вверх и вниз по экрану во время движения героя:</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/h8.png" width="104" height="422" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></p>
<p>Игровые включают все спрайты, в частности персонаж, плиты и звезды.</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/h9.png" width="90" height="100" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></p>
<p>В целях повышения эффективности, игровые ресурсы должны хранится в атласе текстур. Вы можете узнать поподробнее об атласах текстур в Sprite Kit в <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5yYXl3ZW5kZXJsaWNoLmNvbS80NTE1Mi9zcHJpdGUta2l0LXR1dG9yaWFsLWFuaW1hdGlvbnMtYW5kLXRleHR1cmUtYXRsYXNlcw==/">этом уроке</a>.</p>
<h3>Построение сцены</h3>
<p>Вы наверное заметили, что в шаблоне проекта уже создан класс <strong>GameScene</strong>. Он представляет собой сцену Sprite Kit, которая на данный момент отображает надпись &#8220;Hello, World!&#8221; при запуске игры. Большинство действий игры Uber Jump будут происходить здесь, поэтому откройте класс <strong>GameScene.swift</strong> и замените содержимое следующим:</p>
<div class="codebox">
<table>
<tr id="p872312">
<td class="code" id="p87231code2">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">import</span> SpriteKit
 
<span style="color: #a61390;">class</span> GameScene<span style="color: #002200;">:</span> <span style="color: #400080;">SKScene</span> <span style="color: #002200;">{</span>
 
  required <span style="color: #a61390;">init</span>?<span style="color: #002200;">(</span>coder aDecoder<span style="color: #002200;">:</span> <span style="color: #400080;">NSCoder</span><span style="color: #002200;">)</span> <span style="color: #002200;">{</span>
    <span style="color: #a61390;">super</span>.<span style="color: #a61390;">init</span><span style="color: #002200;">(</span>coder<span style="color: #002200;">:</span> aDecoder<span style="color: #002200;">)</span>
  <span style="color: #002200;">}</span>
 
  <span style="color: #a61390;">override</span> <span style="color: #a61390;">init</span><span style="color: #002200;">(</span>size<span style="color: #002200;">:</span> <span style="color: #400080;">CGSize</span><span style="color: #002200;">)</span> <span style="color: #002200;">{</span>
    <span style="color: #a61390;">super</span>.<span style="color: #a61390;">init</span><span style="color: #002200;">(</span>size<span style="color: #002200;">:</span> size<span style="color: #002200;">)</span>
    backgroundColor <span style="color: #002200;">=</span> SKColor.whiteColor<span style="color: #002200;">(</span><span style="color: #002200;">)</span>
  <span style="color: #002200;">}</span>
<span style="color: #002200;">}</span></pre>
</td>
</tr>
</table>
</div>
<p>Нажмите Build и Run. GameScene теперь отображает ничто иное, как белый экран. Это чистый холст, на который мы будем добавлять основные объекты игры. Mega Jump использует эффект параллакса слоев, чтобы произвести реалистичную визуализацию объема.  Например, объекты на переднем двигаются быстрее, чем фоновые объекты. В Uber Jump мы собираемся сделать тот же эффект, создав следующие слои в сцене:</p>
<p><strong>- Background:</strong> слой с медленным движением, отображающий далекий пейзаж.<br />
<strong>- Midground:</strong> более быстрая декорация из веток деревьев.<br />
<strong>- Foreground:</strong> быстро движущийся слой, содержащий персонаж, звезды и платформы, которые составляют ядро геймплея.<br />
<strong>- HUD:</strong> верхний слой, который не двигаться и отображает лейблы подсчета очков.</p>
<p>Фоновый узел &#8211; это первый, который нужно добавить. Откройте <strong>GameScene.swift</strong> и добавьте следующий метод:</p>
<div class="codebox">
<table>
<tr id="p872313">
<td class="code" id="p87231code3">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createBackgroundNode<span style="color: #002200;">(</span><span style="color: #002200;">)</span> <span style="color: #002200;">-</span>&gt; <span style="color: #400080;">SKNode</span> <span style="color: #002200;">{</span>
  <span style="color: #11740a; font-style: italic;">// 1</span>
  <span style="color: #11740a; font-style: italic;">// Create the node</span>
  <span style="color: #a61390;">let</span> backgroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
  <span style="color: #a61390;">let</span> ySpacing <span style="color: #002200;">=</span> <span style="color: #2400d9;">64.0</span> <span style="color: #002200;">*</span> scaleFactor
 
  <span style="color: #11740a; font-style: italic;">// 2</span>
  <span style="color: #11740a; font-style: italic;">// Go through images until the entire background is built</span>
  <span style="color: #a61390;">for</span> index <span style="color: #a61390;">in</span> <span style="color: #2400d9;">0</span>...19 <span style="color: #002200;">{</span>
    <span style="color: #11740a; font-style: italic;">// 3</span>
    <span style="color: #a61390;">let</span> node <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">(</span>imageNamed<span style="color: #002200;">:</span><span style="color: #a61390;">String</span><span style="color: #002200;">(</span>format<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">"Background%02d"</span>, index <span style="color: #002200;">+</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">)</span><span style="color: #002200;">)</span>
    <span style="color: #11740a; font-style: italic;">// 4</span>
    node.setScale<span style="color: #002200;">(</span>scaleFactor<span style="color: #002200;">)</span>
    node.anchorPoint <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">(</span>x<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.5</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span><span style="color: #002200;">)</span>
    node.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">(</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> ySpacing <span style="color: #002200;">*</span> <span style="color: #400080;">CGFloat</span><span style="color: #002200;">(</span>index<span style="color: #002200;">)</span><span style="color: #002200;">)</span>
    <span style="color: #11740a; font-style: italic;">//5</span>
    backgroundNode.addChild<span style="color: #002200;">(</span>node<span style="color: #002200;">)</span>
  <span style="color: #002200;">}</span>
 
  <span style="color: #11740a; font-style: italic;">// 6</span>
  <span style="color: #11740a; font-style: italic;">// Return the completed background node</span>
  <span style="color: #a61390;">return</span> backgroundNode
<span style="color: #002200;">}</span></pre>
</td>
</tr>
</table>
</div>
<p>Давайте подробно разберем, что мы здесь делаем:</p>
<p><strong>1.</strong> Во &#8211; первых, мы создаем новый экземпляр <strong>SKNode</strong>. Он не имеет никакого визуального содержимого, но располагается на сцене. Это означает, что мы можем перемещать его в любое место и вместе с ним будут двигаться его дочерние узлы.</p>
<p><strong>2.</strong> У нас есть 20 фоновых изображений, которые нужно расположить в ряд, чтобы заполнить задний план.</p>
<p><strong>3.</strong> Каждый дочерний узел унаследован от SKSpriteNode с добавлением соответствующего фонового изображения, загруженного из наших ресурсов. </p>
<p><strong>4.</strong> Смещение якорной точки каждого узла в его нижний центр позволяет легко расположить узлы друг над другом. </p>
<p><strong>5.</strong> Мы добавляем каждый дочерний узел в фоновой узел. </p>
<p><strong>6.</strong> Наконец, Мы возвращаем фоновый узел.</p>
<p>Теперь самое время поместить фоновый узел на сцену. В <strong>GameScene.swift</strong> добавьте следующие свойства:</p>
<div class="codebox">
<table>
<tr id="p872314">
<td class="code" id="p87231code4">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Layered Nodes</span>
<span style="color: #a61390;">let</span> backgroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
<span style="color: #a61390;">let</span> midgroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
<span style="color: #a61390;">let</span> foregroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
<span style="color: #a61390;">let</span> hudNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
 
<span style="color: #11740a; font-style: italic;">// To Accommodate iPhone 6</span>
<span style="color: #a61390;">let</span> scaleFactor<span style="color: #002200;">:</span> <span style="color: #400080;">CGFloat</span> <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span></pre>
</td>
</tr>
</table>
</div>
<p>Мы добавляем свойства для каждого из узлов, которые будет использоваться в игре. На данный момент нам нужен только фоновый узел, но не помешает заодно объявить и другие узлы.<br />
Мы также можем добавить свойство <strong>scaleFactor</strong>. Это нужно для того, чтобы графика правильно масштабировалась и позиционировалась на всех моделях iPhone.<br />
Чтобы добавить фон к сцене, вставьте следующий код в метод <strong>init(size:)</strong> класса <strong>GameScene.swift</strong> сразу после строки, которая устанавливает цвет фона:</p>
<div class="codebox">
<table>
<tr id="p872315">
<td class="code" id="p87231code5">
<pre class="swift" style="font-family:monospace;">scaleFactor <span style="color: #002200;">=</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">320.0</span>
 
<span style="color: #11740a; font-style: italic;">// Create the game nodes</span>
<span style="color: #11740a; font-style: italic;">// Background</span>
backgroundNode <span style="color: #002200;">=</span> createBackgroundNode<span style="color: #002200;">(</span><span style="color: #002200;">)</span>
addChild<span style="color: #002200;">(</span>backgroundNode<span style="color: #002200;">)</span></pre>
</td>
</tr>
</table>
</div>
<p>Графика рассчитана на стандартный экран, шириной в 320 точек, который имеют большинство моделей iPhone. Поэтому здесь используется масштабный коэффициент для адаптации под другие размеры экрана. Все, что нам нужно сделать после инициализации фонового узла, это добавить его в качестве дочернего к текущей сцене.<br />
Нажмите Build и Run, чтобы удостовериться в том, что наш фоновый узел отображается на сцене так, как показано ниже:</p>
<p><a href="/wp-content/uploads/2015/02/h10.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h10-220x383.png" width="220" height="383" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Примечание: несмотря на то, что в фоновый узел мы добавили 20 дочерних, вы увидите, что при запуске приложения на устройстве с 4- х дюймовым экраном, на сцене отображаются только девять узлов. А с экраном в 3,5 дюйма &#8211; всего восемь. Sprite Kit достаточно продвинут, и отображает только те узлы, которые должны быть видны в игре на данный момент.</p>
<h3>Добавление узла игрока (Node)</h3>
<p>Настало время выпустить на сцену нашего &#8220;Супер Прыгуна&#8221;. В <strong>GameScene.swift</strong>, добавьте следующий метод:</p>
<div class="codebox">
<table>
<tr id="p872316">
<td class="code" id="p87231code6">
<pre class="swift" style="font-family:monospace;"><span style="color: #a61390;">func</span> createPlayer<span style="color: #002200;">(</span><span style="color: #002200;">)</span> <span style="color: #002200;">-</span>&gt; <span style="color: #400080;">SKNode</span> <span style="color: #002200;">{</span>
  <span style="color: #a61390;">let</span> playerNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
  playerNode.position <span style="color: #002200;">=</span> <span style="color: #400080;">CGPoint</span><span style="color: #002200;">(</span>x<span style="color: #002200;">:</span> <span style="color: #a61390;">self</span>.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span>, y<span style="color: #002200;">:</span> <span style="color: #2400d9;">80.0</span><span style="color: #002200;">)</span>
 
  <span style="color: #a61390;">let</span> sprite <span style="color: #002200;">=</span> <span style="color: #400080;">SKSpriteNode</span><span style="color: #002200;">(</span>imageNamed<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">"Player"</span><span style="color: #002200;">)</span>
  playerNode.addChild<span style="color: #002200;">(</span>sprite<span style="color: #002200;">)</span>
 
  <span style="color: #a61390;">return</span> playerNode
<span style="color: #002200;">}</span></pre>
</td>
</tr>
</table>
</div>
<p>По такому же принципу, как мы добавляли фоновый узел, создается <strong>SKNode</strong> и в него в качестве дочернего добавляется узел <strong>SKSpriteNode</strong>, содержащий спрайт игрока. Расположим узел игрока таким образом, чтоб он был в центре экрана по горизонтали и чуть выше нижней части сцены. Перед тем как добавить узел игрока на сцену, нужно создать передний план. Как уже говорилось выше, узел переднего плана будет содержать игрока, звезды и платформы. Это означает то, что, когда мы будем его перемещать, то вместе с ним будут двигаться все игровые элементы.</p>
<p>Вставьте следующий код в метод init(size:) сразу после строки, которая добавляет <strong>backgroundNode</strong> на сцену:</p>
<div class="codebox">
<table>
<tr id="p872317">
<td class="code" id="p87231code7">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Foreground</span>
foregroundNode <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span>
addChild<span style="color: #002200;">(</span>foregroundNode<span style="color: #002200;">)</span></pre>
</td>
</tr>
</table>
</div>
<p>Теперь, когда для элементов геймплея есть узел переднего плана, мы можем добавить к нему узел игрока. В верхней части <strong>GameScene.swift</strong> объявите следующее свойство:</p>
<div class="codebox">
<table>
<tr id="p872318">
<td class="code" id="p87231code8">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Player</span>
<span style="color: #a61390;">let</span> player <span style="color: #002200;">=</span> <span style="color: #400080;">SKNode</span><span style="color: #002200;">(</span><span style="color: #002200;">)</span></pre>
</td>
</tr>
</table>
</div>
<p>Теперь поместите узел игрока на сцену, вставив следующий код в <strong>init(size:)</strong> сразу после строки, которая добавляет на сцену <strong>foregroundNode</strong>:</p>
<div class="codebox">
<table>
<tr id="p872319">
<td class="code" id="p87231code9">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add the player</span>
player <span style="color: #002200;">=</span> createPlayer<span style="color: #002200;">(</span><span style="color: #002200;">)</span>
foregroundNode.addChild<span style="color: #002200;">(</span>player<span style="color: #002200;">)</span></pre>
</td>
</tr>
</table>
</div>
<p>Постройте и запустите (Build и Run), чтобы увидеть Супер Прыгуна, который готов началу приключения:</p>
<p><a href="/wp-content/uploads/2015/02/h11.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h11-220x384.png" width="220" height="384" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<h3>Добавление гравитации и физического тела</h3>
<p>Наш герой выглядит слишком расслабленным. Было бы неплохо добавить физику в игру и посмотреть, что из этого получится. Начнём с того, что физика нашей игры не мыслима без гравитации. В <strong>GameScene.swift</strong>, добавьте следующую строку в <strong>init(size:)</strong> сразу после строки, которая устанавливает цвет фона:</p>
<div class="codebox">
<table>
<tr id="p8723110">
<td class="code" id="p87231code10">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Add some gravity</span>
physicsWorld.gravity <span style="color: #002200;">=</span> CGVector<span style="color: #002200;">(</span>dx<span style="color: #002200;">:</span> <span style="color: #2400d9;">0.0</span>, dy<span style="color: #002200;">:</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">)</span></pre>
</td>
</tr>
</table>
</div>
<p>Этим самым вы добавляете  вектор силы тяжести в физический мир, основываясь на сюжете игры. Сила тяжести не имеет проекции на ось X, она производит усилие, направленное вниз вдоль оси Y.<br />
Постройте и запустите, чтобы посмотреть, как гравитация будет влиять на узел игрока.</p>
<p><a href="/wp-content/uploads/2015/02/h12.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h12-220x384.png" width="220" height="384" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Хм &#8230; ничего не произошло. Почему гравитация Вашему герою нипочем? Попробуйте выяснить это сами, прежде чем посмотреть ответ.</p>
<p><strong>Ответ:</strong><br />
Сила, создаваемая гравитацией оказывает динамический эффект только на физические тела сцены. А такие объекты класса <strong>SKNode</strong>, как игрок узел нашего игрока, не имеют физических тел, заданных по умолчанию. Поэтому нам нужно задать физическое тело узлу игрока. В конце метода <strong>createPlayer</strong> добавьте следующий код перед оператором return:</p>
<div class="codebox">
<table>
<tr id="p8723111">
<td class="code" id="p87231code11">
<pre class="swift" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// 1</span>
playerNode.physicsBody <span style="color: #002200;">=</span> SKPhysicsBody<span style="color: #002200;">(</span>circleOfRadius<span style="color: #002200;">:</span> sprite.size.width <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span><span style="color: #002200;">)</span>
<span style="color: #11740a; font-style: italic;">// 2</span>
playerNode.physicsBody?.dynamic <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>
<span style="color: #11740a; font-style: italic;">// 3</span>
playerNode.physicsBody?.allowsRotation <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span>
<span style="color: #11740a; font-style: italic;">// 4</span>
playerNode.physicsBody?.restitution <span style="color: #002200;">=</span> <span style="color: #2400d9;">1.0</span>
playerNode.physicsBody?.friction <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span>
playerNode.physicsBody?.angularDamping <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span>
playerNode.physicsBody?.linearDamping <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span></pre>
</td>
</tr>
</table>
</div>
<p>Приведенный выше код задает физическое тело для узла игрока. Давайте рассмотрим его детально:</p>
<p><strong>1.</strong> Каждое физическое тело должно иметь форму, которую физический движок может использовать для обнаружения столкновений. Наиболее удобная форма тела для использования в обнаружении столкновений &#8211; круг (легко определить, когда круги перекрывают друг друга) и , к тому же, круг очень хорошо подходит для узла Вашего игрока. Его радиус составляет половину ширины спрайта.</p>
<p><strong>2.</strong> Физические тела подразделяются на статические и динамические. Динамические тела находятся под воздействием физического движка и поэтому зависят от сил и импульсов. Статические тела не попадают под это воздействие, но мы все равно можем использовать их для обнаружения столкновений. Например, такое статическое тело, как стена или твердая платформа никогда не будет двигаться, но в него могут врезаться другие объекты. Поскольку мы хотим, чтобы узел нашего игрока был под воздействием силы тяжести, установите его свойству dynamic значение true.</p>
<p><strong>3.</strong> Нужно, чтобы узел нашего игрока оставаться всегда в вертикальном положении, поэтому отключаем вращение узла.</p>
<p><strong>4.</strong> Поскольку мы самостоятельно обрабатываем столкновения в этой игре, то устанавливаем параметры физического тела узла игрока таким образом, чтобы не было ни трения ни демпфирования. Однако, мы устанавливаем его свойству restitution значение 1, чтобы физическое тело не потеряло часть своего импульса во время столкновений.</p>
<p>Постройте и запустите, чтобы увидеть как спрайт игрока падает в нижнюю часть экрана, поскольку гравитация безжалостно тянет его к центру Земли.</p>
<p><a href="/wp-content/uploads/2015/02/h13.png"><img itemprop="image" src="/wp-content/uploads/2015/02/h13-220x383.png" width="220" height="383" class="img-art" title="Делаем игру для iPhone в стиле Mega Jump   Часть 1" alt="Делаем игру для iPhone в стиле Mega Jump   Часть 1" /></a></p>
<p>Возможно, это звучит немного мелодраматически, но как наш герой собирается найти своё место в этом мире?</p>
<p><strong>Продолжение через неделю&#8230;.</strong><br />
Скачать <a class="frands" href="https://yadi.sk/d/CuKm-KRhedjgx">графические ресурсы для урока</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2015/02/16/delaem-igru-dlya-iphone-v-stile-mega-jump-chast-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как сделать иконку сайта для iPhone</title>
		<link>http://iphone-gps.ru/2015/02/03/kak-sdelat-ikonku-sajta-dlya-iphone/</link>
		<comments>http://iphone-gps.ru/2015/02/03/kak-sdelat-ikonku-sajta-dlya-iphone/#comments</comments>
		<pubDate>Tue, 03 Feb 2015 11:08:10 +0000</pubDate>
		<dc:creator>Vadim Nefedov</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=38560</guid>
		<description><![CDATA[
Количество устройств работающий на операционной системе iOS с каждым годом растет. Это статья для web-мастеров, которые оптимизируют свои сайты для просмотров с iPhone и iPad. Для того, чтобы при добавлении в закладки браузера Safari или при добавлении на рабочий стол iPhone показывалась нужная иконка сайта, необходимо специально создать изображений. Иконка favicon в данном случае не [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2015/02/zak0.jpg"  width="400" height="270" class="img-art" title="Как сделать иконку сайта для iPhone" alt="Как сделать иконку сайта для iPhone" /></p>
<p>Количество устройств работающий на операционной системе iOS с каждым годом растет. Это статья для web-мастеров, которые оптимизируют свои сайты для просмотров с iPhone и iPad. Для того, чтобы при добавлении в закладки браузера Safari или при добавлении на рабочий стол iPhone показывалась нужная иконка сайта, необходимо специально создать изображений. Иконка favicon в данном случае не работает.<br />
Для сайтов, где нет такой иконки, в <a href="/2013/11/20/vizualnye-zakladki-safari-v-ios-7/">закладках Safari</a> показывается серая заглушка, а на рабочем столе создается иконка на основе скриншота первой страницы. Это не очень красиво. Но достаточно потратить всего несколько минут, чтобы сделать свою иконку сайта для iPhone&#8230;</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/zak2.jpg"  width="400" height="270" class="img-art" title="Как сделать иконку сайта для iPhone" alt="Как сделать иконку сайта для iPhone" /></p>
<h3>Как создать иконку сайта для iPhone</h3>
<p>1. Нужно создать изображение в формате PNG размером 152&#215;152px в любом графическом редакторе. Если вы работаете в Photoshop, то это формат PNG 24. Можно даже задать прозрачность. </p>
<p>2. Сохранить файл под названием &#8220;<strong>apple-touch-icon.png</strong>&#8220;. </p>
<p>3. Загрузить получившийся файл по FTP на сервер, в корневую папку сайта. Например <a target="_blank" href="/apple-touch-icon.png">http://iphone-gps.ru/apple-touch-icon.png</a>.</p>
<p>Теперь при добавлении закладки на ваш сайт, в Safari появится созданная вами иконка. А если вы выберите &#8220;Добавить в Домой&#8221;, то и на рабочем столе.</p>
<p><img itemprop="image" src="/wp-content/uploads/2015/02/zak1.jpg"  width="220" height="391" class="img-art" title="Как сделать иконку сайта для iPhone" alt="Как сделать иконку сайта для iPhone" /></p>
<h3>Сразу отвечу на возможные вопросы.</h3>
<p><strong>Нужно ли что-то прописывать в самом HTML документе?</strong><br />
Нет, ничего специально прописывать в mete не нужно. Браузеры мобильный устройств сами ищут этот файл на вашем сайте. Более того, если такого файла там нет, то сервер выдает в ответ 404 ошибку. Посмотрите в логи на сервере, там много таких запросов. Кроме того &#8211; эти файлы &#8220;ищутся&#8221; не только в момент добавления сайта на домашний экран, а при каждом посещении!<br />
И, вы наверно удивитесь, но Android устройства тоже используют значки apple-touch-icon.png при добавлении закладки сайта на рабочий стол  <img itemprop="image" src='/wp-includes/images/smilies/icon_smile.gif' alt="Как сделать иконку сайта для iPhone" class='wp-smiley' title="Как сделать иконку сайта для iPhone" /> .</p>
<p><strong>А как же Retina, нужно делать несколько изображений под разное разрешение?</strong><br />
Раньше нужно было делать несколько картинок, сейчас достаточно одной большой (152&#215;152px). В принципе, в Apple регулярно меняют разрешения экранов и стандарты для разработчиков. Вполне вероятно, что когда вы будете читать эту статью, что-то уже поменяется. Но, самый актуальный размер всегда можно узнать по ссылке <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL3d3dy5hcHBsZS5jb20vYXBwbGUtdG91Y2gtaWNvbi5wbmc=/">http://www.apple.com/apple-touch-icon.png</a>. Это самый правильный формат иконки <img itemprop="image" src='/wp-includes/images/smilies/icon_smile.gif' alt="Как сделать иконку сайта для iPhone" class='wp-smiley' title="Как сделать иконку сайта для iPhone" /> . </p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2015/02/03/kak-sdelat-ikonku-sajta-dlya-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Введение в UICollectionView или как выводить объекты сеткой &#8211; Видеоурок</title>
		<link>http://iphone-gps.ru/2014/04/16/vvedenie-v-uicollectionview-ili-kak-vyvodit-obekty-setkoj-videourok/</link>
		<comments>http://iphone-gps.ru/2014/04/16/vvedenie-v-uicollectionview-ili-kak-vyvodit-obekty-setkoj-videourok/#comments</comments>
		<pubDate>Wed, 16 Apr 2014 18:06:06 +0000</pubDate>
		<dc:creator>Луцкий Михаил</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>
		<category><![CDATA[программирование для iOS]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=31670</guid>
		<description><![CDATA[
Всем привет! Я продолжаю свой курс уроков по программированию под iOS на Objective-C языке. Как вы помните, в третьем уроке мы с вами писали программу «Книга рецептов», при этом мы использовали UITableView. В этом уроке будет рассказано, как использовать для вывода элементов из массива UICollectionView.
    
UICollectionView относительно молодой элемент в Objective-C. Он [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2014/04/pro01.jpg"  width="400" height="270" class="img-art" title="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" alt="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" /></p>
<p>Всем привет! Я продолжаю свой курс уроков по программированию под iOS на Objective-C языке. Как вы помните, в третьем уроке мы с вами писали программу «Книга рецептов», при этом мы использовали UITableView. В этом уроке будет рассказано, как использовать для вывода элементов из массива <strong>UICollectionView</strong>.</p>
<div class=lado><a href="/wp-content/uploads/2014/04/simulator-collection.jpg" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2014/04/simulator-collection-220x356.jpg"  width="220" height="356" class="img-art" title="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" alt="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" /> </a><a href="/wp-content/uploads/2014/04/soryboard-s-collection-view.jpg" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2014/04/soryboard-s-collection-view-220x293.jpg"  width="220" height="293" class="img-art" title="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" alt="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" /> </a></div>
<p><span class=blue><strong>UICollectionView</strong></span> относительно молодой элемент в Objective-C. Он пришел вместе с iOS 6 в позопрошлом году. Чем же он отличается от UITableView? Главное их отличие в том, что UICollectionView позволяет выводить объекты при помощи сетки. Например, он используется в стандартном приложении «Фото» в iOS, то есть
<div class="quote_art">с его помощью фотографии выводятся по сетке, а не списком сверху вниз.</div>
<p><img itemprop="image" src="/wp-content/uploads/2014/04/code-uicollection.jpg" width="613" height="422" class="img-art" title="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" alt="Введение в UICollectionView или как выводить объекты сеткой   Видеоурок" /></p>
<p>Нашу программу мы будем строить на основе контролера UICollectionView. При помощи этого элемента мы будем выводить фотографии наших рецептов через сетку. В этом уроке мы не будем углубляться в повторное написание книги рецептов, но если вы хорошо усвоили наш третий урок, то для вас не составит труда переписать приложение под данный тип вывода, ибо настоящий программист должен легко осваивать логику программы. Отметим лишь, что сам принцип кодового построения UITableView и UICollectionView очень похожи.</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/1fRp4MbCIK8?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>Обратите внимание, что в ячейку UICollectionView можно вставить не только картинку, но и, например, UILabel, UITextField и т.д. Также стоит отметить, что можно использовать разные типы ячеек в контролере и назначать им разные размеры.</p>
<div class="sor" style="margin-bottom: 50px"><a rel="nofollow" href="/ext/aHR0cDovL2xvdXRza2l5LnJ1L2xzL0xlc3Nvbl81LnppcA==/">Скачать исходники проекта</a></div>
<div class="otbivka"></div>
<div class="otbivka"></div>
<p>Чтобы ничего не пропустить, подписывайтесь на мой <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdXNlci9hcHBsZWpvdXJuYWxjb3VyY2U=/">канал на YouTube</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2014/04/16/vvedenie-v-uicollectionview-ili-kak-vyvodit-obekty-setkoj-videourok/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Добавляем комментарии и «Pull to Refresh» к парсеру новостей &#8211; Видеоурок</title>
		<link>http://iphone-gps.ru/2014/04/11/dobavlyaem-kommentarii-i-pull-to-refresh-k-parseru-novostej-videourok/</link>
		<comments>http://iphone-gps.ru/2014/04/11/dobavlyaem-kommentarii-i-pull-to-refresh-k-parseru-novostej-videourok/#comments</comments>
		<pubDate>Fri, 11 Apr 2014 06:11:59 +0000</pubDate>
		<dc:creator>Луцкий Михаил</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>
		<category><![CDATA[программирование ios]]></category>
		<category><![CDATA[программирование для iPhone]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=31524</guid>
		<description><![CDATA[
Сегодня мы продолжаем наш четвертый урок, в котором начали писать парсер новостей из сайта-блога. В этой части урока будет рассказано, как сделать вывод комментариев к каждой новости, а также мы напишем функцию Pull to Refresh для таблицы с записями.

Итак, в основе движка Loutskiy CMS есть функция комментариев к постам, которые мы будем выводить и в [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2014/04/ac00.jpg"  width="400" height="270" class="img-art" title="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" alt="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" /></p>
<p>Сегодня мы продолжаем наш четвертый урок, в котором начали писать парсер новостей из сайта-блога. В этой части урока будет рассказано, как сделать вывод комментариев к каждой новости, а также мы напишем функцию Pull to Refresh для таблицы с записями.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/uroki-razrabotki-pod-ios-2.jpg" alt="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" width="600" height="239" title="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" /></p>
<p>Итак, в основе движка Loutskiy CMS есть функция комментариев к постам, которые мы будем выводить и в нашем приложении. Их показ будет осуществляться на отдельном ViewController, а вывод будет происходить в таблицу UITableView.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/uroki-razrabotki-pod-ios-4.jpg" alt="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" width="529" height="111" title="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" /></p>
<p>Сами комментарии мы будем получать из базы данных MySQL в JSON-формате. Для этого, из класса DetailViewController мы будем передавать уникальный номер ID страницы-поста в класс CommentsViewController. Это нужно, чтобы сделать запрос к API скрипту, чтобы тот вывел именно те комментарии, которые относятся к этой записи.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/uroki-razrabotki-pod-ios-33.jpg" alt="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" width="361" height="648" title="Добавляем комментарии и «Pull to Refresh» к парсеру новостей   Видеоурок" /></p>
<p>Разработка под iOSВ блоке комментария мы будем выводить имя пользователя, дату и текст. Так как мы делаем статическую высоту ячейки в таблице, а текст комментария может быть слишком большим, мы будем выводить его через TextView. То есть, мы сможем внутри блока с комментарием прокручивать его текст. А получение комментария будет завязано на том же классе JSONLoader.</p>
<p>Теперь нам осталось реализовать только функцию Pull to refresh, которая позволяет делать обновление данных в таблице, путем оттягивающего свайпа сверху вниз. Данный формат очень удобен, для его активации добавьте следующий код в функцию viewDidLoad:</p>
<blockquote><p>UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];<br />
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];<br />
[self.tableView addSubview:refreshControl];</p></blockquote>
<p>ВИДЕО</p>
<p><iframe width="400" height="300" src="//www.youtube.com/embed/wam1f4STWz0" frameborder="0" allowfullscreen></iframe></p>
<div class="sor" style="margin-bottom: 50px"><a rel="nofollow" href="/ext/aHR0cDovL2FwcGxlLmxvdXRza2l5LnJ1L2NvbnRlbnQvZmlsZXMvTGVzc29uXzRfMi56aXA=/">Скачать исходники проекта</a></div>
<div class="otbivka"></div>
<div class="otbivka"></div>
<p>Чтобы ничего не пропустить, подписывайтесь на мой <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdXNlci9hcHBsZWpvdXJuYWxjb3VyY2U=/">канал на YouTube</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2014/04/11/dobavlyaem-kommentarii-i-pull-to-refresh-k-parseru-novostej-videourok/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Создаем «парсер» новостей из сайта-блога для iPhone &#8211; Видеоурок</title>
		<link>http://iphone-gps.ru/2014/04/08/sozdaem-parser-novostej-iz-sajta-bloga-dlya-iphone-videourok/</link>
		<comments>http://iphone-gps.ru/2014/04/08/sozdaem-parser-novostej-iz-sajta-bloga-dlya-iphone-videourok/#comments</comments>
		<pubDate>Tue, 08 Apr 2014 16:39:38 +0000</pubDate>
		<dc:creator>Луцкий Михаил</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>
		<category><![CDATA[программирование для iOS]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=31461</guid>
		<description><![CDATA[
Как вы помните, в прошлом уроке мы создавали программу «Книга рецептов» для iOS. Главным минусом той программы было то, что все данные были статичными, а для того, чтобы их обновить нужно было дописывать код приложения и отправлять его на повторную модерацию в AppStore. В сегодняшнем уроке будет рассказано, как эту проблему можно решить. Сразу стоит [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2014/04/pro0.jpg"  width="400" height="270" class="img-art" title="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" alt="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" /></p>
<p>Как вы помните, в прошлом уроке мы создавали программу «Книга рецептов» для iOS. Главным минусом той программы было то, что все данные были статичными, а для того, чтобы их обновить нужно было дописывать код приложения и отправлять его на повторную модерацию в AppStore. В сегодняшнем уроке будет рассказано, как эту проблему можно решить. Сразу стоит отметить, что для этого урока у вас должен быть веб-сервер, имеющий выход в интернет. Все примеры в данной серии уроков будут написаны на языке PHP, поэтому ваш сервер должен базироваться на Apache или ngnix.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/viewcontroller-file.jpg" alt="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" width="600" height="272" title="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" /></p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/vuvod-v-tablici.jpg" alt="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" width="600" height="396" title="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" /></p>
<div class="quote_art">Основная цель приложения, которое мы напишем – выводить новости сайта из таблицы базы данных MySQL.</div>
<p>Большинство новостных сайтов используют SQL-БД, но стоит отметить, что наше приложение не будет делать прямой SQL-запрос к таблице, потому как нет соответствующего фреймворка в Xcode. Зато Apple дала возможность формировать массивы из JSON-файла. Поэтому мы напишем собственное API, которое будет формировать данный файл. А именно, мы сделаем PHP-скрипт, который будет делать SQL-запрос, а потом автоматически генерировать динамический файл с JSON-структурой. Конечно же, можно использовать и XML формат, но практика показывает, что тогда программа будет гораздо медленнее обрабатывать результат.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/detailviewcontroller.jpg" alt="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" width="600" height="169" title="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" /></p>
<p>Как вы наверняка знаете, все новостные сайты имеют свою CMS (система управления контентом), при этом, многие используют так называемые «открытые» CMS — WordPress, Joomla, Drupal и т.д. Так как партнером нашего канала является группа LWTS, то мы разберем создание парсера новостей на основе их CMS, которую вы можете скачать по этой ссылке &#8211; <a rel="nofollow" target="_blank" href="/ext/aHR0cDovL2x3dHMucnUvcHJvZHVjdHMvMQ==/">http://loutskiy.ru/products/1</a>. Впрочем, для веб-разработчика не составит большого труда преобразовать данный скрипт под другие движки.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/appcoda-v-simulatore.jpg" alt="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" width="434" height="704" title="Создаем «парсер» новостей из сайта блога для iPhone   Видеоурок" /></p>
<p>Итак, наша программа будет получать и выводить новости списком, через таблицу UITableView, а также по нажатию на ячейку открывать страницу с полным текстом статьи. Если со списком новостей все понятно, то полный текст новости будет работать следующим образом: будет открываться страница с UIWebView, которая, в свою очередь, будет подгружать динамичную страницу PHP с текстом новости.</p>
<p>Итак, чтобы приступить к изучению урока, вам нужно скачать нашу библиотеку, состоящую из Objective-C класса и PHP файлов, которые генерируют JSON-страницу и файл с текстом новости.</p>
<p>ВИДЕО</p>
<p><iframe width="400" height="300" src="//www.youtube.com/embed/oT1q_VsZR04" frameborder="0" allowfullscreen></iframe></p>
<p>В следующем уроке мы разберем, как организовать вывод комментариев к статьям в приложении.</p>
<div class="sor" style="margin-bottom: 20px"><a rel="nofollow" href="/ext/aHR0cDovL2FwcGxlLmxvdXRza2l5LnJ1L2NvbnRlbnQvZmlsZXMvcGFyc2VyLnppcA==/">Скачать файлы парсера и класса</a></div>
<div class="sor" style="margin-bottom: 50px"><a rel="nofollow" href="/ext/aHR0cDovL2FwcGxlLmxvdXRza2l5LnJ1L2NvbnRlbnQvZmlsZXMvTGVzc29uXzQuemlw/">Скачать исходники проекта</a></div>
<div class="otbivka"></div>
<div class="otbivka"></div>
<p>Чтобы ничего не пропустить, подписывайтесь на мой <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdXNlci9hcHBsZWpvdXJuYWxjb3VyY2U=/">канал на YouTube</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2014/04/08/sozdaem-parser-novostej-iz-sajta-bloga-dlya-iphone-videourok/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Заканчиваем создание «Книги рецептов» для iOS &#8211; Видеоурок</title>
		<link>http://iphone-gps.ru/2014/04/03/zakanchivaem-sozdanie-knigi-receptov-dlya-ios-videourok/</link>
		<comments>http://iphone-gps.ru/2014/04/03/zakanchivaem-sozdanie-knigi-receptov-dlya-ios-videourok/#comments</comments>
		<pubDate>Thu, 03 Apr 2014 19:03:11 +0000</pubDate>
		<dc:creator>Луцкий Михаил</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>
		<category><![CDATA[программирование ios]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=31349</guid>
		<description><![CDATA[
Сегодня четверг, и как водится, мы публикуем новый материал по программированию на iOS. Как вы помните, в предыдущих двух частях третьего урока, мы создавали приложение «Книга рецептов» для iOS. В сегодняшнем уроке мы закончим разработку данной программы и исправим все оставшиеся недочеты. В этой серии мы сделаем подробное описание для каждого из рецептов, присвоим уникальное изображение [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2014/04/les00.jpg"  width="400" height="270" class="img-art" title="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" alt="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" /></p>
<p>Сегодня четверг, и как водится, мы публикуем новый материал по программированию на iOS. Как вы помните, в предыдущих двух частях третьего урока, мы создавали приложение «Книга рецептов» для iOS. В сегодняшнем уроке мы закончим разработку данной программы и исправим все оставшиеся недочеты. В этой серии мы сделаем подробное описание для каждого из рецептов, присвоим уникальное изображение для каждого из блюд и разберем небольшую кастомизацию Navigation Bar Controller.</p>
<p><img itemprop="image" src="/wp-content/uploads/2014/04/storyboard-final1.jpg" width="600" height="602" class="img-art" title="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" alt="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" /></p>
<p>Итак, основной сегодняшней нашей задачей будет добавление полного описания для каждого рецепта в программе. Для этого мы будем передавать в новый класс номер-идентификатор нажатой ячейки в таблице. Так как нам известно какому рецепту принадлежит какой номер, то мы в классе <span class=blue><strong>DetailViewController</strong></span> применим конструкцию условия <strong>if else</strong>. То есть мы будем сравнивать номер идентификатора с числами, и в случае, если результат будет положительным (true), то программа выведет нужное описание к блюду.</p>
<p><img itemprop="image" src="/wp-content/uploads/2014/04/konstrukciya-if-else1.jpg" width="600" height="310" class="img-art" title="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" alt="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" /></p>
<p>Следующим шагом будет добавление уникальных изображений к нашим рецептам. Определять какую картинку нужно вывести программа будет при помощи той же конструкции<strong>if else</strong>. А само изображение в рецептах выводить будем при помощи функции <span class=blue><strong>UIImageView</strong></span>. Располагать все элементы по своим местам будем в Storyboard.</p>
<p><img itemprop="image" src="/wp-content/uploads/2014/04/appdelegate-custom-bar.jpg" width="600" height="199" class="img-art" title="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" alt="Заканчиваем создание «Книги рецептов» для iOS   Видеоурок" /></p>
<p>Ну и наконец, мы расскажем вам как можно легко кастомизировать Navigation Bar Controller, а именно, как изменить начертание шрифта, кегль, цвет, фон и тд. Это делается достаточно просто, путем добавления нескольких строчек кода в файл <span class=blue><strong>AppDelegate.m</strong></span>.</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/tMdFAcToIHo?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>Итак, в третьем уроке мы создали полноценное приложение, но как вы заметили, все рецепты хранятся в статическом виде внутри кода — то есть, если вы захотите добавить новый рецепт, то нужно будет выпускать обновление приложения. Поэтому в следующем уроке я расскажу, как получать данные из сети Интернет.</p>
<div class="sor" style="margin-bottom: 50px"><a rel="nofollow" href="/ext/aHR0cDovL2xvdXRza2l5LnJ1L2xzL2xlc3NvbjNfMy56aXA=/">Скачать исходники проекта</a></div>
<div class=otbivka></div>
<div class=otbivka></div>
<p>Чтобы ничего не пропустить, подписывайтесь на мой <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdXNlci9hcHBsZWpvdXJuYWxjb3VyY2U=/">канал на YouTube</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2014/04/03/zakanchivaem-sozdanie-knigi-receptov-dlya-ios-videourok/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Продолжаем создавать нашу книгу рецептов &#8211; Видеоурок</title>
		<link>http://iphone-gps.ru/2014/04/01/prodolzhaem-sozdavat-nashu-knigu-receptov-videourok/</link>
		<comments>http://iphone-gps.ru/2014/04/01/prodolzhaem-sozdavat-nashu-knigu-receptov-videourok/#comments</comments>
		<pubDate>Tue, 01 Apr 2014 15:37:03 +0000</pubDate>
		<dc:creator>Луцкий Михаил</dc:creator>
				<category><![CDATA[Разработка программ для iPhone]]></category>
		<category><![CDATA[iOS программирование]]></category>

		<guid isPermaLink="false">http://iphone-gps.ru/?p=31287</guid>
		<description><![CDATA[
Я продолжаю свой курс уроков по программированию на Objective-C под iOS, и сегодня вас ждет вторая часть третьего урока, в котором мы начали создавать приложение «Книга рецептов» для iPhone.
  
Напомним, что в предыдущей части было рассказано, как выводить информацию из массива в таблицу, через стандартный объект UITableView. Разобрали создание статического одномерного массива NSArray, а [...]]]></description>
			<content:encoded><![CDATA[<p><img itemprop="image" src="/wp-content/uploads/2014/04/cod00.jpg"  width="400" height="270" class="img-art" title="Продолжаем создавать нашу книгу рецептов   Видеоурок" alt="Продолжаем создавать нашу книгу рецептов   Видеоурок" /></p>
<p>Я продолжаю свой курс уроков по программированию на Objective-C под iOS, и сегодня вас ждет вторая часть третьего урока, в котором мы начали создавать приложение «Книга рецептов» для iPhone.</p>
<p><a href="/wp-content/uploads/2014/04/storyboard-design1.jpg" rel="lightbox" > <img itemprop="image" src="/wp-content/uploads/2014/04/storyboard-design1-400x379.jpg"  width="400" height="379" class="img-art" title="Продолжаем создавать нашу книгу рецептов   Видеоурок" alt="Продолжаем создавать нашу книгу рецептов   Видеоурок" /> </a></p>
<p>Напомним, что в предыдущей части было рассказано, как выводить информацию из массива в таблицу, через стандартный объект UITableView. Разобрали создание статического одномерного массива NSArray, а также рассмотрели контейнер Navigation Bar Controller.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/Снимок-экрана-2014-04-01-в-18.29.36.png" alt="Продолжаем создавать нашу книгу рецептов   Видеоурок" width="692" height="262" title="Продолжаем создавать нашу книгу рецептов   Видеоурок" /></p>
<p>В сегодняшней части мы уделим внимание страницам с описанием рецептов, создадим вкладку через <span class=blue><strong>TabBar Controller</strong></span>, в которой разместим статичную HTML-страницу, при помощи объекта <span class=blue><strong>UIWebView</strong></span>, а также сделаем поиск в нашей таблице с рецептами по массиву с данными.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/Снимок-экрана-2014-04-01-в-18.30.10.png" alt="Продолжаем создавать нашу книгу рецептов   Видеоурок" width="630" height="174" title="Продолжаем создавать нашу книгу рецептов   Видеоурок" /></p>
<p>Итак, основной акцент мы сделаем на возможность выбора строки в <span class=blue><strong>UITableView</strong></span>, чтобы можно было перейти на новую страницу, на которой будет находиться уникальный рецепт для каждого из блюд. В этой части урока мы сделаем так, чтобы на странице с описанием показывалось только имя рецепта, а в третьей части будет рассказано, как добавить туда подробное описание приготовления блюд.</p>
<p><img itemprop="image" class="img-art" src="/wp-content/uploads/2014/04/Снимок-экрана-2014-04-01-в-18.30.36.png" alt="Продолжаем создавать нашу книгу рецептов   Видеоурок" width="636" height="134" title="Продолжаем создавать нашу книгу рецептов   Видеоурок" /></p>
<p>Затем будет рассказано, как можно пользоваться объектом <span class=blue><strong>UIWebView</strong></span>, который позволяет подгружать в себя HTML-страницу с информацией. Сам UIWebView использует движок Apple WebKit, что позволяет использовать такие технологии, как HTML 5 и ССS 3. Если вы хотите, чтобы вместо HTML страницы открывался сайт, то вставьте следующий код:</p>
<blockquote><p>NSURL* url = [NSURL URLWithString:@"http://loutskiy.ru"]; //Вместо loutskiy.ru указывайте свой сайт  или страницу на сайте</p></blockquote>
<p>Вместо:</p>
<blockquote><p>NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@»about.html» ofType:nil]];</p></blockquote>
<p>Также в этом уроке будет рассказано про то, как сделать стандартный поиск по таблице, через объект Search Display Controller. Данная функция будет искать элементы массива по совпадению символов и выводить результаты поиска в таблицу.</p>
<p>ВИДЕО</p>
<p><iframe width="400" height="300" src="//www.youtube.com/embed/_YVBszGux5g" frameborder="0" allowfullscreen></iframe></p>
<div class="sor" style="margin-bottom: 50px"><a rel="nofollow" href="/ext/aHR0cDovL2xvdXRza2l5LnJ1L2xzL2xlc3NvbjNfMS56aXA=/">Скачать исходники проекта</a></div>
<div class=otbivka></div>
<p>Чтобы ничего не пропустить, подписывайтесь на мой <a rel="nofollow" target="_blank" href="/ext/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdXNlci9hcHBsZWpvdXJuYWxjb3VyY2U=/">канал на YouTube</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://iphone-gps.ru/2014/04/01/prodolzhaem-sozdavat-nashu-knigu-receptov-videourok/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
