Во последниот дел од овој серијал ќе ја дотераме нашата игра. Прво ќе напишеме неколку линии за ‘вртење’ на топчето. Потоа, ќе додадеме SpriteFont кој што се користи за пишување текст за да ги нацртаме индикаторите за поени. Следно, ќе ставиме една линија на средина за да ја поделиме површината за играње на два дела, па ќе ставиме звуци за колизии и на крај ќе додадеме Splash Screen и логоа.

Вртење на Топчето

Отворете ја Game1.cs класата и додадете нова константа:

const float SPIN = 2.5f;

 

Следно, во Update методот веднаш после линиите за движење со Touch, додадете ги следните if-тестови:

player1.Move(player1TouchVelocity);
player2.Move(player2TouchVelocity);

if (player1TouchVelocity.Y > 0f)
{
	player1Velocity = player1TouchVelocity;
}
if (player2TouchVelocity.Y > 0f)
{
	player2Velocity = player2TouchVelocity;
}

if (player1Velocity.Y != 0)
{
	player1Velocity.Normalize();
}
if(player2Velocity.Y != 0)
{
	player2Velocity.Normalize();
}

 

Во нашиот случај, доколку играчите користат touch, ќе забележите дека брзината на играчите не е дефинирана, туку во зависност од брзината на влечење, се мрда и играчот. Додека, со тастатура, има една и единствена брзина дефинирана во константата KEYBOARD_PADDLE_SPEED. За да не се дозволи играчите на touch да можат повеќе или помалку да го ‘вртат’ топчето, брзините ќе ги нормализираме за да се добие насоката на движење на играчот.

Значи прво проверуваме дали постои инпут со touch, доколку постои ја зачувуваме таа вредност и потоа ја нормализираме.

Во истиот Update метод, во if-тестовите кои што проверуваат дали има колизија помеѓу играчите и топчето, додадете ги линиите како што е покажано подолу:

if (GameObject.CheckPaddleBallCollision(player1, ball))
{
	ball.Velocity.X = Math.Abs(ball.Velocity.X);
	ball.Velocity += player1Velocity * SPIN;
}

if (GameObject.CheckPaddleBallCollision(player2, ball))
{
	ball.Velocity.X = -Math.Abs(ball.Velocity.X);
	ball.Velocity += player2Velocity*SPIN;
}

 

Откако ја менуваме насоката на топчето, на брзината ја додаваме насоката на играчот помножена со константата за ‘вртење’ на топчето.

Притиснете F5 или Debug –> Start Debugging и тестирајте. Ќе забележите дека во зависност од тоа како го удирате топчето, тоа или забрзува или забавува.

Слободно можете да ги менувате константите во зависност од тоа дали сакате топчето да има поголема почетна брзина, да има поголемо вртење и слично.

Индикатори за Поени

Најпрво превземете и инсталирајте го 8Bit Wonder фонтот од тука.

Сега ќе треба да се повторат чекорите за внесување надворешни фајлови од вториот дел за да ставиме SpriteFont во нашата игра.

Пуштете го Visual Studio 2012 Express for Windows Phone и отворете го PongContent проектот. Притиснете десен-клик на Content проектот па Add –> New Item.

 

Одберете лево Visual C#, потоа одберете SpriteFont, крстете го RetroFont и притиснете Add.

Откако ќе притиснете Add, ќе ви се отвори RetroFont.spritefont фајлот во Visual Studio каде што може да ги променувате неговите параметри како име на фонт, големина, стил итн.

Направете ги следните промени:

<FontName>8Bit Wonder</FontName>

<Size>32</Size>

<Style>Bold</Style>

Откако ќе ги промените вредностите, притиснете Build –> Build Solution. Откако ќе се комплетира компајлирањето, исклучете го Visual Studio 2012 Express for Windows Phone.

Вратете се на PongClone проектот, притиснете десен-клик на ‘Content’ фолдерот, Add –> Existing item.

Навигирајте во:

…\Documents\Visual Studio 2012\Projects\PongContent\PongContent\PongContent\bin\Windows Phone\Debug\Content

Одберете го RetroFont.xnb и притиснете Add.

Сега, селектирајте го RetroFont и променете го Build Action од None во Content.

Отворете ја Player.cs класата и додадете ја следната променлива:

public int Score;

Отворете ја Game1.cs класата, декларирајте нова SpriteFont променлива по декларацијата на играчите и топчето:

Player player1;
Player player2;
Ball ball;

SpriteFont retroFont;

Во LoadContent методот додадете ја следната линија за вчитување на SpriteFont-от:

retroFont = Content.Load<SpriteFont>("RetroFont");

Во Update методот, сменете ги if-тестовите за повторно лансирање на топчето во следното:

if (ball.Position.X + ball.Texture.Width < 0)
{
	ball.Launch(BALL_START_SPEED);
	player2.Score++;
}

if (ball.Position.X > ScreenWidth)
{
	ball.Launch(BALL_START_SPEED);
	player1.Score++;
}

Значи, доколку топчето излезе од левата страна, вториот играч добива еден поен. Доколку топчето излезе од десната страна, првиот играч добива еден поен.

Во Draw методот, помеѓу _spriteBatch.Begin() и player1.Draw(_spriteBatch) додадете ја линијата за цртање на поените:

_spriteBatch.Begin();
_spriteBatch.DrawString(retroFont, player1.Score + "        " + player2.Score,new Vector2(ScreenWidth / 2 -retroFont.MeasureString(player1.Score + "        " + player2.Score).X / 2,0), Color.Cyan);
player1.Draw(_spriteBatch);

DrawString методот го прима SpriteFont објектот, текстот што сакаме да го напишеме, позицијата на текстот (во нашиот случај во зависност од должината на string-от позицијата ќе се променува, а должината на string-от ја мериме со MeasureString методот), и бојата на текстот.

Притиснете F5 или Debug –> Start Debugging за да тестирате. Ќе забележите на горната страна нацртани се индикаторите за поени на играчите.

Сега може да ја додадеме и линијата на средина за да ја поделиме површината на два дела.

Во Game1.cs веднаш после декларацијата на SpriteFont retroFont; додадете една текстура која што ќе ја нацртаме на средина:

SpriteFont retroFont;
Texture2D middleTexture;

Во LoadContent методот додадете ја следната линија:

middleTexture = Content.Load<Texture2D>("Middle");

Во Draw методот, после _spriteBatch.Begin() додадете ја линијата за цртање на текстурата:

_spriteBatch.Draw(middleTexture,new Rectangle(ScreenWidth / 2 - middleTexture.Width / 2, 0, middleTexture.Width,ScreenHeight), null, Color.White);

Забележувате дека сега користиме друг overload на Draw методот. Бидејќи Middle текстурата ни е 4 пиксели широка и 1 пиксел висока (4×1), со помош на Rectangle ќе ја рашириме текстурата од горе до долу. Кога се користи Rectangle за цртање на објекти на екран, без разлика колкава е големината на текстурата, таа се раширува за да ја опфати големината на Rectangle објектот.

Притиснете F5 или Debug –> Start Debugging за да ја видите новата текстура.

Звучни Ефекти

Бидејќи звуците веќе ги ставивме во нашиот проект во вториот дел кога ги префрливме сите екстерни фајлови, сега нема потреба од повторно компајлирање.

За менаџирање на звучните ефекти ќе креираме нова статична класа, ‘SoundManager’.

Притиснете десен-клик на ‘Classes’, Add –> Class… , крстете ја класата ‘SoundManager’ (без наводници) и притиснете Add.

Преправете ја класата во следното:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;

namespace PongClone
{
    public static class SoundManager
    {
        public static SoundEffect BallWallCollisionSoundEffect;
        public static SoundEffect PaddleBallCollisionSoundEffect;

        public static void LoadSounds(ContentManager Content)
        {
            BallWallCollisionSoundEffect = Content.Load<SoundEffect>("BallWallCollision");
            PaddleBallCollisionSoundEffect = Content.Load<SoundEffect>("PaddleBallCollision");
        }
    }
}

Забележувате дека имаме две променливи кои што ќе ги чуваат звуците за колизија помеѓу ‘ѕидовите’ и топчето, и помеѓу играчите и топчето. Потоа имаме еден статичен метод кој што прима ContentManager објект кој што се користи за вчитување на звуците.

Отворете ја Game1.cs класата и во LoadContent додадете ја следната линија:

SoundManager.LoadSounds(Content);

Потоа, во Update методот, преправете ги if-тестовите за колизија помеѓу играчите и топчето во следното:

if (GameObject.CheckPaddleBallCollision(player1, ball))
{
	ball.Velocity.X = Math.Abs(ball.Velocity.X);
	ball.Velocity += player1Velocity * SPIN;
	SoundManager.PaddleBallCollisionSoundEffect.Play();
}

if (GameObject.CheckPaddleBallCollision(player2, ball))
{
	ball.Velocity.X = -Math.Abs(ball.Velocity.X);
	ball.Velocity += player2Velocity*SPIN;
	SoundManager.PaddleBallCollisionSoundEffect.Play();
}

Значи, штом има колизија помеѓу некој од играчите и топчето, го активираме звукот.

Отворете ја Ball.cs класата и преправете го CheckWallCollision методот во следното:

public void CheckWallCollision()
{
	if (Position.Y < 0)
	{
		Position.Y = 0;
		Velocity.Y *= -1;
		SoundManager.BallWallCollisionSoundEffect.Play();
	}
	if (Position.Y + Texture.Height > Game1.ScreenHeight)
	{
		Position.Y = Game1.ScreenHeight - Texture.Height;
		Velocity.Y *= -1;
		SoundManager.BallWallCollisionSoundEffect.Play();
	}
}

Исто и тука забележувате дека штом се детектира колизија помеѓу топчето и горната или долната страна на екранот, го активираме звукот.

Притиснете F5 или Debug –> Start Debugging за да ги тестирате последните промени.

Splash Screen и Логоа

Превземете го .rar фајлот од тука и екстрактирајте ги сликите во следниот фолдер:

…\Documents\Visual Studio 2012\Projects\PongClone\PongClone\Assets

Кога ќе ве праша дали сакате да ги промените старите слики со новите, прифатете.

Во Visual Studio 2012, отворете го Package.appxmanifest фајлот (покажан на сликата)

Ке ви се отвори нов прозорец со опции за името на играта, можност за промена на логоата и слично. Притиснете на Splash Screen и во Background Color напишете black.

Притиснете F5 или Debug –> Start Debugging за да тестирате. Ќе видите дека сега имате нов Splash Screen.

Исто така на вашиот Start Screen ќе забележите ново иконче за играта.

Честито, ја комплетиравте вашата прва Windows 8 игра со MonoGame.

Мојот Solution може да го превземете од тука.

Напомена: Ќе треба да ги сетирате референците до MonoGame за да го тестирате мојот Solution.

Се надевам ви се допадна овој мини серијал. Доколку имате некакви прашања, оставете коментар подолу. Би сакал да им се заблагодарам на дечките од 3D Buzz, бидејќи пред повеќе од една година кога го учев XNA фрејмворкот, една од поголемите задачи беше креирање на Pong игра.

Advertisements