mirror of
https://github.com/Memorix101/UnityXNA/
synced 2024-12-30 15:25:35 +01:00
The XNA 4.0 PlatformerGame sample is successfully running inside Unity3D 3.5. Implemented a basic game loop, game timing, content loading for Texture2D, SoundEffect and Song. Emulated SpriteBatch drawing for sprites and strings (note SpriteFont is not yet supported to all strings are rendered using the default GUI label font). Songs can be played using an AudioSource attached to the XNATest game object which acts as an emulator for MediaPlayer. Playing a SoundEffect creates a game object with an AudioSource attached which is automatically deleted when the sound finishes. Implemented keyboard input with a limited set of XNA Keys mapping to Unity3D KeyCodes.
257 lines
9.0 KiB
C#
257 lines
9.0 KiB
C#
#region File Description
|
|
//-----------------------------------------------------------------------------
|
|
// PlatformerGame.cs
|
|
//
|
|
// Microsoft XNA Community Game Platform
|
|
// Copyright (C) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
#endregion
|
|
|
|
using System;
|
|
using System.IO;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using Microsoft.Xna.Framework.Input;
|
|
using Microsoft.Xna.Framework.Media;
|
|
using Microsoft.Xna.Framework.Input.Touch;
|
|
|
|
|
|
namespace Platformer
|
|
{
|
|
/// <summary>
|
|
/// This is the main type for your game
|
|
/// </summary>
|
|
public class PlatformerGame : Microsoft.Xna.Framework.Game
|
|
{
|
|
// Resources for drawing.
|
|
private GraphicsDeviceManager graphics;
|
|
private SpriteBatch spriteBatch;
|
|
|
|
// Global content.
|
|
private SpriteFont hudFont;
|
|
|
|
private Texture2D winOverlay;
|
|
private Texture2D loseOverlay;
|
|
private Texture2D diedOverlay;
|
|
|
|
// Meta-level game state.
|
|
private int levelIndex = -1;
|
|
private Level level;
|
|
private bool wasContinuePressed;
|
|
|
|
// When the time remaining is less than the warning time, it blinks on the hud
|
|
private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);
|
|
|
|
// We store our input states so that we only poll once per frame,
|
|
// then we use the same input state wherever needed
|
|
private GamePadState gamePadState;
|
|
private KeyboardState keyboardState;
|
|
private TouchCollection touchState;
|
|
private AccelerometerState accelerometerState;
|
|
|
|
// The number of levels in the Levels directory of our content. We assume that
|
|
// levels in our content are 0-based and that all numbers under this constant
|
|
// have a level file present. This allows us to not need to check for the file
|
|
// or handle exceptions, both of which can add unnecessary time to level loading.
|
|
private const int numberOfLevels = 3;
|
|
|
|
public PlatformerGame()
|
|
{
|
|
graphics = new GraphicsDeviceManager(this);
|
|
Content.RootDirectory = "Content";
|
|
|
|
#if WINDOWS_PHONE
|
|
graphics.IsFullScreen = true;
|
|
TargetElapsedTime = TimeSpan.FromTicks(333333);
|
|
#endif
|
|
|
|
Accelerometer.Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// LoadContent will be called once per game and is the place to load
|
|
/// all of your content.
|
|
/// </summary>
|
|
protected override void LoadContent()
|
|
{
|
|
// Create a new SpriteBatch, which can be used to draw textures.
|
|
spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
|
|
// Load fonts
|
|
hudFont = Content.Load<SpriteFont>("Fonts/Hud");
|
|
|
|
// Load overlay textures
|
|
winOverlay = Content.Load<Texture2D>("Overlays/you_win");
|
|
loseOverlay = Content.Load<Texture2D>("Overlays/you_lose");
|
|
diedOverlay = Content.Load<Texture2D>("Overlays/you_died");
|
|
|
|
//Known issue that you get exceptions if you use Media PLayer while connected to your PC
|
|
//See http://social.msdn.microsoft.com/Forums/en/windowsphone7series/thread/c8a243d2-d360-46b1-96bd-62b1ef268c66
|
|
//Which means its impossible to test this from VS.
|
|
//So we have to catch the exception and throw it away
|
|
try
|
|
{
|
|
MediaPlayer.IsRepeating = true;
|
|
MediaPlayer.Play(Content.Load<Song>("Sounds/Music"));
|
|
}
|
|
catch { }
|
|
|
|
LoadNextLevel();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allows the game to run logic such as updating the world,
|
|
/// checking for collisions, gathering input, and playing audio.
|
|
/// </summary>
|
|
/// <param name="gameTime">Provides a snapshot of timing values.</param>
|
|
protected override void Update(GameTime gameTime)
|
|
{
|
|
// Handle polling for our input and handling high-level input
|
|
HandleInput();
|
|
|
|
// update our level, passing down the GameTime along with all of our input states
|
|
level.Update(gameTime, keyboardState, gamePadState, touchState,
|
|
accelerometerState, Window.CurrentOrientation);
|
|
|
|
base.Update(gameTime);
|
|
}
|
|
|
|
private void HandleInput()
|
|
{
|
|
// get all of our input states
|
|
keyboardState = Keyboard.GetState();
|
|
gamePadState = GamePad.GetState(PlayerIndex.One);
|
|
touchState = TouchPanel.GetState();
|
|
accelerometerState = Accelerometer.GetState();
|
|
|
|
// Exit the game when back is pressed.
|
|
if (gamePadState.Buttons.Back == ButtonState.Pressed)
|
|
Exit();
|
|
|
|
bool continuePressed =
|
|
keyboardState.IsKeyDown(Keys.Space) ||
|
|
gamePadState.IsButtonDown(Buttons.A) ||
|
|
touchState.AnyTouch();
|
|
|
|
// Perform the appropriate action to advance the game and
|
|
// to get the player back to playing.
|
|
if (!wasContinuePressed && continuePressed)
|
|
{
|
|
if (!level.Player.IsAlive)
|
|
{
|
|
level.StartNewLife();
|
|
}
|
|
else if (level.TimeRemaining == TimeSpan.Zero)
|
|
{
|
|
if (level.ReachedExit)
|
|
LoadNextLevel();
|
|
else
|
|
ReloadCurrentLevel();
|
|
}
|
|
}
|
|
|
|
wasContinuePressed = continuePressed;
|
|
}
|
|
|
|
private void LoadNextLevel()
|
|
{
|
|
// move to the next level
|
|
levelIndex = (levelIndex + 1) % numberOfLevels;
|
|
|
|
// Unloads the content for the current level before loading the next one.
|
|
if (level != null)
|
|
level.Dispose();
|
|
|
|
// Load the level.
|
|
string levelPath = string.Format("Content/Levels/{0}.txt", levelIndex);
|
|
using (Stream fileStream = TitleContainer.OpenStream(levelPath))
|
|
level = new Level(Services, fileStream, levelIndex);
|
|
}
|
|
|
|
private void ReloadCurrentLevel()
|
|
{
|
|
--levelIndex;
|
|
LoadNextLevel();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the game from background to foreground.
|
|
/// </summary>
|
|
/// <param name="gameTime">Provides a snapshot of timing values.</param>
|
|
protected override void Draw(GameTime gameTime)
|
|
{
|
|
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
|
|
|
|
spriteBatch.Begin();
|
|
|
|
level.Draw(gameTime, spriteBatch);
|
|
|
|
DrawHud();
|
|
|
|
spriteBatch.End();
|
|
|
|
base.Draw(gameTime);
|
|
}
|
|
|
|
private void DrawHud()
|
|
{
|
|
Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea;
|
|
Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
|
|
Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
|
|
titleSafeArea.Y + titleSafeArea.Height / 2.0f);
|
|
|
|
// Draw time remaining. Uses modulo division to cause blinking when the
|
|
// player is running out of time.
|
|
string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
|
|
Color timeColor;
|
|
if (level.TimeRemaining > WarningTime ||
|
|
level.ReachedExit ||
|
|
(int)level.TimeRemaining.TotalSeconds % 2 == 0)
|
|
{
|
|
timeColor = Color.Yellow;
|
|
}
|
|
else
|
|
{
|
|
timeColor = Color.Red;
|
|
}
|
|
DrawShadowedString(hudFont, timeString, hudLocation, timeColor);
|
|
|
|
// Draw score
|
|
float timeHeight = hudFont.MeasureString(timeString).Y;
|
|
DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);
|
|
|
|
// Determine the status overlay message to show.
|
|
Texture2D status = null;
|
|
if (level.TimeRemaining == TimeSpan.Zero)
|
|
{
|
|
if (level.ReachedExit)
|
|
{
|
|
status = winOverlay;
|
|
}
|
|
else
|
|
{
|
|
status = loseOverlay;
|
|
}
|
|
}
|
|
else if (!level.Player.IsAlive)
|
|
{
|
|
status = diedOverlay;
|
|
}
|
|
|
|
if (status != null)
|
|
{
|
|
// Draw status message.
|
|
Vector2 statusSize = new Vector2(status.Width, status.Height);
|
|
spriteBatch.Draw(status, center - statusSize / 2, Color.White);
|
|
}
|
|
}
|
|
|
|
private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
|
|
{
|
|
spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
|
|
spriteBatch.DrawString(font, value, position, color);
|
|
}
|
|
}
|
|
}
|