Posts from the ‘GameDev’ Category

Sparrow Beta Is Live!

Well that took longer than I expected, but finally, we got a playable version of Sparrow in the Windows Phone Store! Currently, it is hidden from the store because we submitted it as an invite-only beta to hunt down the bugs that we couldn’t find. We are planning to end the beta and release publicly once we are sure that we fixed all the reported bugs and balanced the game.

If you have a Windows Phone (7 or 8) device and are interested in testing the game out, let me know. Here are some screenshots from the beta:

 

 

 

 

 

 

 

 

 

 

 

We did a major change with the levels. Instead of having separate missions (which was taking a lot of time to create), we decided to start with a survival mode and procedurally generate the enemy waves. As you play the survival mode, you progress by upgrading your aircraft, switching to the next, more powerful aircraft if you don’t lose all your lives, pick up new weapons etc.

I do not want this post to be the ‘post-mortem’, I’m planning to write that after we release, so I will conclude with a few words about the beta. We worked quite a lot during the mayday and Orthodox Easter holidays to finish the beta version and I thought that’s it, now I can take a break for a few days… Wrong! We had to submit updates and fix bugs that were reported several hours after the beta was released.

There are 20 testers that have played the game and we got some valuable feedback. There were some performance issues, which I believe we finally sorted out and the game should run OK on any device. We still have to decide whether we should switch some effects that we do using the Mercury Particle Engine to ordinary sprite sheet animations to increase performance.

After we release on the WP store, we are planning to finish the Windows 8 port using MonoGame, and then depending on the popularity we will either continue adding more content or move to a new project which might not be a game, but it will probably have some game elements :). 

Until next time.

Advertisements

Sparrow Progress Report #2

Time for another short update on Sparrow. In this post I will briefly write about what I was working on in the last two weeks, and I’ll show you one of the four player aircraft that will be available in the first version.

Levels

As I noted in my last post, I started working on the levels two weeks ago. I am almost done with the fourth level, and I must say I am still not bored from testing and tweaking all those enemy waves. Compared to Aqua Guard, I’m having much more fun creating the levels for Sparrow.

The best part in creating the levels is definitely the boss battles (yes there will be several bosses to blow up!). I was having trouble killing the third boss, but luckily I gave it to a mate, Aleksandar (he worked with me on Aqua Guard, you can check his blog here) who killed it without losing a single life. This proved two things: I suck at my own game 😦 , and I must give early test versions to other people before I come up with any conclusions.

I kinda shot myself in the foot when I was asked in a TV interview (during the crazy local media coverage) about how many levels we planned for the first version. Even though we hadn’t decided yet, I said 10 levels, so now we (read that as I) must create at least 10 levels.

Background Tiles

In the first week of February my brother was working on several enemy aircraft and bosses. I believe we ended up with some nice sprites even though this is the first time he is doing pixelart. Few days ago he started drawing some background tiles, and I like where things are going. I will post a screenshot soon; maybe next week.

In the WOWZAPP build, we were using a full texture for the background which used a lot of resources and you could notice slight FPS drops at times. So now, I had to write some code for tile drawing. First I browsed  the net for open-source level editors where we could quickly use the tiles Alpay created to create backgrounds for the levels. We are now using Tiled which has everything that I needed. It saves the levels in a nice XML file which can easily be parsed.

Alpay is drawing 16×16 tiles and because WP7 has a resolution of 480×800, that means 1500 tiles are drawn on screen at any given time. At first I was stuck with updating the positions of 9000 tiles (6 full screens) which was an OK number and not causing FPS drops. If I increased the number of tiles, I encountered drops in FPS. Then I came up with a simple solution of first loading all the tiles during a loading screen to an array, and then using another array of 1530 tiles (one full screen and one row of 30 tiles just above the top) which was used for drawing the tiles. Now, I only have to update 1530 tiles and check the position of the last row. If the last row is out of the screen I extract the next row from the big array that contains the whole level. Now, I can load a lot of tiles (tested loading 72000, worked without any FPS drops) without the need of updating the ones that are off screen.

Collision Detection

I first decided to go with per-pixel collision on Sparrow, but as soon as I reached Level 3 where I increased the number of objects on screen, I encountered FPS drops. I tried optimizing it by checking every other pixel, but no luck. I narrowed the issue down to a certain Texture2D method, GetData(). Apparently the FPS drops happened when I was extracting the color values from the textures. I was even using collision rectangles (extract only the area covered by the rectangle where the intersection between two sprites happens) rather than extracting the colors of the complete textures.

I was definitely not going to decrease the number of objects on screen, so I decided to return to rectangle collision, but a little more sophisticated one. Now I am using Rectangle arrays for each object that contain several rectangles to cover the objects. For example, I can cover the Su-27’s area with only 3 Rectangles. The performance drastically increased and I can’t notice any visual problems with the collisions.

Are we going to miss another deadline?

Hopefully, we aren’t. There are two more weeks until February ends, and we should have at least 8 levels until then. The menu screens might not be all ready by then, but temporary stuff shouldn’t be a problem when giving the game to several people for testing. If you have a Windows Phone and are interested in testing the game before it is released, let me know.

Rahim is currently working on implementing Scoreoid for achievements and score tracking. In the last two weeks he was also working on save states and menu screens for choosing aircraft, levels and weapons.

The Screenshots

This is a Su-27 Flanker which is a playable aircraft.

OK, I know I said I will only show one aircraft, but I really like how the Su-25 Frogfoot looks, so I must show you that one too. The Su-25 will be an enemy plane.

Thanks for reading!

Sparrow Progress Report

In the last few weeks, the media in Macedonia overhyped our WOWZAPP 2012 first place award. We were interviewed by a few TV and radio stations, internet news portals and our university even arranged a meeting with the President of Macedonia.

There were some hiccups along the way with false reports saying the game is already out, our team got hired by Microsoft, etc. We wasted a lot of time with these false reports, trying to contact the people who made them public so they can correct them. But, the media today is a complete mess, at least ours is. After few minutes of being mentioned in one place (in our case DW), a chain-reaction was started and the news article was already grabbed by few other news portals. I was pretty disappointed because when we were giving the interviews they said we will be contacted when the news article is done so we can check the validity of the information, but this never happened. So on one hand, the game got a pretty cool promotion in Macedonia, but on the other hand… the false reports… ugh. And, yes, the pressure is much greater now since many people are expecting an interesting game.

Enough about the media, the goal of this post is about the game itself and not the media coverage.

The Progress Report

After WOWZAPP 2012, we started refactoring the (ugly) code we wrote during WOWZAPP. In December, we had to focus on our university courses (and we were a bit lazy 🙂 ) so we did not do a lot of progress. We were planning to release a closed beta by the end of January (yes, that’s today) but unfortunately we missed that deadline due to several reasons.

Because Macedonian Developers are not yet supported by the Windows 8 Store, we decided to focus on the Windows Phone version of the game.

The code is fully refactored now and I am currently working on creating levels for the game. I am pretty happy that more or less the weapon and powerup systems are done and very flexible. I also implemented the Mercury Particle Engine for some nice particle effects. Rahim is currently working on setting up the high-score and achievements and he will then move to finishing up the menus and save states.

We also have some news in the art front. Abdullah decided to drop out, and now my brother, Alpay, started doing the sprite work. I do not have any in-game screenshots for you at the moment, but on the left you can see a helicopter that he created, which will be used in the final version of the game.

 

 

Beta Testing

We are planning to start the beta test by the end of February. If you have a Windows Phone (either 7 or 8) and are interested in testing our game (and pinky-swear to give feedback), contact me. I better get back and continue working on those levels before we miss another deadline. Thanks for reading.

Developing 2D Games For Windows 8 Using MonoGame Part Four–Polishing

In the final part of this series we will polish our game. First we will type few lines to add ball spin. Then, we will add a SpriteFont which is used for drawing text on screen. We will use that to draw player scores. Next, we will add a line in the middle of the screen to separate player one’s field from player two’s field. Then we will add sounds for the collisions, and finish with adding a splash screen and tiles.

Ball Spin

Open the Game1.cs class and add a new constant:

const float SPIN = 2.5f;

Next, in the Update method, right after the lines for moving the players via Touch, add the following if-tests:

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();
}

In our case, if the players use touch input, you will notice that the velocity of the players is not strictly limited. The paddles will move with the same speed as the players’ drag speed. With keyboard on the other hand, there is a strict speed value defined in the constant KEYBOARD_PADDLE_SPEED. We do not want to allow the players using touch to have more or less ball spin when they hit the ball. That is why we normalize their velocities, so we can only take their movement direction.

So, first we check whether there is touch input. If true, we save that value and then normalize it.

In the same Update method, in the if-tests that check whether there is collision between the paddles and the ball, add the lines like shown below:

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;
}

 

After we change the direction of the ball, we add spin to the ball in the direction of player movement.

Press F5 or Debug –> Start Debugging to test. You will notice that when you hit the ball while you are moving a paddle, the ball’s velocity decreases or increases.

Feel free to experiment with the values given to the constants to alter gameplay. You can change the initial speed of the ball, add more or less spin etc.

Score Indicators

First, download and install the 8Bit Wonder font from here.

Now you will need to repeat the steps for compiling external assets as shown in part two so we can add a SpriteFont to our game.

Launch Visual Studio 2012 Express for Windows Phone and open the PongContent project. Right click on the Content project and Add –> New Item.

 

On the left side pick Visual C#, and then choose SpriteFont. Change the name to RetroFont and click Add.

After you click Add, the SpriteFont file will automatically open in Visual Studio. You can see different parameters that can be changed like font name, size, style etc.

Make the following changes:

<FontName>8Bit Wonder</FontName>

<Size>32</Size>

<Style>Bold</Style>

After you change the values, compile the project by pressing Build –> Build Solution. When the project successfully builds, close Visual Studio 2012 Express for Windows Phone.

Return to the PongClone project, right-click on the ‘Content’ folder and Add –> Existing Item…

Navigate to:

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

Select RetroFont.xnb and click Add.

Now select RetroFont and change its Build Action from None to Content.

Open the Player.cs class and add the following field:

public int Score;

Open the the Game1.cs class and declare a new SpriteFont variable after the declaration of the players and the ball:

Player player1;
Player player2;
Ball ball;

SpriteFont retroFont;

In the LoadContent method, add the following line to load the SpriteFont:

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

 

In the Update method, change the if-tests for launching the ball when it leaves the screen to the following:

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++;
}

So, if the ball leaves the screen from the left side, player 2 gets 1 point. If the ball leaves the screen from the right side, player 1 gets 1 point.

In the Draw method, between _spriteBatch.Begin() and player1.Draw(_spriteBatch), add a line for drawing the scores:

_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);

The DrawString method takes the SpriteFont object, the string we want to draw, position of the string (in our case the position depends on the length of the screen which is measured with the MeasureString method), and text color.

Press F5 or Debug –> Start Debugging to test. You will notice each player’s score on the top of the screen.

Now we can also add a line in the middle to divide the player fields.

In Game1.cs right after declaring SpriteFont retroFont; add a new texture:

SpriteFont retroFont;
Texture2D middleTexture;

In LoadContent, add the following line:

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

In the Draw method, after _spriteBatch.Begin() add the line for drawing the texture:

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

You will notice that we are using a different overload for the Draw method. Because the Middle texture has a width of 4 pixels and a height of 1 pixel (4×1), with the help of a Rectangle we can stretch it however we want. When you use a Rectangle for drawing objects on screen, the texture size does not matter. The texture is stretched or shrinked to fit inside the defined Rectangle.

Press F5 or Debug –> Start Debugging to see the new texture.

Sound Effects

Because we already compiled the sound effects when adding our external assets in part two, we can immediately start using them.

For managing sound effects we will create a new static class, ‘SoundManager’.

Right-click on the ‘Classes’ folder, Add –> Class… Change the name to ‘SoundManager’ (without quotation marks) and click Add.

Change the code in SoundManager.cs to the following:

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");
        }
    }
}

You will notice that we have two fields for holding the collision sounds between the ‘walls’ and ball, and between the players and the ball. Then we have a static method that takes a ContentManager object which is used for loading the sound effects.

Open the Game1.cs class and in the LoadContent method add the following line:

SoundManager.LoadSounds(Content);

Then in the Update method, change the if-tests for collision between the balls and the player to the following:

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();
}

So, as soon as the ball and a player collides, we play the sound effect.

Open the Ball.cs class and change the CheckWallCollision method to the following:

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();
	}
}

The same thing happens here. As soon as we detect collision between a ‘wall’ and the ball, we play the sound effect.

Press F5 or Debug –> Start Debugging to test the latest changes.

Splash Screen and Tiles

Download a .rar file containing the images from here. Extract the images to the following folder:

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

When you are asked, overwrite the existing files.

In Visual Studio 2012, open the Package.appxmanifest file (shown on the screen below).

A new window will open that contains options for the name of the game, ability to change logos and icons, etc. Click on the Splash Screen tab and type ‘blac’ (without quotation marks) in the Background Color field.

Press F5 or Debug –> Start Debugging to test. You will see that you now have a shiny new Splash Screen.

Also in your Windows 8 Start Screen you will notice a new small tile for your game.

Congratulations, you completed your first Windows 8 game using MonoGame!

You can download my Solution from here.

Note: You will need to set up the correct references to the MonoGame project in order to test my Solution.

I hope you liked this mini series. If you have any questions, feel free to leave a comment below. I would like to thank the folks over at 3D Buzz, because more than a year ago when I was learning the XNA Framework, one of their assignments was to create a Pong game.

Развивање 2Д Игри За Windows 8 Со MonoGame Четврт Дел–Дотерување

Во последниот дел од овој серијал ќе ја дотераме нашата игра. Прво ќе напишеме неколку линии за ‘вртење’ на топчето. Потоа, ќе додадеме 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 игра.