1 #region File Description
2 // Project Title: The Singularity
3 // Creators: Sean Smith & Stefan Dieckmann
4 // Class: GAM315
5 // File: TheSingularity.cs
6 #endregion
7
8 #region Using Statements
9 using System;
10 using System.Collections.Generic;
11 using System.Linq;
12 using Microsoft.Xna.Framework;
13 using Microsoft.Xna.Framework.Audio;
14 using Microsoft.Xna.Framework.Content;
15 using Microsoft.Xna.Framework.GamerServices;
16 using Microsoft.Xna.Framework.Graphics;
17 using Microsoft.Xna.Framework.Input;
18 using Microsoft.Xna.Framework.Media;
19 using Microsoft.Xna.Framework.Net;
20 using Microsoft.Xna.Framework.Storage;
21 #endregion
22
23 namespace TheSingularity
24 {
25 public class TheSingularity : Microsoft.Xna.Framework.Game
26 {
27 #region Fields
28 private const int MinimumXPos = -2700;
29 private const int MaximumXPos = 2700;
30 private const int MinimumZPos = -2000;
31 private const int MaximumZPos = 2000;
32
33 GraphicsDeviceManager graphics;
34 GraphicsDevice device;
35 SpriteBatch spriteBatch;
36
37 Input input; // input object
38 Camera camera; // camera object
39
40 // Set position of camera
41 Vector3 cameraPosition = new Vector3(0.0f, 5500.0f, 100.0f);
42 Random rand = new Random(); // random variable
43
44 Ship ship; // ship object
45 Asteroid[] asteroids; // asteroid array
46 int maxAsteroids = 5; // max number of asteroids
47
48 Model shipModel; // ship model
49 Model projModel; // ship projection model
50 Model asteroidModel; // asteroid model
51
52 ScrollingBackground bgStars; // background object
53 SpriteFont fontScore;
54 int playerScore = 0;
55
56 //Set the sound effects to use
57 bool soundEnginePlaying = false;
58 SoundEffectInstance soundEngineInstance;
59 SoundEffect soundExplosion1, soundExplosion2;
60 SoundEffect soundFire1;
61 #endregion
62
63
64 #region Initialization
65 public TheSingularity()
66 {
67 graphics = new GraphicsDeviceManager(this);
68 Content.RootDirectory = "Content";
69 }
70
71 /// <summary>
72 /// Allows the game to perform any initialization it needs to before starting to run.
73 /// This is where it can query for any required services and load any non-graphic
74 /// related content. Calling base.Initialize will enumerate through any components
75 /// and initialize them as well.
76 /// </summary>
77 protected override void Initialize()
78 {
79 graphics.PreferredBackBufferWidth = 1024;
80 graphics.PreferredBackBufferHeight = 768;
81
82 input = new Input();
83
84 camera = new Camera();
85 camera.Init(MathHelper.ToRadians(45.0f), graphics.GraphicsDevice.Viewport.AspectRatio, 10000.0f, cameraPosition);
86
87 base.Initialize();
88 }
89
90 /// <summary>
91 /// LoadContent will be called once per game and is the place to load
92 /// all of your content.
93 /// </summary>
94 protected override void LoadContent()
95 {
96 device = graphics.GraphicsDevice;
97 // Create a new SpriteBatch, which can be used to draw textures.
98 spriteBatch = new SpriteBatch(GraphicsDevice);
99
100 ship = new Ship(MinimumXPos, MaximumXPos, MinimumZPos, MaximumZPos);
101 asteroids = new Asteroid[maxAsteroids];
102
103 // Load models
104 shipModel = Content.Load<Model>("Models\\LandShark");
105 projModel = Content.Load<Model>("Models\\mgun_proj");
106 asteroidModel = Content.Load<Model>("Models\\asteroid1");
107
108 // Load scolling background
109 bgStars = new ScrollingBackground();
110 Texture2D background = Content.Load<Texture2D>("Textures\\B1_stars");
111 bgStars.Load(GraphicsDevice, background);
112
113 // Load on screen text font
114 fontScore = Content.Load<SpriteFont>("Fonts\\ScoreFont");
115
116 // Load the sound effects
117 soundExplosion1 = Content.Load<SoundEffect>("Audio\\Explosions\\explosion1");
118 soundExplosion2 = Content.Load<SoundEffect>("Audio\\Explosions\\explosion2");
119 soundFire1 = Content.Load<SoundEffect>("Audio\\Weapons\\pdp1_fire");
120 }
121
122 /// <summary>
123 /// UnloadContent will be called once per game and is the place to unload
124 /// all content.
125 /// </summary>
126 protected override void UnloadContent()
127 {
128 // TODO: Unload any non ContentManager content here
129 }
130 #endregion
131
132
133 #region Update
134 /// <summary>
135 /// Allows the game to run logic such as updating the world,
136 /// checking for collisions, gathering input, and playing audio.
137 /// </summary>
138 /// <param name="gameTime">Provides a snapshot of timing values.</param>
139 protected override void Update(GameTime gameTime)
140 {
141 float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
142
143 soundEnginePlaying = false; // Reset sound
144 input.Update(); // Call input update
145
146 if (input.currentKeyboardState.IsKeyDown(Keys.Escape))
147 Exit();
148
149 // Calls collision detection
150 CheckCollisions();
151
152 // Update the ship
153 if (ship.Update(gameTime))
154 {
155 // Allow the player to make sound
156 soundEnginePlaying = true;
157 soundFire1.Play();
158 }
159
160 //Update background
161 bgStars.Update(elapsed * 100);
162
163 // Update each asteroid being rendered
164 for (int counter = 0; counter < maxAsteroids; counter++)
165 {
166 // Reset asteroid
167 Asteroid asteroid = null;
168 asteroid = asteroids[counter];
169
170 // If an asteroid exists
171 if (asteroid != null)
172 {
173 // Reset asteroid if moves past boundary
174 if (asteroid.Position.Z >= MaximumZPos + 500)
175 asteroids[counter] = null;
176 else
177 // Update each asteroid
178 asteroid.Update(gameTime);
179 }
180 else
181 // Create random asteroid
182 asteroids[counter] = new Asteroid(rand);
183 }
184
185 base.Update(gameTime);
186 }
187
188 public void CheckCollisions()
189 {
190 // Bounding sphere for ship
191 BoundingSphere shipSphere = // Bounding sphere for ship
192 new BoundingSphere(ship.Position, 100f);
193
194 // Check for collisions with EACH asteroid
195 for (int counter = 0; counter < maxAsteroids; counter++)
196 {
197 Asteroid asteroid = null; // Reset asteroid
198 asteroid = asteroids[counter];
199 if (asteroid != null)
200 {
201 BoundingSphere asteroidSphere = // Bounding sphere for asteroid
202 new BoundingSphere(asteroid.Position, 200f);
203
204 // If there is a collision detected between Ship and Asteroid
205 if(shipSphere.Contains(asteroidSphere) != ContainmentType.Disjoint)
206 {
207 asteroids[counter] = null; // Reset asteroid
208 ship.Reset();
209 soundEnginePlaying = true;
210 soundExplosion1.Play();
211 playerScore = 0;
212 }
213 // Check for collision with EACH ship projectile
214 for (int counter1 = 0; counter1 < ship.projectiles.Count; counter1++)
215 {
216 Projectile proj = null; // Reset projectile
217 proj = ship.projectiles[counter1];
218
219 if (proj != null)
220 {
221 BoundingSphere projSphere = // Bounding sphere for projectile
222 new BoundingSphere(proj.projectilePosition, 50f);
223
224 // If there is a collision detected between Projectile and Asteroid
225 if (asteroidSphere.Contains(projSphere) != ContainmentType.Disjoint)
226 {
227 asteroids[counter] = null; // Reset asteroid
228 ship.projectiles.Remove(proj);
229 soundEnginePlaying = true;
230 soundExplosion2.Play();
231 playerScore += 10;
232 }
233 }
234 }
235 }
236 }
237 }
238 #endregion
239
240 #region Draw
241 /// <summary>
242 /// This is called when the game should draw itself.
243 /// </summary>
244 /// <param name="gameTime">Provides a snapshot of timing values.</param>
245 protected override void Draw(GameTime gameTime)
246 {
247 GraphicsDevice.Clear(Color.Black);
248
249 spriteBatch.Begin();
250
251 bgStars.Draw(spriteBatch);
252
253 spriteBatch.End();
254
255 GraphicsDevice.RenderState.DepthBufferEnable = true;
256 GraphicsDevice.RenderState.AlphaBlendEnable = false;
257 GraphicsDevice.RenderState.AlphaTestEnable = false;
258
259 DrawModel(shipModel, ship.World, 1.0f);
260
261 if (ship.projectiles.Count > 0)
262 {
263 foreach (Projectile projectile in ship.projectiles)
264 {
265 Matrix projectileWorld = Matrix.Identity;
266 projectileWorld.Translation = projectile.projectilePosition;
267
268 DrawModel(projModel, projectileWorld, 0.5f);
269 }
270 }
271
272 for (int counter = 0; counter < maxAsteroids; counter++)
273 {
274 Asteroid asteroid = null;
275 asteroid = asteroids[counter];
276
277 if (asteroid != null)
278 DrawModel(asteroidModel, asteroid.World, 0.2f);
279 }
280
281 spriteBatch.Begin();
282 DrawText();
283 spriteBatch.End();
284
285 base.Draw(gameTime);
286 }
287
288 /// <summary>
289 /// Simple model drawing method. The interesting part here is that
290 /// the view and projection matrices are taken from the camera object.
291 /// </summary>
292 private void DrawModel(Model model, Matrix world, float scale)
293 {
294 Matrix[] transforms = new Matrix[model.Bones.Count];
295 model.CopyAbsoluteBoneTransformsTo(transforms);
296
297 foreach (ModelMesh mesh in model.Meshes)
298 {
299 foreach (BasicEffect effect in mesh.Effects)
300 {
301 effect.EnableDefaultLighting();
302 effect.PreferPerPixelLighting = true;
303 effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(scale) * world;
304
305 effect.View = camera.view;
306 effect.Projection = camera.projection;
307 }
308 mesh.Draw();
309 }
310 }
311
312 // Draw the Text
313 private void DrawText()
314 {
315 spriteBatch.DrawString(fontScore, "Player Score: " + playerScore.ToString(), new Vector2(300, 45), Color.White);
316 }
317 #endregion
318 }
319
320 #region Entry
321
322 static class Program
323 {
324 /// <summary>
325 /// The main entry point for the application.
326 /// </summary>
327 static void Main(string[] args)
328 {
329 using (TheSingularity game = new TheSingularity())
330 {
331 game.Run();
332 }
333 }
334 }
335
336 #endregion
337 }