tag:blogger.com,1999:blog-83339816535617991742024-03-13T23:17:25.887-07:00Chris' Casual Game Development BlogAnonymoushttp://www.blogger.com/profile/13195644748323861784noreply@blogger.comBlogger4125tag:blogger.com,1999:blog-8333981653561799174.post-14665528434606907682017-07-14T19:00:00.002-07:002017-07-14T19:00:26.006-07:00Amazon Lumberyard 1.9.0.1 Quick and Dirty: How to access the TickBus via a Lua ScriptFirst lets launch the Lumberyard editor and create a new level.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-KYcAa1UKmuI/WWU02LEBvUI/AAAAAAAABSM/pef8E3JA0q82i0wvPggaQYv4CFPdetseQCLcBGAs/s1600/ly-newlevel-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="600" data-original-width="718" height="267" src="https://4.bp.blogspot.com/-KYcAa1UKmuI/WWU02LEBvUI/AAAAAAAABSM/pef8E3JA0q82i0wvPggaQYv4CFPdetseQCLcBGAs/s320/ly-newlevel-1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Click "New Level".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-kj4YNiUcawA/WWU02EU4FqI/AAAAAAAABSI/p86R52m4yu0nsR0w5aqMriEA-RMnZKnjQCLcBGAs/s1600/ly-newlevel-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="335" data-original-width="659" height="162" src="https://3.bp.blogspot.com/-kj4YNiUcawA/WWU02EU4FqI/AAAAAAAABSI/p86R52m4yu0nsR0w5aqMriEA-RMnZKnjQCLcBGAs/s320/ly-newlevel-2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For simplicity's sake let's leave the terrain texture settings at their default.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-1JIexuA105U/WWU02FPdPCI/AAAAAAAABSE/lz-OS90nLyIvSq0lWyToHX8Qk0XEXs1jQCLcBGAs/s1600/ly-newlevel-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="248" data-original-width="657" height="120" src="https://4.bp.blogspot.com/-1JIexuA105U/WWU02FPdPCI/AAAAAAAABSE/lz-OS90nLyIvSq0lWyToHX8Qk0XEXs1jQCLcBGAs/s320/ly-newlevel-3.png" width="320" /></a></div>
<br />
Click OK!<br />
<br />
Next, let's create a new Component Entity. Right-click on the game world and select "Create Entity".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-pykRZbUmS7Y/WWVAUFjLyAI/AAAAAAAABSQ/Megb3ARoKXEcfCJRun19xfUkhiuOEPxFACLcBGAs/s1600/ly-create-new-entity-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="167" data-original-width="323" height="165" src="https://3.bp.blogspot.com/-pykRZbUmS7Y/WWVAUFjLyAI/AAAAAAAABSQ/Megb3ARoKXEcfCJRun19xfUkhiuOEPxFACLcBGAs/s320/ly-create-new-entity-1.png" width="320" /></a></div>
<br />
<br />
Add a Lua Script Component.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-2sUMMW-vMDQ/WWl2lXBi9OI/AAAAAAAABS0/w2f6E9UD5BgbfBxHwMgisDW4odsI2kCRwCLcBGAs/s1600/ly-newsriptcomp-1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="396" height="290" src="https://2.bp.blogspot.com/-2sUMMW-vMDQ/WWl2lXBi9OI/AAAAAAAABS0/w2f6E9UD5BgbfBxHwMgisDW4odsI2kCRwCLcBGAs/s320/ly-newsriptcomp-1.PNG" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-BewqYsPJCKw/WWl2lfv77QI/AAAAAAAABSs/4gxkfqyfOW8pAVF5wAlnkKhkjTbtk7_ugCLcBGAs/s1600/ly-newsriptcomp-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="601" data-original-width="379" height="320" src="https://1.bp.blogspot.com/-BewqYsPJCKw/WWl2lfv77QI/AAAAAAAABSs/4gxkfqyfOW8pAVF5wAlnkKhkjTbtk7_ugCLcBGAs/s320/ly-newsriptcomp-3.png" width="201" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ofySPHCHSs4/WWl2lfNdO_I/AAAAAAAABSw/XlOx1l_oNpQY1Be025YiMVRt7KrCaUEwwCLcBGAs/s1600/ly-newsriptcomp-2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="398" height="320" src="https://3.bp.blogspot.com/-ofySPHCHSs4/WWl2lfNdO_I/AAAAAAAABSw/XlOx1l_oNpQY1Be025YiMVRt7KrCaUEwwCLcBGAs/s320/ly-newsriptcomp-2.PNG" width="304" /></a></div>
<br />
<br />
Open the Lua Script Editor<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-djhRJQ5-tbM/WWl29gRHIuI/AAAAAAAABS4/DMc1EfUmBSYan8q9_K4FClIJe6mwG_CbACLcBGAs/s1600/ly-newsriptcomp-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="682" data-original-width="505" height="320" src="https://2.bp.blogspot.com/-djhRJQ5-tbM/WWl29gRHIuI/AAAAAAAABS4/DMc1EfUmBSYan8q9_K4FClIJe6mwG_CbACLcBGAs/s320/ly-newsriptcomp-4.png" width="236" /></a></div>
<br />
Run your script in Game Mode (ctrl-G). You should see the tick message in the editor's console window.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/13195644748323861784noreply@blogger.com0tag:blogger.com,1999:blog-8333981653561799174.post-43211692457378882002015-12-28T18:57:00.005-08:002015-12-28T18:59:54.497-08:00Windows 8/10 Game Development using C#, XNA, and MonoGame 3.4: Building a Shooter Game Walkthrough – Part 9: Adding Sound Effects and Music<br />
<div style="margin: 0in 0in 0pt;">
<span style="font-family: Arial;"><b>A Few Words Before We Begin</b></span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">If you are following along you will notice that the title of
this series is updated to reflect Windows 10 and Monogame 3.4. </span><br />
<span style="font-family: Arial;"><br /></span>
<span style="mso-spacerun: yes;"><span style="font-family: Arial;"></span></span><span style="font-family: Arial;">Don’t worry! </span><span style="font-family: Arial;">All of the code we have
written and the projects we created will run just fine on Windows 8, 8.1, or
10 if you are working in Visual Studio 2010 or 2013 and have installed the XNA Game Studio 4.0. If that is your situation skip the next couple of paragraphs.</span><br />
<br />
<span style="font-family: Arial;">However, for those of you that are ready to put the past behind you and completely sever the cord with the Microsoft XNA framework or you are brand new to game development and Monogame then the following steps walk you through creating a new MonoGame project for Windows 10. I also provide a quick outline for using the MonoGame content pipeline to add graphics, sound, and effects to your games.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><b>Creating a New Windows 10 MonoGame UAP Project</b></span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Let's get started! First we want to create a new Windows 10 UAP MonoGame project.</span><br />
<br />
<span style="font-family: Arial;">Step 1.) Open Visual Studio and select File->New Project. Call it</span><span style="font-family: Arial;"> "ShooterTutorial-step-9-uap". </span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Step 2) Copy in the source code from previous tutorials.</span><br />
<span style="font-family: Arial;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-BNCE7nQbtcQ/VoG2vTRSPQI/AAAAAAAAA7w/9c9LugxszTI/s1600/UAPSolution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="http://1.bp.blogspot.com/-BNCE7nQbtcQ/VoG2vTRSPQI/AAAAAAAAA7w/9c9LugxszTI/s320/UAPSolution.png" width="320" /></a></div>
<span style="font-family: Arial;"><br /></span>
<br />
<span style="font-family: Arial;">In this tutorial we will reuse the png files used previous installments of the series. This should help to illustrate the point that the everything both source and content can be copied and pasted into a MonoGame project directly from an XNA project.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Or you could just fork my Windows 10 UAP app here from <a href="https://cclements1384@bitbucket.org/cclements1384/shootertutorial-step-9-uap.git">here</a> and skip all the details. </span><br />
<span style="font-family: Arial;"><b><br /></b></span>
<span style="font-family: Arial;"><b>Note: The repository linked above is a Git repository not HG as used in the past.</b></span><br />
<br /></div>
<div style="margin: 0in 0in 0pt;">
<span style="font-family: Arial;">Now, where was I?</span><br />
<br />
<span style="font-family: Arial;">Ah yes I remember, sound, music and explosions. In this blog post we will expand our game project to add
game music and sound effects.</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;"> </span></span><span style="font-family: Arial;">Music and
sound can greatly improve the immersion and set the mood of your game.</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;"> </span></span><span style="font-family: Arial;">Game sounds can be nearly as important to
your game as graphics. </span><span style="font-family: Arial;">How bland would Mario Brothers be if there were no sound associated with picking coins?</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;"> </span></span><span style="font-family: Arial;">Sounds may become game play elements in and of themselves.</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;"> </span></span><span style="font-family: Arial;">Imagine your game character being a dark
room and footsteps approaching from behind? </span></div>
<br />
<div style="margin: 0in 0in 0pt;">
<b style="mso-bidi-font-weight: normal;"><span style="font-family: Arial;">Add the Content Files
to Our Project</span></b></div>
<br />
<div style="margin: 0in 0in 0pt;">
<span style="font-family: Arial;">Our first order of business will be to add the sound game
music and sound effect contents to our project.</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;">
</span></span><span style="font-family: Arial;">Start by creating a new folder in the project
called </span><b style="mso-bidi-font-weight: normal;"><span style="font-family: Arial;">Sounds</span></b><span style="font-family: Arial;">. I typically locate this folder below the <b>Content</b> folder that appears in our new MonoGame Windows 10 UAP solution.</span><span style="mso-spacerun: yes;"><span style="font-family: Arial;"> </span></span><span style="font-family: Arial;">Next copy in the gameMusic.mp3,
laserfire.wav, and explosion.wav files into the Sounds folder.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Rl6u7R83PN8/VoG1v2HSfFI/AAAAAAAAA7Y/b_JKHiBAZVM/s1600/ContentInSolutionExplorer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/-Rl6u7R83PN8/VoG1v2HSfFI/AAAAAAAAA7Y/b_JKHiBAZVM/s320/ContentInSolutionExplorer.png" width="244" /></a></div>
<br />
<span style="font-family: Arial;">Next launch the MonoGame Content PipeLine Tool by double clicking the <b>Content.mgcb</b> file in the solution explorer. You may be prompted about which application to use to open the file type. If you are prompted, brows to the pipeline.exe file located in the directory where you installed Monogame. It should similar to this C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\Pipeline.exe.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">To add content to the Monogame Content Pipeline tool right-click on "Content" and click "Add". Now browse to existing images, models, sounds, or effects you want to add and click "open".</span><br />
<div>
<br /></div>
<span style="font-family: Arial;">If you have done everything correctly your pipeline tool should look like this:</span><br />
<span style="font-family: Arial;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-uvZIPxlehvg/VoG1xs6kaQI/AAAAAAAAA7g/S33QQ1HAr_k/s1600/ContentPipelineTool.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://2.bp.blogspot.com/-uvZIPxlehvg/VoG1xs6kaQI/AAAAAAAAA7g/S33QQ1HAr_k/s320/ContentPipelineTool.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial;">The next step is to save the content project and attempt to compile your assets. On the <b>Build</b> menu select "build". The content tool will attempt to build all assets; images, sounds, and models. There is no need to build each type individually.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-LEiGqzg-dvA/VoG2Vpu9pDI/AAAAAAAAA7o/KyGqh5WX7JA/s1600/ContentPipelineToolBuild.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="314" src="http://1.bp.blogspot.com/-LEiGqzg-dvA/VoG2Vpu9pDI/AAAAAAAAA7o/KyGqh5WX7JA/s320/ContentPipelineToolBuild.png" width="320" /></a></div>
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">If all goes well the content tool should your content files will build with no errors and your content will be ready to use in your game projects. </span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><b>Consuming our Sound Resources</b></span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">First, let's add a sound that represents the discharge of our ship's laser cannon. XNA/Mongame provides two class for working with sound effects; SoundEffect and SoundEffectInstance. Let's add variables for each to our class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> //Our Laser Sound and Instance</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private SoundEffect laserSound;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private SoundEffectInstance laserSoundInstance;</span><br />
<br />
<span style="font-family: Arial;">Next, we need to load the sound from our compiled content file into the soundEffect class. Loading sounds isn't much different from loading images. We will use the contentmanager class and load the sound in the LoadContent Method of the main game class. Add the following line of code to the LoadContent method.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> // Load the laserSound Effect and create the effect Instance</span><br />
<span style="font-family: Courier New, Courier, monospace;"> laserSound = Content.Load<SoundEffect>("Sounds\\laserFire");</span><br />
<span style="font-family: Arial;"></span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Once we have the laserSound class populated with sound data we need to create an instance of the sound effect. We can do that using the CreateInstance mthod on the SoundEffect class. Add this last line just below the one above in the LoadContent method.</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> laserSoundInstance = laserSound.CreateInstance();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Now for the fun bit! </span><span style="font-family: Arial;">I decided to add this last snippet of code to the method we call when the user presses the fire button. This method is appropriately named "FireLaser".</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Add this line of code inside of the "if" constrains our rate of fire by check the elasped time since the last time the fire button was pressed. Here is the entire code block as reference.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> // govern the rate of fire for our lasers</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (gameTime.TotalGameTime - previousLaserSpawnTime > laserSpawnTime)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> previousLaserSpawnTime = gameTime.TotalGameTime;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> // Add the laer to our list.</span><br />
<span style="font-family: Courier New, Courier, monospace;"> AddLaser();</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> // Play the laser sound!</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b> laserSoundInstance.Play();</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Time to test! If everything is correct then you should hear a distinct "ziiiip!" when you press the fire button (space bar). This sound should occur at the same rate as the laser image appears on the screen. The sound should not play any faster than the actual ship is firing. In short, the sound is constrained to the rate of fire.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">If you made it this far, then I assume the laser sound is working as you would expect. Now let's add the explosion sound. All of the steps are the same so this time I will breeze through it.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">First, add the two variables we need to hold and play the explosion sound. Remember these variables are members of the Game class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> //Our Explosion Sound.</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private SoundEffect explosionSound;</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> private SoundEffectInstance explosionSoundInstance;</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Next, load the sound effect in the LoadContent method and instantiate the SoundEffectInstance class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">// Load the laserSound Effect and create the effect Instance</span><br />
<span style="font-family: Courier New, Courier, monospace;">explosionSound = Content.Load<SoundEffect>("Sounds\\explosion");</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">explosionSoundInstance = explosionSound.CreateInstance();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Finally, let's play the explosion sound when we add a new explosion to the game. Add the following code to the AddExplosion method.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> /* play the explosion sound. */</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> explosionSoundInstance.Play();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">If you run the game you will find the explosion sound is played either when a laser blast or the player's ship collides with an aerial mine.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">You may also notice the only one instance of the explosion sound is played at a time. This means that if you were to destroy two targets in in rapid succession you may find that you only hear the explosion sound once. Let's alter our code to play the sound from the SoundEffect class rather then the SoundEffectInstance class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Change the line above to:</span><br />
<span style="font-family: Arial;">explosionSound.Play();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Remember to clean up the SoundEffectInstance classes with a dispose method when you are done. This can be done when exiting the game or perhaps moving between screens when a given sound is no longer needed.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">I added the following code the UnloadContent method.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">laserSoundInstance.Dispose();</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">explosionSoundInstance.Dispose();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><b>Adding Game Music</b></span><br />
<span style="font-family: Arial;"><b><br /></b></span>
<span style="font-family: Arial;">I will wrap up this installment of the tutorial by adding game music to our demo. The steps for adding game music are similar to those for adding other types of content. However, the playback makes use of the Song class and the MediaPlayer class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">First declare a variable that will hold our game music. Add this line of code the Game class.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">// Game Music.</span><br />
<span style="font-family: Courier New, Courier, monospace;">private Song gameMusic;</span><br />
<span style="font-family: Arial;"><br /></span><span style="font-family: Arial;">Next add the following line of code to the LoadContent method.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">// Load the game music</span><br />
<span style="font-family: Courier New, Courier, monospace;">gameMusic = Content.Load<Song>("Sounds\\gameMusic");</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">Lastly, let's kick off the playback of our game music by using the MediaPlayer class. You can start the playback with this line of code, again, in the LoadContent method.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">// Start playing the music.</span><br />
<span style="font-family: Courier New, Courier, monospace;"> MediaPlayer.Play(gameMusic);</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">When you want to stop the music you can call the stop method like this:</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">MedialPlayer.Stop();</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><b>Conclusion</b></span><br />
<span style="font-family: Arial;"><b><br /></b></span>
<span style="font-family: Arial;">Today we learned how to convert our Windows 7/8.1 based game projects to Windows 10 UAP projects. We also learned how to use the MonoGame Content Pipeline tool to completely remove the dependence on XNA.</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">We also learned how to add cool sound effects and music play back to our games. Of course this tutorial only scratches the surface. There is a lot more ground to cover when it comes to sounds such as adjusting pitch, tone, volume, and of course 3D effects. Next time we will add a GameState class and create menus to navigate to and from. Thanks for reading and following along!</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;">As always, you can find the complete source code for this tutorial <a href="https://cclements1384@bitbucket.org/cclements1384/shootertutorial-step-9-uap.git">here</a>.</span><br />
<span style="font-family: Arial;">Chris</span><br />
<span style="font-family: Arial;"><br /></span>
<span style="font-family: Arial;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/13195644748323861784noreply@blogger.com7tag:blogger.com,1999:blog-8333981653561799174.post-29751281452692639992015-02-28T10:57:00.001-08:002015-07-21T19:24:26.283-07:00Windows 8 Game Development using C#, XNA and MonoGame 3.0: Building a Shooter Game Walkthrough – Part 8: Here comes the Boom!In part <a href="http://chrisongames.blogspot.com/2014/12/windows-8-game-development-using-c-xna.html">seven </a>of this series we expanded our game by adding a laser gun to the player’s ship and code that detects collisions between a laser beam and an enemy mine. When a laser beam collides with an enemy mine the enemy is removed from the list of “active” mines. Effectively, the enemy is destroyed. Pretty cool eh? But, wouldn’t it be cooler and more satisfying if the enemy mine was destroyed in a burst of flames, their remains scattered to the winds? That is exactly the effect we will be adding in this step.<br />
<br />
First let’s “true up” our project. You can download the code base from which I will be working <a href="https://cclements1384@bitbucket.org/cclements1384/shootertutorial-step-8">here</a>. This project should contain all the features of Tara Walker’s tutorial series and also my contribution from part seven.<br />
<br />
<h3>
Step 1 – Create the Explosion Class</h3>
The first thing we need to do is add a new class to our game project. Let’s call this class Explosion.cs. The explosions class is not much different than our player, enemy, or laser classes. This class has many of the save variables and methods as the classes mentioned above. <br />
At the top of our new class we Ithe following namespace references.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShooterTutorial;
</pre>
<br />
Just like we did in previous steps we are going to add the following stub methods to our class, Initialize(), Update(), and Draw(). <br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">public void Initialize()
{
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch spriteBatch)
{
}
</pre>
<br />
Next we will define a series of variables that will render our sprite animation, track the location of the explosion, return the height and width of the explosion sprite, and finally, track the explosion's time to live. This is the amount of time that we will render the explosion animation. Explosions can’t go on forever (as much as we may wish they would). All good things must come to an end.
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">Animation explosionAnimation;
Vector2 Position;
public bool Active;
int timeToLive;
public int Width
{
get { return explosionAnimation.FrameWidth; }
}
public int Height
{
get { return explosionAnimation.FrameWidth; }
}
</pre>
<br />
Let’s modify the Initialize() method to accept an instance of our Animation class and a Vector2 called position. The position will be that of the exploding enemy mine. The animation class will be responsible for looping through each frame of our sprite strip and displaying the a single image from a series.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">public void Initialize(Animation animation, Vector2 position)
{
explosionAnimation = animation;
Position = position;
Active = true;
timeToLive = 30;
}
</pre>
<br />
The next step is to modify the Update() method to call our animation class’ update method, decrement the time to live and set the explosion’s active flag to false once it’s time to live has expired.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">public void Update(GameTime gameTime)
{
explosionAnimation.Update(gameTime);
timeToLive -= 1;
if (timeToLive <= 0)
{
this.Active = false;
}
}
</pre>
<br />
The final modification to the explosion class is in the Draw() method. Here we invoke our animation class’ draw method to send the sprite frame to the buffer for rendering.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">public void Draw(SpriteBatch spriteBatch
{
explosionAnimation.Draw(spriteBatch);
}
</pre>
<br />
<h3>
Step 2 - Wiring the Explosion Class into the Main Game Class</h3>
For this tutorial I decided that it may be possible to have more than one “active” explosion being rendered at one time. Therefore I am going to need a collection to hold any possible explosions that are touched off. Add the following lines of code to the top of the Game1.cs class.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// Collections of explosions
List<Explosion> explosions;
//Texture to hold explosion animation.
Texture2D explosionTexture;
</pre>
<br />
The first line of code establishes a list of explosions. The second line defines a Texture2D structure that will hold our sprite strip.<br />
Now is a good time to add the explosion sprite strip to our content builder project. To do this, first navigate to the location of the explosion.png graphics file. If you open the contents of this files using a graphics editor such as Paint.NET you will see that this is a long rectangular “strip” image containing eleven sprites of the explosion in various states. Our animation class loops across this strip displaying each image briefly to provide the illusion of continuous animation. This works exactly the same way a cartoonist would draw and photograph a series of images and then display them in rapid succession to produce an animated feature.<br />
Next we will add a single line of code to the Initialize() method. This will instantiate our list of explosions.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// init our collection of explosions.
explosions = new List<Explosion>();
</pre>
<br />
Now let’s load our sprite strip into the Texture2D struction defined earlier. Add this line of code to the LoadContent() method of the Game1.cs class.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// load the explosion sheet
explosionTexture = Content.Load<Texture2D>("Graphics\\explosion");
</pre>
<br />
There is one last bit of setup we need to do before we can get to the fun stuff (blowing up enemies). Let’s create a helper method that will initialize and insert a new instance of an explosion into our explosions collection. Add this method to the bottom of the Game1.cs class.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">protected void AddExplosion(Vector2 enemyPosition)
{
Animation explosionAnimation = new Animation();
explosionAnimation.Initialize(explosionTexture,
enemyPosition,
134,
134,
12,
30,
Color.White,
1.0f,
true);
Explosion explosion = new Explosion();
explosion.Initilize(explosionAnimation, enemyPosition);
explosions.Add(explosion);
}
</pre>
<br />
This method is pretty simple. First we create a new instance of the animation class using the explosion sprite strip. Next we create a new instance of an explosion and pass in the explosion animation and the last position of the enemy ship that will be exploding. Lastly, this explosion instance is added to the list of “active” explosions.<br />
Now the fun begins! We already have code that detects collisions between the enemies and the player and also between the enemies and laser beams. Let’s inject code at those locations to add an explosion.<br />
Find the DetectCollisions() method. Inside that method you will find a loop for each laser beam that has been fired and is still active. Within that loop is a bounds check between the rectangle of the laser beam and that of an enemy mine. Let’s add our explosion code inside of that bounds check.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// test the bounds of the laser and enemy
if (laserRectangle.Intersects(enemyRectangle))
{
// Show the explosion where the enemy was...
AddExplosion(enemies[i].Position);
// kill off the enemy
enemies[i].Health = 0;
// kill off the laserbeam
laserBeams[l].Active = false;
}
</pre>
<br />
Add the same line of code inside the bounds check for the player’s ship and the an enemy.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">if (playerRectangle.Intersects(enemyRectangle))
{
// kill off the enemy
enemies[i].Health = 0;
// Show the explosion where the enemy was...
AddExplosion(enemies[i].Position);
// deal damge to the player
_player.Health -= enemies[i].Damage;
// if the player has no health destroy it.
if (_player.Health <= 0)
{
_player.Active = false;
}
}
</pre>
<br />
The last two steps for adding the explosion animation to our game is to add the Draw() and Update() methods for our explosions.<br />
Add this code to the Draw() method of the Game1.cs class.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">
// draw explosions
foreach(var e in explosions)
{
e.Draw(_spriteBatch);
}
</pre>
<br />
This code simply loops across the explosion list and calls the Draw() method of each explosion class it contains.<br />
Next we call the update method of our explosion class(es). This advances the displayed animation from based on the game time. This code is very similar to the draw code we added above. Let’s extract this loop into it’s own method.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">private void UpdateExplosions(GameTime gameTime)
{
for (var e = 0; e < explosions.Count; e++ )
{
explosions[e].Update(gameTime);
if (!explosions[e].Active)
explosions.Remove(explosions[e]);
}
}
</pre>
<br />
This code loops across the explosions collection and checks to see if the explosion is still active. If the explosion is no longer active (it has played its entire animation) then it is removed from the explosions list. Let’s add our new method inside the Update() method of the Game1.cs class.<br />
<br />
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">UpdateExplosions(gameTime);
</pre>
<br />
<h3>
Conclusion</h3>
<br />
In this tutorial we didn’t really do anything differently than was has already been demonstrated in previous steps. You may begin to see a pattern emerging in these game classes. They all contain an Initialize(), Update(), and Draw() methods. These are the bacis functions that any game object must perform. It must be created, it must react to user input, AI, or the world around it, and it must be rendered to the game screen. <br />
In the next tutorial we will add sound effects and game music. It’s really simple to do and adds a new level of polish and immersion to your game project.Anonymoushttp://www.blogger.com/profile/13195644748323861784noreply@blogger.com4tag:blogger.com,1999:blog-8333981653561799174.post-17943512924055105152014-12-15T22:52:00.001-08:002015-07-21T19:24:26.277-07:00Windows 8 Game Development using C#, XNA and MonoGame 3.0: Building a Shooter Game Walkthrough – Part 7: Load Your Weapons!<span style="font-family: Arial, Helvetica, sans-serif;">In this continuation of Tara Walker's series: Windows 8 Game Development Using C#, XNA and MonoGame we will expand our game by giving the player the ability to fire deadly laser blasts at the enemy. We will create the laser game object, add code to fire the laser when the user presses the space bar, and detect collisions between our laser blasts and the enemy areal mines. You can find a link to her original series <a href="http://blogs.msdn.com/b/tarawalker/archive/2012/12/04/windows-8-game-development-using-c-xna-and-monogame-3-0-building-a-shooter-game-walkthrough-part-1-overview-installation-monogame-3-0-project-creation.aspx">here.</a></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Creating the Laser Blast</span></h2>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Step 1 - Create the Laser Class</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Add a new class to your project called <b>Laser.cs</b>. Add the following using statements to the top of the class definition.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
</pre>
<br />
<div>
As in our player and enemy classes, we will stub out the methods for Draw(), Update(), and Initialize(). We will also define a couple of new variables that represent the characteristics of our laser blast. Add the following definitions to the top of the <b>Laser.cs</b> class.</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// animation the represents the laser animation.
public Animation LaserAnimation;
// the speed the laser travels
float laserMoveSpeed = 30f;
// position of the laser
public Vector2 Position;
// The damage the laser deals.
int Damage = 10;
// set the laser to active
public bool Active;
// Laser beams range.
int Range;
// the width of the laser image.
public int Width
{
get { return LaserAnimation.FrameWidth; }
}
// the height of the laser image.
public int Height
{
get { return LaserAnimation.FrameHeight; }
}
</pre>
<h4>
Design Break:</h4>
<div>
As you look over the variables above, hopefully you are already getting cool ideas for power ups and enhancements. Perhaps the player can get bonuses to the laser's damage and speed characteristics. Will you permit your laser to fly all the way across the screen or will it fizzle out shortly after being fired? As a game designer these are all aspects you must consider. All of which will have a effect on game play and ultimately, the finished product. It's a good idea to write these ideas down as part of a game design before you begin coding. Having a formal game design will save you time during implementation. Now back to coding!</div>
<div>
<br /></div>
<div>
Add the following implementations for the Initialize(), Update(), and Draw() methods.</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">public void Initialize(Animation animation, Vector2 position)
{
LaserAnimation = animation;
Position = position;
Active = true;
}
public void Update(GameTime gameTime)
{
Position.X += laserMoveSpeed;
LaserAnimation.Position = Position;
LaserAnimation.Update(gameTime);
}
public void Draw(SpriteBatch spriteBatch)
{
LaserAnimation.Draw(spriteBatch);
}
</pre>
<h3>
Step 2 - Add the Laser Texture Content and Load It</h3>
<div>
Locate the <b>laser.xnb </b>from the downloaded folder and add it to your project. In my project I placed this texture file in the \Content\Graphics folder. Once you have added this file. Right-click on the file in the solution explorer and click "properties". Set the "<b>build action</b>" setting to "<b>content</b>" and set the "<b>copy to output directory"</b> setting to "<b>Copy if newer</b>". </div>
</div>
</div>
</div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Next let's add the following variable near the top of the game class <b>Game1.cs</b>. This variable will hold the texture for our laser beam.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<br />
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// texture to hold the laser.
Texture2D laserTexture;
// govern how fast our laser can fire.
TimeSpan laserSpawnTime;
TimeSpan previousLaserSpawnTime;
</pre>
I will mention the two TimeSpan variables in detail later. For now let's just add them just below the declaration of our texture variable. Add the following line of code the the <b>LoadContent()</b> method of the Game class <b>Game1.cs</b>. </div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// load th texture to serve as the laser
laserTexture = Content.Load<Texture2D>("Graphics\\laser");
</pre>
<br /></div>
<h3>
Step 3 - Initialize our Laser Object List</h3>
<div>
<br /></div>
<h4>
Design Break:</h4>
<div>
<span style="font-weight: normal;">Before we can add our laser we must make a couple of game design decisions. Firstly, will the player be able to fire only one laser beam at a time or will we permit them to fire multiple beams in a hail of flaming hot destruction? Trust me, it matters! For this tutorial we will go with the latter option. We will establish a variable that governs a rate of fire for our laser cannon. That means we may have more than one active beam at a time. This requires us to create a collection of laser beam objects.</span></div>
<div>
<span style="font-weight: normal;"><br /></span></div>
<div>
To store the volley of laser fire, add this list definition near the top of the <b>Game1 </b>class just below the laserTexture declaration:</div>
<div>
<br /></div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">List<Laser> laserBeams;
</pre>
Next add the following variable definitions to the <b>Initialize()</b> method. I will explain each one below.</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// init our laser
laserBeams = new List<Laser>();
const float SECONDS_IN_MINUTE = 60f;
const float RATE_OF_FIRE = 200f ;
laserSpawnTime = TimeSpan.FromSeconds(SECONDS_IN_MINUTE /RATE_OF_FIRE);
previousLaserSpawnTime = TimeSpan.Zero;
</pre>
<br />
The first variable should be fairly obvious. We are simply instantiating ("newing up") a strongly typed list of our Laser class. The next line is for nothing more than readability. I create a float to hold the number of seconds in one minute. Then I create another float to hold a rate of fire (lasers per minute). II use the seconds in one minute and the rate of fire variables to calculate a time span, in seconds, that governs how quickly my laser can fire another round. In this case I want a rate of fire of 200 rounds per second so my time span between shots will be less than one second (60/200). The very last line initializes a variable that will be set when a new laser is fired. When the time between "now" and the previousLaserSpawnTime is greater or = the laserSpawnTime then I can fire a new beam.</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
Step 4 - Add Code to Fire a Laser</h3>
<div>
To support firing the player's weapons I added the following two classes to the <b>Game1.cs</b> class.</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">protected void FireLaser(GameTime gameTime)
{
// govern the rate of fire for our lasers
if (gameTime.TotalGameTime - previousLaserSpawnTime > laserSpawnTime)
{
previousLaserSpawnTime = gameTime.TotalGameTime;
// Add the laer to our list.
AddLaser();
}
}
protected void AddLaser()
{
Animation laserAnimation = new Animation();
// initlize the laser animation
laserAnimation.Initialize(laserTexture,
player.Position,
46,
16,
1,
30,
Color.White,
1f,
true);
Laser laser = new Laser();
// Get the starting postion of the laser.
var laserPostion = player.Position;
// Adjust the position slightly to match the muzzle of the cannon.
laserPostion.Y += 37;
laserPostion.X += 70;
// init the laser
laser.Initialize(laserAnimation, laserPostion);
laserBeams.Add(laser);
/* todo: add code to create a laser. */
// laserSoundInstance.Play();
}
</pre>
<div>
<br /></div>
<div>
<br /></div>
<div>
The <b>FireLaser()</b> method is pretty straight-forward. First, I check to see if enough time has passed between now and the last time I fired a laser. If it has then I record the current time and call the <b>AddLaser</b>() method.</div>
<div>
<br /></div>
<div>
The <b>AddLaser() </b>method simply initializes a new instance of the animation class using our laser beam texture. Then we set the laser's starting position to that of the player's current position. We assume the laser is emitted from the player's ship. Finally, we pass our animation class into the <b>Initialize() </b>method of our laser class and add it to our collection of Laser objects. Did you see the commented code to play the sound of a laser blast? That's a teaser for a future tutorial! </div>
<div>
<br /></div>
<div>
The last thing we need to do is to wire up our <b>FireLaser()</b> method to the press of the space bar on the keyboard or the X button on the XBox controller. Add this code to the <b>UpdatePlayer()</b> method of the <b>Game1.cs</b> class.</div>
<div>
<br /></div>
<div>
<div>
<br /></div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">if (_currentKeyboardState.IsKeyDown(Keys.Space) || _currentGamePadState.Buttons.X == ButtonState.Pressed)
{
FireLaser(gameTime);
}
</pre>
<br />
Step 5 - Add Code to Track Laser Beams and Detect Collisions</div>
</div>
</div>
</div>
</div>
<div>
Now that we can add laser beams to our collection we need to loop through all active lasers and update their positions and detect collisions with enemies. This part is pretty simple. Just add the following code to the <b>Update()</b> method of the <b>Game1.cs</b> class.</div>
<div>
<br /></div>
<div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// update laserbeams
for (var i = 0; i < laserBeams.Count;i++ )
{
laserBeams[i].Update(gameTime);
// Remove the beam when its deactivated or is at the end of the screen.
if (!laserBeams[i].Active || laserBeams[i].Position.X > GraphicsDevice.Viewport.Width)
{
laserBeams.Remove(laserBeams[i]);
}
}
</pre>
<br /></div>
<div>
Notice that I never used the "range" variable I declared earlier in my code. I just decided that a beam would fly across the screen until it reached the right side or collided with an enemy mine. </div>
<div>
<br /></div>
<div>
Next we need to loop through all enemies and check to see if they are colliding with any of the laser beams in our collection. To do this, we need a nested loop. Add this code to the <b>UpdateCollisions() </b>method in the <b>Game1.cs</b> class.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">Rectangle laserRectangle;
</pre>
<div>
<br /></div>
<div>
<br /></div>
<div>
This rectangle is used to define the bounding box around a laser beam and is used in collision detection against the rectangles of enemies. Locate the section of code in the <b>UpdateCollisions()</b> method where we loop through our collection of enemies testing for collisions with the player. Add this code <b>INSIDE </b>the enemy loop as shown.</div>
<div>
<br /></div>
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// detect collisions between the player and all enemies.
enemies.ForEach(e =>
{
//create a retangle for the enemy
enemyRectangle = new Rectangle(
(int)e.Position.X,
(int)e.Position.Y,
e.Width,
e.Height);
// now see if this enemy collide with any laser shots
laserBeams.ForEach(lb =>
{
// create a rectangle for this laserbeam
laserRectangle = new Rectangle(
(int)lb.Position.X,
(int)lb.Position.Y,
lb.Width,
lb.Height);
// test the bounds of the laer and enemy
if (laserRectangle.Intersects(enemyRectangle))
{
// play the sound of explosion.
var explosion = explosionSound.CreateInstance();
explosion.Play();
// Show the explosion where the enemy was...
AddExplosion(e.Position);
// kill off the enemy
e.Health = 0;
//record the kill
myGame.Stage.EnemiesKilled++;
// kill off the laserbeam
lb.Active = false;
// record your score
myGame.Score += e.Value;
}
});
});
</pre>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Step 6 - Draw the Laser Beams</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The last step is to add code in the <b>Draw()</b> method of the <b>Game1.cs</b> class to loop through each object in the laser beam collection and invoke it's draw method. Add this code:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<div>
<pre class="brush: csharp; highlight: [5, 15]; html-script: true">// Draw the lasers.
foreach (var l in laserBeams)
{
l.Draw(spriteBatch);
}
</pre>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Well That is it! If you have done everything correctly then your player's ship will now be armed with a deadly laser cannon. Experiment with the rate of fire and laser speed variables. Find a combination that is both fun and challenging. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-mZY1sKii0jA/VI_T79kIryI/AAAAAAAAAyY/IWsqT50-kGs/s1600/ShooterTutorial.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="http://1.bp.blogspot.com/-mZY1sKii0jA/VI_T79kIryI/AAAAAAAAAyY/IWsqT50-kGs/s1600/ShooterTutorial.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Now you can blast away at enemies!</td></tr>
</tbody></table>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Next time we will make these pesky enemy mines EXPLODE!</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">You can find the source code for this step <a href="https://cclements1384@bitbucket.org/cclements1384/shootertutorial">here</a>:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/13195644748323861784noreply@blogger.com2