Adding initial files
This commit is contained in:
74
axios/ScreenSystem/BackgroundScreen.cs
Normal file
74
axios/ScreenSystem/BackgroundScreen.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// The background screen sits behind all the other menu screens.
|
||||
/// It draws a background image that remains fixed in place regardless
|
||||
/// of whatever transitions the screens on top of it may be doing.
|
||||
/// </summary>
|
||||
public class BackgroundScreen : GameScreen
|
||||
{
|
||||
private const float LogoScreenHeightRatio = 0.25f;
|
||||
private const float LogoScreenBorderRatio = 0.0375f;
|
||||
private const float LogoWidthHeightRatio = 1.4f;
|
||||
|
||||
private Texture2D _backgroundTexture;
|
||||
private Rectangle _logoDestination;
|
||||
//private Texture2D _logoTexture;
|
||||
private Rectangle _viewport;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public BackgroundScreen()
|
||||
{
|
||||
TransitionOnTime = TimeSpan.FromSeconds(0.5);
|
||||
TransitionOffTime = TimeSpan.FromSeconds(0.5);
|
||||
}
|
||||
|
||||
public override void LoadContent()
|
||||
{
|
||||
//_logoTexture = ScreenManager.Content.Load<Texture2D>("Common/logo");
|
||||
_backgroundTexture = ScreenManager.Content.Load<Texture2D>("Common/gradient");
|
||||
|
||||
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
|
||||
Vector2 logoSize = new Vector2();
|
||||
logoSize.Y = viewport.Height * LogoScreenHeightRatio;
|
||||
logoSize.X = logoSize.Y * LogoWidthHeightRatio;
|
||||
|
||||
float border = viewport.Height * LogoScreenBorderRatio;
|
||||
Vector2 logoPosition = new Vector2(viewport.Width - border - logoSize.X,
|
||||
viewport.Height - border - logoSize.Y);
|
||||
_logoDestination = new Rectangle((int)logoPosition.X, (int)logoPosition.Y, (int)logoSize.X,
|
||||
(int)logoSize.Y);
|
||||
_viewport = viewport.Bounds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the background screen. Unlike most screens, this should not
|
||||
/// transition off even if it has been covered by another screen: it is
|
||||
/// supposed to be covered, after all! This overload forces the
|
||||
/// coveredByOtherScreen parameter to false in order to stop the base
|
||||
/// Update method wanting to transition off.
|
||||
/// </summary>
|
||||
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
|
||||
bool coveredByOtherScreen)
|
||||
{
|
||||
base.Update(gameTime, otherScreenHasFocus, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the background screen.
|
||||
/// </summary>
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
ScreenManager.SpriteBatch.Begin();
|
||||
ScreenManager.SpriteBatch.Draw(_backgroundTexture, _viewport, Color.White);
|
||||
//ScreenManager.SpriteBatch.Draw(_logoTexture, _logoDestination, Color.White * 0.6f);
|
||||
ScreenManager.SpriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
369
axios/ScreenSystem/Camera2D.cs
Normal file
369
axios/ScreenSystem/Camera2D.cs
Normal file
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public class Camera2D
|
||||
{
|
||||
private const float _minZoom = 0.02f;
|
||||
private const float _maxZoom = 20f;
|
||||
private static GraphicsDevice _graphics;
|
||||
|
||||
private Matrix _batchView;
|
||||
|
||||
private Vector2 _currentPosition;
|
||||
|
||||
private float _currentRotation;
|
||||
|
||||
private float _currentZoom;
|
||||
private Vector2 _maxPosition;
|
||||
private float _maxRotation;
|
||||
private Vector2 _minPosition;
|
||||
private float _minRotation;
|
||||
private bool _positionTracking;
|
||||
private Matrix _projection;
|
||||
private bool _rotationTracking;
|
||||
private Vector2 _targetPosition;
|
||||
private float _targetRotation;
|
||||
private Body _trackingBody;
|
||||
private Vector2 _translateCenter;
|
||||
private Matrix _view;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor for the Camera2D class.
|
||||
/// </summary>
|
||||
/// <param name="graphics"></param>
|
||||
public Camera2D(GraphicsDevice graphics)
|
||||
{
|
||||
_graphics = graphics;
|
||||
_projection = Matrix.CreateOrthographicOffCenter(0f, ConvertUnits.ToSimUnits(_graphics.Viewport.Width),
|
||||
ConvertUnits.ToSimUnits(_graphics.Viewport.Height), 0f, 0f,
|
||||
1f);
|
||||
_view = Matrix.Identity;
|
||||
_batchView = Matrix.Identity;
|
||||
|
||||
_translateCenter = new Vector2(ConvertUnits.ToSimUnits(_graphics.Viewport.Width / 2f),
|
||||
ConvertUnits.ToSimUnits(_graphics.Viewport.Height / 2f));
|
||||
|
||||
ResetCamera();
|
||||
}
|
||||
|
||||
public Matrix View
|
||||
{
|
||||
get { return _batchView; }
|
||||
}
|
||||
|
||||
public Matrix SimView
|
||||
{
|
||||
get { return _view; }
|
||||
}
|
||||
|
||||
public Matrix SimProjection
|
||||
{
|
||||
get { return _projection; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current position of the camera.
|
||||
/// </summary>
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(_currentPosition); }
|
||||
set
|
||||
{
|
||||
_targetPosition = ConvertUnits.ToSimUnits(value);
|
||||
if (_minPosition != _maxPosition)
|
||||
{
|
||||
Vector2.Clamp(ref _targetPosition, ref _minPosition, ref _maxPosition, out _targetPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The furthest up, and the furthest left the camera can go.
|
||||
/// if this value equals maxPosition, then no clamping will be
|
||||
/// applied (unless you override that function).
|
||||
/// </summary>
|
||||
public Vector2 MinPosition
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(_minPosition); }
|
||||
set { _minPosition = ConvertUnits.ToSimUnits(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the furthest down, and the furthest right the camera will go.
|
||||
/// if this value equals minPosition, then no clamping will be
|
||||
/// applied (unless you override that function).
|
||||
/// </summary>
|
||||
public Vector2 MaxPosition
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(_maxPosition); }
|
||||
set { _maxPosition = ConvertUnits.ToSimUnits(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current rotation of the camera in radians.
|
||||
/// </summary>
|
||||
public float Rotation
|
||||
{
|
||||
get { return _currentRotation; }
|
||||
set
|
||||
{
|
||||
_targetRotation = value % MathHelper.TwoPi;
|
||||
if (_minRotation != _maxRotation)
|
||||
{
|
||||
_targetRotation = MathHelper.Clamp(_targetRotation, _minRotation, _maxRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum rotation in radians.
|
||||
/// </summary>
|
||||
/// <value>The min rotation.</value>
|
||||
public float MinRotation
|
||||
{
|
||||
get { return _minRotation; }
|
||||
set { _minRotation = MathHelper.Clamp(value, -MathHelper.Pi, 0f); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum rotation in radians.
|
||||
/// </summary>
|
||||
/// <value>The max rotation.</value>
|
||||
public float MaxRotation
|
||||
{
|
||||
get { return _maxRotation; }
|
||||
set { _maxRotation = MathHelper.Clamp(value, 0f, MathHelper.Pi); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current rotation of the camera in radians.
|
||||
/// </summary>
|
||||
public float Zoom
|
||||
{
|
||||
get { return _currentZoom; }
|
||||
set
|
||||
{
|
||||
_currentZoom = value;
|
||||
_currentZoom = MathHelper.Clamp(_currentZoom, _minZoom, _maxZoom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the body that this camera is currently tracking.
|
||||
/// Null if not tracking any.
|
||||
/// </summary>
|
||||
public Body TrackingBody
|
||||
{
|
||||
get { return _trackingBody; }
|
||||
set
|
||||
{
|
||||
_trackingBody = value;
|
||||
if (_trackingBody != null)
|
||||
{
|
||||
_positionTracking = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnablePositionTracking
|
||||
{
|
||||
get { return _positionTracking; }
|
||||
set
|
||||
{
|
||||
if (value && _trackingBody != null)
|
||||
{
|
||||
_positionTracking = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_positionTracking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableRotationTracking
|
||||
{
|
||||
get { return _rotationTracking; }
|
||||
set
|
||||
{
|
||||
if (value && _trackingBody != null)
|
||||
{
|
||||
_rotationTracking = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rotationTracking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableTracking
|
||||
{
|
||||
set
|
||||
{
|
||||
EnablePositionTracking = value;
|
||||
EnableRotationTracking = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveCamera(Vector2 amount)
|
||||
{
|
||||
_currentPosition += amount;
|
||||
if (_minPosition != _maxPosition)
|
||||
{
|
||||
Vector2.Clamp(ref _currentPosition, ref _minPosition, ref _maxPosition, out _currentPosition);
|
||||
}
|
||||
_targetPosition = _currentPosition;
|
||||
_positionTracking = false;
|
||||
_rotationTracking = false;
|
||||
}
|
||||
|
||||
public void RotateCamera(float amount)
|
||||
{
|
||||
_currentRotation += amount;
|
||||
if (_minRotation != _maxRotation)
|
||||
{
|
||||
_currentRotation = MathHelper.Clamp(_currentRotation, _minRotation, _maxRotation);
|
||||
}
|
||||
_targetRotation = _currentRotation;
|
||||
_positionTracking = false;
|
||||
_rotationTracking = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the camera to default values.
|
||||
/// </summary>
|
||||
public void ResetCamera()
|
||||
{
|
||||
_currentPosition = Vector2.Zero;
|
||||
_targetPosition = Vector2.Zero;
|
||||
_minPosition = Vector2.Zero;
|
||||
_maxPosition = Vector2.Zero;
|
||||
|
||||
_currentRotation = 0f;
|
||||
_targetRotation = 0f;
|
||||
_minRotation = -MathHelper.Pi;
|
||||
_maxRotation = MathHelper.Pi;
|
||||
|
||||
_positionTracking = false;
|
||||
_rotationTracking = false;
|
||||
|
||||
_currentZoom = 1f;
|
||||
|
||||
SetView();
|
||||
}
|
||||
|
||||
public void Jump2Target()
|
||||
{
|
||||
_currentPosition = _targetPosition;
|
||||
_currentRotation = _targetRotation;
|
||||
|
||||
SetView();
|
||||
}
|
||||
|
||||
private void SetView()
|
||||
{
|
||||
Matrix matRotation = Matrix.CreateRotationZ(_currentRotation);
|
||||
Matrix matZoom = Matrix.CreateScale(_currentZoom);
|
||||
Vector3 translateCenter = new Vector3(_translateCenter, 0f);
|
||||
Vector3 translateBody = new Vector3(-_currentPosition, 0f);
|
||||
|
||||
_view = Matrix.CreateTranslation(translateBody) *
|
||||
matRotation *
|
||||
matZoom *
|
||||
Matrix.CreateTranslation(translateCenter);
|
||||
|
||||
translateCenter = ConvertUnits.ToDisplayUnits(translateCenter);
|
||||
translateBody = ConvertUnits.ToDisplayUnits(translateBody);
|
||||
|
||||
_batchView = Matrix.CreateTranslation(translateBody) *
|
||||
matRotation *
|
||||
matZoom *
|
||||
Matrix.CreateTranslation(translateCenter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the camera forward one timestep.
|
||||
/// </summary>
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
if (_trackingBody != null)
|
||||
{
|
||||
if (_positionTracking)
|
||||
{
|
||||
_targetPosition = _trackingBody.Position;
|
||||
if (_minPosition != _maxPosition)
|
||||
{
|
||||
Vector2.Clamp(ref _targetPosition, ref _minPosition, ref _maxPosition, out _targetPosition);
|
||||
}
|
||||
}
|
||||
if (_rotationTracking)
|
||||
{
|
||||
_targetRotation = -_trackingBody.Rotation % MathHelper.TwoPi;
|
||||
if (_minRotation != _maxRotation)
|
||||
{
|
||||
_targetRotation = MathHelper.Clamp(_targetRotation, _minRotation, _maxRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector2 delta = _targetPosition - _currentPosition;
|
||||
float distance = delta.Length();
|
||||
if (distance > 0f)
|
||||
{
|
||||
delta /= distance;
|
||||
}
|
||||
float inertia;
|
||||
if (distance < 10f)
|
||||
{
|
||||
inertia = (float) Math.Pow(distance / 10.0, 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
inertia = 1f;
|
||||
}
|
||||
|
||||
float rotDelta = _targetRotation - _currentRotation;
|
||||
|
||||
float rotInertia;
|
||||
if (Math.Abs(rotDelta) < 5f)
|
||||
{
|
||||
rotInertia = (float) Math.Pow(rotDelta / 5.0, 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rotInertia = 1f;
|
||||
}
|
||||
if (Math.Abs(rotDelta) > 0f)
|
||||
{
|
||||
rotDelta /= Math.Abs(rotDelta);
|
||||
}
|
||||
|
||||
_currentPosition += 100f * delta * inertia * (float) gameTime.ElapsedGameTime.TotalSeconds;
|
||||
_currentRotation += 80f * rotDelta * rotInertia * (float) gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
SetView();
|
||||
}
|
||||
|
||||
public Vector2 ConvertScreenToWorld(Vector2 location)
|
||||
{
|
||||
Vector3 t = new Vector3(location, 0);
|
||||
|
||||
t = _graphics.Viewport.Unproject(t, _projection, _view, Matrix.Identity);
|
||||
|
||||
return new Vector2(t.X, t.Y);
|
||||
}
|
||||
|
||||
public Vector2 ConvertWorldToScreen(Vector2 location)
|
||||
{
|
||||
Vector3 t = new Vector3(location, 0);
|
||||
|
||||
t = _graphics.Viewport.Project(t, _projection, _view, Matrix.Identity);
|
||||
|
||||
return new Vector2(t.X, t.Y);
|
||||
}
|
||||
}
|
||||
}
|
103
axios/ScreenSystem/ConvertUnits.cs
Normal file
103
axios/ScreenSystem/ConvertUnits.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert units between display and simulation units.
|
||||
/// </summary>
|
||||
public static class ConvertUnits
|
||||
{
|
||||
private static float _displayUnitsToSimUnitsRatio = 100f;
|
||||
private static float _simUnitsToDisplayUnitsRatio = 1 / _displayUnitsToSimUnitsRatio;
|
||||
|
||||
public static void SetDisplayUnitToSimUnitRatio(float displayUnitsPerSimUnit)
|
||||
{
|
||||
_displayUnitsToSimUnitsRatio = displayUnitsPerSimUnit;
|
||||
_simUnitsToDisplayUnitsRatio = 1 / displayUnitsPerSimUnit;
|
||||
}
|
||||
|
||||
public static float ToDisplayUnits(float simUnits)
|
||||
{
|
||||
return simUnits * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static float ToDisplayUnits(int simUnits)
|
||||
{
|
||||
return simUnits * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static Vector2 ToDisplayUnits(Vector2 simUnits)
|
||||
{
|
||||
return simUnits * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static void ToDisplayUnits(ref Vector2 simUnits, out Vector2 displayUnits)
|
||||
{
|
||||
Vector2.Multiply(ref simUnits, _displayUnitsToSimUnitsRatio, out displayUnits);
|
||||
}
|
||||
|
||||
public static Vector3 ToDisplayUnits(Vector3 simUnits)
|
||||
{
|
||||
return simUnits * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static Vector2 ToDisplayUnits(float x, float y)
|
||||
{
|
||||
return new Vector2(x, y) * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static void ToDisplayUnits(float x, float y, out Vector2 displayUnits)
|
||||
{
|
||||
displayUnits = Vector2.Zero;
|
||||
displayUnits.X = x * _displayUnitsToSimUnitsRatio;
|
||||
displayUnits.Y = y * _displayUnitsToSimUnitsRatio;
|
||||
}
|
||||
|
||||
public static float ToSimUnits(float displayUnits)
|
||||
{
|
||||
return displayUnits * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static float ToSimUnits(double displayUnits)
|
||||
{
|
||||
return (float)displayUnits * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static float ToSimUnits(int displayUnits)
|
||||
{
|
||||
return displayUnits * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static Vector2 ToSimUnits(Vector2 displayUnits)
|
||||
{
|
||||
return displayUnits * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static Vector3 ToSimUnits(Vector3 displayUnits)
|
||||
{
|
||||
return displayUnits * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static void ToSimUnits(ref Vector2 displayUnits, out Vector2 simUnits)
|
||||
{
|
||||
Vector2.Multiply(ref displayUnits, _simUnitsToDisplayUnitsRatio, out simUnits);
|
||||
}
|
||||
|
||||
public static Vector2 ToSimUnits(float x, float y)
|
||||
{
|
||||
return new Vector2(x, y) * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static Vector2 ToSimUnits(double x, double y)
|
||||
{
|
||||
return new Vector2((float)x, (float)y) * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
|
||||
public static void ToSimUnits(float x, float y, out Vector2 simUnits)
|
||||
{
|
||||
simUnits = Vector2.Zero;
|
||||
simUnits.X = x * _simUnitsToDisplayUnitsRatio;
|
||||
simUnits.Y = y * _simUnitsToDisplayUnitsRatio;
|
||||
}
|
||||
}
|
||||
}
|
57
axios/ScreenSystem/FramerateCounterComponent.cs
Normal file
57
axios/ScreenSystem/FramerateCounterComponent.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays the FPS
|
||||
/// </summary>
|
||||
public class FrameRateCounter : DrawableGameComponent
|
||||
{
|
||||
private TimeSpan _elapsedTime = TimeSpan.Zero;
|
||||
private NumberFormatInfo _format;
|
||||
private int _frameCounter;
|
||||
private int _frameRate;
|
||||
private Vector2 _position;
|
||||
private ScreenManager _screenManager;
|
||||
|
||||
public FrameRateCounter(ScreenManager screenManager)
|
||||
: base(screenManager.Game)
|
||||
{
|
||||
_screenManager = screenManager;
|
||||
_format = new NumberFormatInfo();
|
||||
_format.NumberDecimalSeparator = ".";
|
||||
#if XBOX
|
||||
_position = new Vector2(55, 35);
|
||||
#else
|
||||
_position = new Vector2(30, 25);
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
_elapsedTime += gameTime.ElapsedGameTime;
|
||||
|
||||
if (_elapsedTime <= TimeSpan.FromSeconds(1)) return;
|
||||
|
||||
_elapsedTime -= TimeSpan.FromSeconds(1);
|
||||
_frameRate = _frameCounter;
|
||||
_frameCounter = 0;
|
||||
}
|
||||
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
_frameCounter++;
|
||||
|
||||
string fps = string.Format(_format, "{0} fps", _frameRate);
|
||||
|
||||
_screenManager.SpriteBatch.Begin();
|
||||
_screenManager.SpriteBatch.DrawString(_screenManager.Fonts.FrameRateCounterFont, fps,
|
||||
_position + Vector2.One, Color.Black);
|
||||
_screenManager.SpriteBatch.DrawString(_screenManager.Fonts.FrameRateCounterFont, fps,
|
||||
_position, Color.White);
|
||||
_screenManager.SpriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
285
axios/ScreenSystem/GameScreen.cs
Normal file
285
axios/ScreenSystem/GameScreen.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
#region File Description
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PlayerIndexEventArgs.cs
|
||||
//
|
||||
// XNA Community Game Platform
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum describes the screen transition state.
|
||||
/// </summary>
|
||||
public enum ScreenState
|
||||
{
|
||||
TransitionOn,
|
||||
Active,
|
||||
TransitionOff,
|
||||
Hidden,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A screen is a single layer that has update and draw logic, and which
|
||||
/// can be combined with other layers to build up a complex menu system.
|
||||
/// For instance the main menu, the options menu, the "are you sure you
|
||||
/// want to quit" message box, and the main game itself are all implemented
|
||||
/// as screens.
|
||||
/// </summary>
|
||||
public abstract class GameScreen
|
||||
{
|
||||
private GestureType _enabledGestures = GestureType.None;
|
||||
private bool _otherScreenHasFocus;
|
||||
|
||||
public GameScreen()
|
||||
{
|
||||
ScreenState = ScreenState.TransitionOn;
|
||||
TransitionPosition = 1;
|
||||
TransitionOffTime = TimeSpan.Zero;
|
||||
TransitionOnTime = TimeSpan.Zero;
|
||||
HasCursor = false;
|
||||
HasVirtualStick = false;
|
||||
}
|
||||
|
||||
public bool HasCursor { get; set; }
|
||||
|
||||
public bool HasVirtualStick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normally when one screen is brought up over the top of another,
|
||||
/// the first screen will transition off to make room for the new
|
||||
/// one. This property indicates whether the screen is only a small
|
||||
/// popup, in which case screens underneath it do not need to bother
|
||||
/// transitioning off.
|
||||
/// </summary>
|
||||
public bool IsPopup { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates how long the screen takes to
|
||||
/// transition on when it is activated.
|
||||
/// </summary>
|
||||
public TimeSpan TransitionOnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates how long the screen takes to
|
||||
/// transition off when it is deactivated.
|
||||
/// </summary>
|
||||
public TimeSpan TransitionOffTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current position of the screen transition, ranging
|
||||
/// from zero (fully active, no transition) to one (transitioned
|
||||
/// fully off to nothing).
|
||||
/// </summary>
|
||||
public float TransitionPosition { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current alpha of the screen transition, ranging
|
||||
/// from 1 (fully active, no transition) to 0 (transitioned
|
||||
/// fully off to nothing).
|
||||
/// </summary>
|
||||
public float TransitionAlpha
|
||||
{
|
||||
get { return 1f - TransitionPosition; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current screen transition state.
|
||||
/// </summary>
|
||||
public ScreenState ScreenState { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// There are two possible reasons why a screen might be transitioning
|
||||
/// off. It could be temporarily going away to make room for another
|
||||
/// screen that is on top of it, or it could be going away for good.
|
||||
/// This property indicates whether the screen is exiting for real:
|
||||
/// if set, the screen will automatically remove itself as soon as the
|
||||
/// transition finishes.
|
||||
/// </summary>
|
||||
public bool IsExiting { get; protected internal set; }
|
||||
|
||||
public bool AlwaysHasFocus = false;
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this screen is active and can respond to user input.
|
||||
/// </summary>
|
||||
public bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return !_otherScreenHasFocus &&
|
||||
(ScreenState == ScreenState.TransitionOn ||
|
||||
ScreenState == ScreenState.Active);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manager that this screen belongs to.
|
||||
/// </summary>
|
||||
public ScreenManager ScreenManager { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gestures the screen is interested in. Screens should be as specific
|
||||
/// as possible with gestures to increase the accuracy of the gesture engine.
|
||||
/// For example, most menus only need Tap or perhaps Tap and VerticalDrag to operate.
|
||||
/// These gestures are handled by the ScreenManager when screens change and
|
||||
/// all gestures are placed in the InputState passed to the HandleInput method.
|
||||
/// </summary>
|
||||
public GestureType EnabledGestures
|
||||
{
|
||||
get { return _enabledGestures; }
|
||||
protected set
|
||||
{
|
||||
_enabledGestures = value;
|
||||
|
||||
// the screen manager handles this during screen changes, but
|
||||
// if this screen is active and the gesture types are changing,
|
||||
// we have to update the TouchPanel ourself.
|
||||
if (ScreenState == ScreenState.Active)
|
||||
{
|
||||
TouchPanel.EnabledGestures = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load graphics content for the screen.
|
||||
/// </summary>
|
||||
public virtual void LoadContent()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unload content for the screen.
|
||||
/// </summary>
|
||||
public virtual void UnloadContent()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the screen to run logic, such as updating the transition position.
|
||||
/// Unlike HandleInput, this method is called regardless of whether the screen
|
||||
/// is active, hidden, or in the middle of a transition.
|
||||
/// </summary>
|
||||
public virtual void Update(GameTime gameTime, bool otherScreenHasFocus,
|
||||
bool coveredByOtherScreen)
|
||||
{
|
||||
_otherScreenHasFocus = otherScreenHasFocus;
|
||||
|
||||
if (IsExiting)
|
||||
{
|
||||
// If the screen is going away to die, it should transition off.
|
||||
ScreenState = ScreenState.TransitionOff;
|
||||
|
||||
if (!UpdateTransition(gameTime, TransitionOffTime, 1))
|
||||
{
|
||||
// When the transition finishes, remove the screen.
|
||||
ScreenManager.RemoveScreen(this);
|
||||
}
|
||||
}
|
||||
else if (coveredByOtherScreen)
|
||||
{
|
||||
// If the screen is covered by another, it should transition off.
|
||||
if (UpdateTransition(gameTime, TransitionOffTime, 1))
|
||||
{
|
||||
// Still busy transitioning.
|
||||
ScreenState = ScreenState.TransitionOff;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transition finished!
|
||||
ScreenState = ScreenState.Hidden;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise the screen should transition on and become active.
|
||||
if (UpdateTransition(gameTime, TransitionOnTime, -1))
|
||||
{
|
||||
// Still busy transitioning.
|
||||
ScreenState = ScreenState.TransitionOn;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transition finished!
|
||||
ScreenState = ScreenState.Active;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for updating the screen transition position.
|
||||
/// </summary>
|
||||
private bool UpdateTransition(GameTime gameTime, TimeSpan time, int direction)
|
||||
{
|
||||
// How much should we move by?
|
||||
float transitionDelta;
|
||||
|
||||
if (time == TimeSpan.Zero)
|
||||
{
|
||||
transitionDelta = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
transitionDelta = (float)(gameTime.ElapsedGameTime.TotalMilliseconds /
|
||||
time.TotalMilliseconds);
|
||||
}
|
||||
|
||||
// Update the transition position.
|
||||
TransitionPosition += transitionDelta * direction;
|
||||
|
||||
// Did we reach the end of the transition?
|
||||
if (((direction < 0) && (TransitionPosition <= 0)) ||
|
||||
((direction > 0) && (TransitionPosition >= 1)))
|
||||
{
|
||||
TransitionPosition = MathHelper.Clamp(TransitionPosition, 0, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise we are still busy transitioning.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the screen to handle user input. Unlike Update, this method
|
||||
/// is only called when the screen is active, and not when some other
|
||||
/// screen has taken the focus.
|
||||
/// </summary>
|
||||
public virtual void HandleInput(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the screen should draw itself.
|
||||
/// </summary>
|
||||
public virtual void Draw(GameTime gameTime)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the screen to go away. Unlike ScreenManager.RemoveScreen, which
|
||||
/// instantly kills the screen, this method respects the transition timings
|
||||
/// and will give the screen a chance to gradually transition off.
|
||||
/// </summary>
|
||||
public virtual void ExitScreen()
|
||||
{
|
||||
if (TransitionOffTime == TimeSpan.Zero)
|
||||
{
|
||||
// If the screen has a zero transition time, remove it immediately.
|
||||
ScreenManager.RemoveScreen(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise flag that it should transition off and then exit.
|
||||
IsExiting = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
axios/ScreenSystem/IDemoScreen.cs
Normal file
8
axios/ScreenSystem/IDemoScreen.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public interface IDemoScreen
|
||||
{
|
||||
string GetTitle();
|
||||
string GetDetails();
|
||||
}
|
||||
}
|
469
axios/ScreenSystem/InputHelper.cs
Normal file
469
axios/ScreenSystem/InputHelper.cs
Normal file
@@ -0,0 +1,469 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// an enum of all available mouse buttons.
|
||||
/// </summary>
|
||||
public enum MouseButtons
|
||||
{
|
||||
LeftButton,
|
||||
MiddleButton,
|
||||
RightButton,
|
||||
ExtraButton1,
|
||||
ExtraButton2
|
||||
}
|
||||
|
||||
public class InputHelper
|
||||
{
|
||||
private readonly List<GestureSample> _gestures = new List<GestureSample>();
|
||||
private GamePadState _currentGamePadState;
|
||||
private KeyboardState _currentKeyboardState;
|
||||
private MouseState _currentMouseState;
|
||||
private GamePadState _currentVirtualState;
|
||||
|
||||
private GamePadState _lastGamePadState;
|
||||
private KeyboardState _lastKeyboardState;
|
||||
private MouseState _lastMouseState;
|
||||
private GamePadState _lastVirtualState;
|
||||
private bool _handleVirtualStick;
|
||||
|
||||
private Vector2 _cursor;
|
||||
private bool _cursorIsValid;
|
||||
private bool _cursorIsVisible;
|
||||
private bool _cursorMoved;
|
||||
private Sprite _cursorSprite;
|
||||
|
||||
#if WINDOWS_PHONE
|
||||
private VirtualStick _phoneStick;
|
||||
private VirtualButton _phoneA;
|
||||
private VirtualButton _phoneB;
|
||||
#endif
|
||||
|
||||
private ScreenManager _manager;
|
||||
private Viewport _viewport;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new input state.
|
||||
/// </summary>
|
||||
public InputHelper(ScreenManager manager)
|
||||
{
|
||||
_currentKeyboardState = new KeyboardState();
|
||||
_currentGamePadState = new GamePadState();
|
||||
_currentMouseState = new MouseState();
|
||||
_currentVirtualState = new GamePadState();
|
||||
|
||||
_lastKeyboardState = new KeyboardState();
|
||||
_lastGamePadState = new GamePadState();
|
||||
_lastMouseState = new MouseState();
|
||||
_lastVirtualState = new GamePadState();
|
||||
|
||||
_manager = manager;
|
||||
|
||||
_cursorIsVisible = false;
|
||||
_cursorMoved = false;
|
||||
#if WINDOWS_PHONE
|
||||
_cursorIsValid = false;
|
||||
#else
|
||||
_cursorIsValid = true;
|
||||
#endif
|
||||
_cursor = Vector2.Zero;
|
||||
|
||||
_handleVirtualStick = false;
|
||||
}
|
||||
|
||||
public GamePadState GamePadState
|
||||
{
|
||||
get { return _currentGamePadState; }
|
||||
}
|
||||
|
||||
public KeyboardState KeyboardState
|
||||
{
|
||||
get { return _currentKeyboardState; }
|
||||
}
|
||||
|
||||
public MouseState MouseState
|
||||
{
|
||||
get { return _currentMouseState; }
|
||||
}
|
||||
|
||||
public GamePadState VirtualState
|
||||
{
|
||||
get { return _currentVirtualState; }
|
||||
}
|
||||
|
||||
public GamePadState PreviousGamePadState
|
||||
{
|
||||
get { return _lastGamePadState; }
|
||||
}
|
||||
|
||||
public KeyboardState PreviousKeyboardState
|
||||
{
|
||||
get { return _lastKeyboardState; }
|
||||
}
|
||||
|
||||
public MouseState PreviousMouseState
|
||||
{
|
||||
get { return _lastMouseState; }
|
||||
}
|
||||
|
||||
public GamePadState PreviousVirtualState
|
||||
{
|
||||
get { return _lastVirtualState; }
|
||||
}
|
||||
|
||||
public bool ShowCursor
|
||||
{
|
||||
get { return _cursorIsVisible && _cursorIsValid; }
|
||||
set { _cursorIsVisible = value; }
|
||||
}
|
||||
|
||||
public bool EnableVirtualStick
|
||||
{
|
||||
get { return _handleVirtualStick; }
|
||||
set { _handleVirtualStick = value; }
|
||||
}
|
||||
|
||||
public Vector2 Cursor
|
||||
{
|
||||
get { return _cursor; }
|
||||
}
|
||||
|
||||
public bool IsCursorMoved
|
||||
{
|
||||
get { return _cursorMoved; }
|
||||
}
|
||||
|
||||
public bool IsCursorValid
|
||||
{
|
||||
get { return _cursorIsValid; }
|
||||
}
|
||||
|
||||
public void LoadContent()
|
||||
{
|
||||
_cursorSprite = new Sprite(_manager.Content.Load<Texture2D>("Common/cursor"));
|
||||
#if WINDOWS_PHONE
|
||||
// virtual stick content
|
||||
_phoneStick = new VirtualStick(_manager.Content.Load<Texture2D>("Common/socket"),
|
||||
_manager.Content.Load<Texture2D>("Common/stick"), new Vector2(80f, 400f));
|
||||
|
||||
Texture2D temp = _manager.Content.Load<Texture2D>("Common/buttons");
|
||||
_phoneA = new VirtualButton(temp, new Vector2(695f, 380f), new Rectangle(0, 0, 40, 40), new Rectangle(0, 40, 40, 40));
|
||||
_phoneB = new VirtualButton(temp, new Vector2(745f, 360f), new Rectangle(40, 0, 40, 40), new Rectangle(40, 40, 40, 40));
|
||||
#endif
|
||||
_viewport = _manager.GraphicsDevice.Viewport;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the latest state of the keyboard and gamepad and mouse/touchpad.
|
||||
/// </summary>
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
_lastKeyboardState = _currentKeyboardState;
|
||||
_lastGamePadState = _currentGamePadState;
|
||||
_lastMouseState = _currentMouseState;
|
||||
if (_handleVirtualStick)
|
||||
{
|
||||
_lastVirtualState = _currentVirtualState;
|
||||
}
|
||||
|
||||
_currentKeyboardState = Keyboard.GetState();
|
||||
_currentGamePadState = GamePad.GetState(PlayerIndex.One);
|
||||
_currentMouseState = Mouse.GetState();
|
||||
|
||||
if (_handleVirtualStick)
|
||||
{
|
||||
#if XBOX
|
||||
_currentVirtualState= GamePad.GetState(PlayerIndex.One);
|
||||
#elif WINDOWS
|
||||
if (GamePad.GetState(PlayerIndex.One).IsConnected)
|
||||
{
|
||||
_currentVirtualState = GamePad.GetState(PlayerIndex.One);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentVirtualState = HandleVirtualStickWin();
|
||||
}
|
||||
#elif WINDOWS_PHONE
|
||||
_currentVirtualState = HandleVirtualStickWP7();
|
||||
#endif
|
||||
}
|
||||
|
||||
_gestures.Clear();
|
||||
while (TouchPanel.IsGestureAvailable)
|
||||
{
|
||||
_gestures.Add(TouchPanel.ReadGesture());
|
||||
}
|
||||
|
||||
// Update cursor
|
||||
Vector2 oldCursor = _cursor;
|
||||
if (_currentGamePadState.IsConnected && _currentGamePadState.ThumbSticks.Left != Vector2.Zero)
|
||||
{
|
||||
Vector2 temp = _currentGamePadState.ThumbSticks.Left;
|
||||
_cursor += temp * new Vector2(300f, -300f) * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
Mouse.SetPosition((int)_cursor.X, (int)_cursor.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cursor.X = _currentMouseState.X;
|
||||
_cursor.Y = _currentMouseState.Y;
|
||||
}
|
||||
_cursor.X = MathHelper.Clamp(_cursor.X, 0f, _viewport.Width);
|
||||
_cursor.Y = MathHelper.Clamp(_cursor.Y, 0f, _viewport.Height);
|
||||
|
||||
if (_cursorIsValid && oldCursor != _cursor)
|
||||
{
|
||||
_cursorMoved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cursorMoved = false;
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
if (_viewport.Bounds.Contains(_currentMouseState.X, _currentMouseState.Y))
|
||||
{
|
||||
_cursorIsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cursorIsValid = false;
|
||||
}
|
||||
#elif WINDOWS_PHONE
|
||||
if (_currentMouseState.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
_cursorIsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cursorIsValid = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (_cursorIsVisible && _cursorIsValid)
|
||||
{
|
||||
_manager.SpriteBatch.Begin();
|
||||
_manager.SpriteBatch.Draw(_cursorSprite.Texture, _cursor, null, Color.White, 0f, _cursorSprite.Origin, 1f, SpriteEffects.None, 0f);
|
||||
_manager.SpriteBatch.End();
|
||||
}
|
||||
#if WINDOWS_PHONE
|
||||
if (_handleVirtualStick)
|
||||
{
|
||||
_manager.SpriteBatch.Begin();
|
||||
_phoneA.Draw(_manager.SpriteBatch);
|
||||
_phoneB.Draw(_manager.SpriteBatch);
|
||||
_phoneStick.Draw(_manager.SpriteBatch);
|
||||
_manager.SpriteBatch.End();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private GamePadState HandleVirtualStickWin()
|
||||
{
|
||||
Vector2 _leftStick = Vector2.Zero;
|
||||
List<Buttons> _buttons = new List<Buttons>();
|
||||
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.A))
|
||||
{
|
||||
_leftStick.X -= 1f;
|
||||
}
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.S))
|
||||
{
|
||||
_leftStick.Y -= 1f;
|
||||
}
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.D))
|
||||
{
|
||||
_leftStick.X += 1f;
|
||||
}
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.W))
|
||||
{
|
||||
_leftStick.Y += 1f;
|
||||
}
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.Space))
|
||||
{
|
||||
_buttons.Add(Buttons.A);
|
||||
}
|
||||
if (_currentKeyboardState.IsKeyDown(Keys.LeftControl))
|
||||
{
|
||||
_buttons.Add(Buttons.B);
|
||||
}
|
||||
if (_leftStick != Vector2.Zero)
|
||||
{
|
||||
_leftStick.Normalize();
|
||||
}
|
||||
|
||||
return new GamePadState(_leftStick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
|
||||
}
|
||||
|
||||
private GamePadState HandleVirtualStickWP7()
|
||||
{
|
||||
List<Buttons> _buttons = new List<Buttons>();
|
||||
Vector2 _stick = Vector2.Zero;
|
||||
#if WINDOWS_PHONE
|
||||
_phoneA.Pressed = false;
|
||||
_phoneB.Pressed = false;
|
||||
TouchCollection touchLocations = TouchPanel.GetState();
|
||||
foreach (TouchLocation touchLocation in touchLocations)
|
||||
{
|
||||
_phoneA.Update(touchLocation);
|
||||
_phoneB.Update(touchLocation);
|
||||
_phoneStick.Update(touchLocation);
|
||||
}
|
||||
if (_phoneA.Pressed)
|
||||
{
|
||||
_buttons.Add(Buttons.A);
|
||||
}
|
||||
if (_phoneB.Pressed)
|
||||
{
|
||||
_buttons.Add(Buttons.B);
|
||||
}
|
||||
_stick = _phoneStick.StickPosition;
|
||||
#endif
|
||||
return new GamePadState(_stick, Vector2.Zero, 0f, 0f, _buttons.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for checking if a key was newly pressed during this update.
|
||||
/// </summary>
|
||||
public bool IsNewKeyPress(Keys key)
|
||||
{
|
||||
return (_currentKeyboardState.IsKeyDown(key) &&
|
||||
_lastKeyboardState.IsKeyUp(key));
|
||||
}
|
||||
|
||||
public bool IsNewKeyRelease(Keys key)
|
||||
{
|
||||
return (_lastKeyboardState.IsKeyDown(key) &&
|
||||
_currentKeyboardState.IsKeyUp(key));
|
||||
}
|
||||
|
||||
public bool IsNewVirtualButtonPress(Buttons button)
|
||||
{
|
||||
return (_lastVirtualState.IsButtonUp(button) &&
|
||||
_currentVirtualState.IsButtonDown(button));
|
||||
}
|
||||
|
||||
public bool IsNewVirtualButtonRelease(Buttons button)
|
||||
{
|
||||
return (_lastVirtualState.IsButtonDown(button) &&
|
||||
_currentVirtualState.IsButtonUp(button));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for checking if a button was newly pressed during this update.
|
||||
/// </summary>
|
||||
public bool IsNewButtonPress(Buttons button)
|
||||
{
|
||||
return (_currentGamePadState.IsButtonDown(button) &&
|
||||
_lastGamePadState.IsButtonUp(button));
|
||||
}
|
||||
|
||||
public bool IsNewButtonRelease(Buttons button)
|
||||
{
|
||||
return (_lastGamePadState.IsButtonDown(button) &&
|
||||
_currentGamePadState.IsButtonUp(button));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for checking if a mouse button was newly pressed during this update.
|
||||
/// </summary>
|
||||
public bool IsNewMouseButtonPress(MouseButtons button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MouseButtons.LeftButton:
|
||||
return (_currentMouseState.LeftButton == ButtonState.Pressed &&
|
||||
_lastMouseState.LeftButton == ButtonState.Released);
|
||||
case MouseButtons.RightButton:
|
||||
return (_currentMouseState.RightButton == ButtonState.Pressed &&
|
||||
_lastMouseState.RightButton == ButtonState.Released);
|
||||
case MouseButtons.MiddleButton:
|
||||
return (_currentMouseState.MiddleButton == ButtonState.Pressed &&
|
||||
_lastMouseState.MiddleButton == ButtonState.Released);
|
||||
case MouseButtons.ExtraButton1:
|
||||
return (_currentMouseState.XButton1 == ButtonState.Pressed &&
|
||||
_lastMouseState.XButton1 == ButtonState.Released);
|
||||
case MouseButtons.ExtraButton2:
|
||||
return (_currentMouseState.XButton2 == ButtonState.Pressed &&
|
||||
_lastMouseState.XButton2 == ButtonState.Released);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the requested mouse button is released.
|
||||
/// </summary>
|
||||
/// <param name="button">The button.</param>
|
||||
public bool IsNewMouseButtonRelease(MouseButtons button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MouseButtons.LeftButton:
|
||||
return (_lastMouseState.LeftButton == ButtonState.Pressed &&
|
||||
_currentMouseState.LeftButton == ButtonState.Released);
|
||||
case MouseButtons.RightButton:
|
||||
return (_lastMouseState.RightButton == ButtonState.Pressed &&
|
||||
_currentMouseState.RightButton == ButtonState.Released);
|
||||
case MouseButtons.MiddleButton:
|
||||
return (_lastMouseState.MiddleButton == ButtonState.Pressed &&
|
||||
_currentMouseState.MiddleButton == ButtonState.Released);
|
||||
case MouseButtons.ExtraButton1:
|
||||
return (_lastMouseState.XButton1 == ButtonState.Pressed &&
|
||||
_currentMouseState.XButton1 == ButtonState.Released);
|
||||
case MouseButtons.ExtraButton2:
|
||||
return (_lastMouseState.XButton2 == ButtonState.Pressed &&
|
||||
_currentMouseState.XButton2 == ButtonState.Released);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for a "menu select" input action.
|
||||
/// </summary>
|
||||
public bool IsMenuSelect()
|
||||
{
|
||||
return IsNewKeyPress(Keys.Space) ||
|
||||
IsNewKeyPress(Keys.Enter) ||
|
||||
IsNewButtonPress(Buttons.A) ||
|
||||
IsNewButtonPress(Buttons.Start) ||
|
||||
IsNewMouseButtonPress(MouseButtons.LeftButton);
|
||||
}
|
||||
|
||||
public bool IsMenuPressed()
|
||||
{
|
||||
return _currentKeyboardState.IsKeyDown(Keys.Space) ||
|
||||
_currentKeyboardState.IsKeyDown(Keys.Enter) ||
|
||||
_currentGamePadState.IsButtonDown(Buttons.A) ||
|
||||
_currentGamePadState.IsButtonDown(Buttons.Start) ||
|
||||
_currentMouseState.LeftButton == ButtonState.Pressed;
|
||||
}
|
||||
|
||||
public bool IsMenuReleased()
|
||||
{
|
||||
return IsNewKeyRelease(Keys.Space) ||
|
||||
IsNewKeyRelease(Keys.Enter) ||
|
||||
IsNewButtonRelease(Buttons.A) ||
|
||||
IsNewButtonRelease(Buttons.Start) ||
|
||||
IsNewMouseButtonRelease(MouseButtons.LeftButton);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for a "menu cancel" input action.
|
||||
/// </summary>
|
||||
public bool IsMenuCancel()
|
||||
{
|
||||
return IsNewKeyPress(Keys.Escape) ||
|
||||
IsNewButtonPress(Buttons.Back);
|
||||
}
|
||||
}
|
||||
}
|
89
axios/ScreenSystem/LogoScreen.cs
Normal file
89
axios/ScreenSystem/LogoScreen.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public class LogoScreen : GameScreen
|
||||
{
|
||||
private const float LogoScreenHeightRatio = 4f / 6f;
|
||||
private const float LogoWidthHeightRatio = 1.4f;
|
||||
|
||||
private ContentManager _content;
|
||||
private Rectangle _destination;
|
||||
private TimeSpan _duration;
|
||||
private Texture2D _farseerLogoTexture;
|
||||
|
||||
public LogoScreen(TimeSpan duration)
|
||||
{
|
||||
_duration = duration;
|
||||
TransitionOffTime = TimeSpan.FromSeconds(2.0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads graphics content for this screen. The background texture is quite
|
||||
/// big, so we use our own local ContentManager to load it. This allows us
|
||||
/// to unload before going from the menus into the game itself, wheras if we
|
||||
/// used the shared ContentManager provided by the Game class, the content
|
||||
/// would remain loaded forever.
|
||||
/// </summary>
|
||||
public override void LoadContent()
|
||||
{
|
||||
if (_content == null)
|
||||
{
|
||||
_content = new ContentManager(ScreenManager.Game.Services, "Content");
|
||||
}
|
||||
|
||||
_farseerLogoTexture = _content.Load<Texture2D>("Common/logo");
|
||||
|
||||
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
|
||||
int rectHeight = (int)(viewport.Height * LogoScreenHeightRatio);
|
||||
int rectWidth = (int)(rectHeight * LogoWidthHeightRatio);
|
||||
int posX = viewport.Bounds.Center.X - rectWidth / 2;
|
||||
int posY = viewport.Bounds.Center.Y - rectHeight / 2;
|
||||
|
||||
_destination = new Rectangle(posX, posY, rectWidth, rectHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads graphics content for this screen.
|
||||
/// </summary>
|
||||
public override void UnloadContent()
|
||||
{
|
||||
_content.Unload();
|
||||
}
|
||||
|
||||
public override void HandleInput(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
if (input.KeyboardState.GetPressedKeys().Length > 0 ||
|
||||
input.GamePadState.IsButtonDown(Buttons.A | Buttons.Start | Buttons.Back) ||
|
||||
input.MouseState.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
_duration = TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
|
||||
bool coveredByOtherScreen)
|
||||
{
|
||||
_duration -= gameTime.ElapsedGameTime;
|
||||
if (_duration <= TimeSpan.Zero)
|
||||
{
|
||||
ExitScreen();
|
||||
}
|
||||
|
||||
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
||||
}
|
||||
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
ScreenManager.GraphicsDevice.Clear(Color.White);
|
||||
|
||||
ScreenManager.SpriteBatch.Begin();
|
||||
ScreenManager.SpriteBatch.Draw(_farseerLogoTexture, _destination, Color.White);
|
||||
ScreenManager.SpriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
118
axios/ScreenSystem/MenuButton.cs
Normal file
118
axios/ScreenSystem/MenuButton.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class represents a single entry in a MenuScreen. By default this
|
||||
/// just draws the entry text string, but it can be customized to display menu
|
||||
/// entries in different ways. This also provides an event that will be raised
|
||||
/// when the menu entry is selected.
|
||||
/// </summary>
|
||||
public sealed class MenuButton
|
||||
{
|
||||
private Vector2 _baseOrigin;
|
||||
private bool _flip;
|
||||
private bool _hover;
|
||||
|
||||
/// <summary>
|
||||
/// The position at which the entry is drawn. This is set by the MenuScreen
|
||||
/// each frame in Update.
|
||||
/// </summary>
|
||||
private Vector2 _position;
|
||||
|
||||
private float _scale;
|
||||
private GameScreen _screen;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks a fading selection effect on the entry.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The entries transition out of the selection effect when they are deselected.
|
||||
/// </remarks>
|
||||
private float _selectionFade;
|
||||
|
||||
private Texture2D _sprite;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new menu entry with the specified text.
|
||||
/// </summary>
|
||||
public MenuButton(Texture2D sprite, bool flip, Vector2 position, GameScreen screen)
|
||||
{
|
||||
_screen = screen;
|
||||
_scale = 1f;
|
||||
_sprite = sprite;
|
||||
_baseOrigin = new Vector2(_sprite.Width / 2f, _sprite.Height / 2f);
|
||||
_hover = false;
|
||||
_flip = flip;
|
||||
Position = position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position at which to draw this menu entry.
|
||||
/// </summary>
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
|
||||
public bool Hover
|
||||
{
|
||||
get { return _hover; }
|
||||
set { _hover = value; }
|
||||
}
|
||||
|
||||
public GameScreen Screen
|
||||
{
|
||||
get { return _screen; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the menu entry.
|
||||
/// </summary>
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
float fadeSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 4;
|
||||
if (_hover)
|
||||
{
|
||||
_selectionFade = Math.Min(_selectionFade + fadeSpeed, 1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectionFade = Math.Max(_selectionFade - fadeSpeed, 0f);
|
||||
}
|
||||
_scale = 1f + 0.1f * _selectionFade;
|
||||
}
|
||||
|
||||
public void Collide(Vector2 position)
|
||||
{
|
||||
Rectangle collisonBox = new Rectangle((int)(Position.X - _sprite.Width / 2f),
|
||||
(int)(Position.Y - _sprite.Height / 2f),
|
||||
(_sprite.Width),
|
||||
(_sprite.Height));
|
||||
|
||||
if (collisonBox.Contains((int)position.X, (int)position.Y))
|
||||
{
|
||||
_hover = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_hover = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the menu entry. This can be overridden to customize the appearance.
|
||||
/// </summary>
|
||||
public void Draw()
|
||||
{
|
||||
SpriteBatch batch = _screen.ScreenManager.SpriteBatch;
|
||||
Color color = Color.Lerp(Color.White, new Color(255, 210, 0), _selectionFade);
|
||||
|
||||
batch.Draw(_sprite, _position - _baseOrigin * _scale, null, color, 0f, Vector2.Zero,
|
||||
_scale, _flip ? SpriteEffects.FlipVertically : SpriteEffects.None, 0f);
|
||||
}
|
||||
}
|
||||
}
|
193
axios/ScreenSystem/MenuEntry.cs
Normal file
193
axios/ScreenSystem/MenuEntry.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public enum EntryType
|
||||
{
|
||||
Screen,
|
||||
Separator,
|
||||
ExitItem,
|
||||
BackItem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class represents a single entry in a MenuScreen. By default this
|
||||
/// just draws the entry text string, but it can be customized to display menu
|
||||
/// entries in different ways. This also provides an event that will be raised
|
||||
/// when the menu entry is selected.
|
||||
/// </summary>
|
||||
public sealed class MenuEntry
|
||||
{
|
||||
private float _alpha;
|
||||
private Vector2 _baseOrigin;
|
||||
|
||||
private float _height;
|
||||
private MenuScreen _menu;
|
||||
|
||||
/// <summary>
|
||||
/// The position at which the entry is drawn. This is set by the MenuScreen
|
||||
/// each frame in Update.
|
||||
/// </summary>
|
||||
private Vector2 _position;
|
||||
|
||||
private float _scale;
|
||||
private GameScreen _screen;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks a fading selection effect on the entry.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The entries transition out of the selection effect when they are deselected.
|
||||
/// </remarks>
|
||||
private float _selectionFade;
|
||||
|
||||
/// <summary>
|
||||
/// The text rendered for this entry.
|
||||
/// </summary>
|
||||
private string _text;
|
||||
|
||||
private EntryType _type;
|
||||
private float _width;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new menu entry with the specified text.
|
||||
/// </summary>
|
||||
public MenuEntry(MenuScreen menu, string text, EntryType type, GameScreen screen)
|
||||
{
|
||||
_text = text;
|
||||
_screen = screen;
|
||||
_type = type;
|
||||
_menu = menu;
|
||||
_scale = 0.9f;
|
||||
_alpha = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text of this menu entry.
|
||||
/// </summary>
|
||||
public string Text
|
||||
{
|
||||
get { return _text; }
|
||||
set { _text = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position at which to draw this menu entry.
|
||||
/// </summary>
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
|
||||
public float Alpha
|
||||
{
|
||||
get { return _alpha; }
|
||||
set { _alpha = value; }
|
||||
}
|
||||
|
||||
public GameScreen Screen
|
||||
{
|
||||
get { return _screen; }
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
SpriteFont font = _menu.ScreenManager.Fonts.MenuSpriteFont;
|
||||
|
||||
_baseOrigin = new Vector2(font.MeasureString(Text).X, font.MeasureString("M").Y) * 0.5f;
|
||||
|
||||
_width = font.MeasureString(Text).X * 0.8f;
|
||||
_height = font.MeasureString("M").Y * 0.8f;
|
||||
}
|
||||
|
||||
public bool IsExitItem()
|
||||
{
|
||||
return _type == EntryType.ExitItem;
|
||||
}
|
||||
|
||||
public bool IsSelectable()
|
||||
{
|
||||
return _type != EntryType.Separator;
|
||||
}
|
||||
|
||||
public bool IsBackItem()
|
||||
{
|
||||
return _type == EntryType.BackItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the menu entry.
|
||||
/// </summary>
|
||||
public void Update(bool isSelected, GameTime gameTime)
|
||||
{
|
||||
// there is no such thing as a selected item on Windows Phone, so we always
|
||||
// force isSelected to be false
|
||||
#if WINDOWS_PHONE
|
||||
isSelected = false;
|
||||
#endif
|
||||
// When the menu selection changes, entries gradually fade between
|
||||
// their selected and deselected appearance, rather than instantly
|
||||
// popping to the new state.
|
||||
if (_type != EntryType.Separator)
|
||||
{
|
||||
float fadeSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 4;
|
||||
if (isSelected)
|
||||
{
|
||||
_selectionFade = Math.Min(_selectionFade + fadeSpeed, 1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectionFade = Math.Max(_selectionFade - fadeSpeed, 0f);
|
||||
}
|
||||
_scale = 0.7f + 0.1f * _selectionFade;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the menu entry. This can be overridden to customize the appearance.
|
||||
/// </summary>
|
||||
public void Draw()
|
||||
{
|
||||
SpriteFont font = _menu.ScreenManager.Fonts.MenuSpriteFont;
|
||||
SpriteBatch batch = _menu.ScreenManager.SpriteBatch;
|
||||
|
||||
Color color;
|
||||
if (_type == EntryType.Separator)
|
||||
{
|
||||
color = Color.DarkOrange;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the selected entry in yellow, otherwise white
|
||||
color = Color.Lerp(Color.White, new Color(255, 210, 0), _selectionFade);
|
||||
}
|
||||
color *= _alpha;
|
||||
|
||||
// Draw text, centered on the middle of each line.
|
||||
batch.DrawString(font, _text, _position - _baseOrigin * _scale + Vector2.One,
|
||||
Color.DarkSlateGray * _alpha * _alpha, 0, Vector2.Zero, _scale, SpriteEffects.None, 0);
|
||||
batch.DrawString(font, _text, _position - _baseOrigin * _scale, color, 0, Vector2.Zero, _scale,
|
||||
SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries how much space this menu entry requires.
|
||||
/// </summary>
|
||||
public int GetHeight()
|
||||
{
|
||||
return (int)_height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries how wide the entry is, used for centering on the screen.
|
||||
/// </summary>
|
||||
public int GetWidth()
|
||||
{
|
||||
return (int)_width;
|
||||
}
|
||||
}
|
||||
}
|
338
axios/ScreenSystem/MenuScreen.cs
Normal file
338
axios/ScreenSystem/MenuScreen.cs
Normal file
@@ -0,0 +1,338 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for screens that contain a menu of options. The user can
|
||||
/// move up and down to select an entry, or cancel to back out of the screen.
|
||||
/// </summary>
|
||||
public class MenuScreen : GameScreen
|
||||
{
|
||||
#if WINDOWS || XBOX
|
||||
protected const float NumEntries = 15;
|
||||
#elif WINDOWS_PHONE
|
||||
protected const float NumEntries = 9;
|
||||
#endif
|
||||
protected List<MenuEntry> _menuEntries = new List<MenuEntry>();
|
||||
protected string _menuTitle;
|
||||
protected Vector2 _titlePosition;
|
||||
protected Vector2 _titleOrigin;
|
||||
protected int _selectedEntry;
|
||||
protected float _menuBorderTop;
|
||||
protected float _menuBorderBottom;
|
||||
protected float _menuBorderMargin;
|
||||
protected float _menuOffset;
|
||||
protected float _maxOffset;
|
||||
|
||||
protected Texture2D _texScrollButton;
|
||||
protected Texture2D _texSlider;
|
||||
|
||||
protected MenuButton _scrollUp;
|
||||
protected MenuButton _scrollDown;
|
||||
protected MenuButton _scrollSlider;
|
||||
protected bool _scrollLock;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public MenuScreen(string menuTitle)
|
||||
{
|
||||
_menuTitle = menuTitle;
|
||||
|
||||
TransitionOnTime = TimeSpan.FromSeconds(0.7);
|
||||
TransitionOffTime = TimeSpan.FromSeconds(0.7);
|
||||
HasCursor = true;
|
||||
}
|
||||
|
||||
public void AddMenuItem(string name, EntryType type, GameScreen screen)
|
||||
{
|
||||
MenuEntry entry = new MenuEntry(this, name, type, screen);
|
||||
_menuEntries.Add(entry);
|
||||
}
|
||||
|
||||
public void AddMenuItem(MenuEntry me)
|
||||
{
|
||||
_menuEntries.Add(me);
|
||||
}
|
||||
|
||||
public override void LoadContent()
|
||||
{
|
||||
base.LoadContent();
|
||||
|
||||
_texScrollButton = ScreenManager.Content.Load<Texture2D>("Common/arrow");
|
||||
_texSlider = ScreenManager.Content.Load<Texture2D>("Common/slider");
|
||||
|
||||
//Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
|
||||
//float scrollBarPos = viewport.Width / 2f;
|
||||
//scrollBarPos -= _texScrollButton.Width + 2f;
|
||||
|
||||
|
||||
|
||||
InitMenu();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void InitMenu()
|
||||
{
|
||||
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
|
||||
SpriteFont font = ScreenManager.Fonts.MenuSpriteFont;
|
||||
float scrollBarPos = viewport.Width / 2f;
|
||||
|
||||
for (int i = 0; i < _menuEntries.Count; ++i)
|
||||
{
|
||||
_menuEntries[i].Initialize();
|
||||
scrollBarPos = Math.Min(scrollBarPos,
|
||||
(viewport.Width - _menuEntries[i].GetWidth()) / 2f);
|
||||
}
|
||||
|
||||
_titleOrigin = font.MeasureString(_menuTitle) / 2f;
|
||||
_titlePosition = new Vector2(viewport.Width / 2f, font.MeasureString("M").Y / 2f + 10f);
|
||||
|
||||
_menuBorderMargin = font.MeasureString("M").Y * 0.8f;
|
||||
_menuBorderTop = (viewport.Height - _menuBorderMargin * (NumEntries - 1)) / 2f;
|
||||
_menuBorderBottom = (viewport.Height + _menuBorderMargin * (NumEntries - 1)) / 2f;
|
||||
|
||||
_menuOffset = 0f;
|
||||
_maxOffset = Math.Max(0f, (_menuEntries.Count - NumEntries) * _menuBorderMargin);
|
||||
|
||||
_scrollUp = new MenuButton(_texScrollButton, false,
|
||||
new Vector2(scrollBarPos, _menuBorderTop - _texScrollButton.Height), this);
|
||||
_scrollDown = new MenuButton(_texScrollButton, true,
|
||||
new Vector2(scrollBarPos, _menuBorderBottom + _texScrollButton.Height), this);
|
||||
_scrollSlider = new MenuButton(_texSlider, false, new Vector2(scrollBarPos, _menuBorderTop), this);
|
||||
|
||||
_scrollLock = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the menu entry at the position of the given mouse state.
|
||||
/// </summary>
|
||||
/// <returns>Index of menu entry if valid, -1 otherwise</returns>
|
||||
private int GetMenuEntryAt(Vector2 position)
|
||||
{
|
||||
if (this.TransitionPosition == 0f && this.ScreenState == SamplesFramework.ScreenState.Active)
|
||||
{
|
||||
int index = 0;
|
||||
foreach (MenuEntry entry in _menuEntries)
|
||||
{
|
||||
float width = entry.GetWidth();
|
||||
float height = entry.GetHeight();
|
||||
Rectangle rect = new Rectangle((int)(entry.Position.X - width / 2f),
|
||||
(int)(entry.Position.Y - height / 2f),
|
||||
(int)width, (int)height);
|
||||
if (rect.Contains((int)position.X, (int)position.Y) && entry.Alpha > 0.1f)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Responds to user input, changing the selected entry and accepting
|
||||
/// or cancelling the menu.
|
||||
/// </summary>
|
||||
public override void HandleInput(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
// Mouse or touch on a menu item
|
||||
int hoverIndex = GetMenuEntryAt(input.Cursor);
|
||||
if (hoverIndex > -1 && _menuEntries[hoverIndex].IsSelectable() && !_scrollLock)
|
||||
{
|
||||
_selectedEntry = hoverIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedEntry = -1;
|
||||
}
|
||||
|
||||
_scrollSlider.Hover = false;
|
||||
if (input.IsCursorValid)
|
||||
{
|
||||
_scrollUp.Collide(input.Cursor);
|
||||
_scrollDown.Collide(input.Cursor);
|
||||
_scrollSlider.Collide(input.Cursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_scrollUp.Hover = false;
|
||||
_scrollDown.Hover = false;
|
||||
_scrollLock = false;
|
||||
}
|
||||
|
||||
// Accept or cancel the menu?
|
||||
if (input.IsMenuSelect() && _selectedEntry != -1)
|
||||
{
|
||||
if (_menuEntries[_selectedEntry].IsExitItem())
|
||||
{
|
||||
ScreenManager.Game.Exit();
|
||||
}
|
||||
else if (_menuEntries[_selectedEntry].IsBackItem())
|
||||
{
|
||||
this.ExitScreen();
|
||||
}
|
||||
else if (_menuEntries[_selectedEntry].Screen != null)
|
||||
{
|
||||
ScreenManager.AddScreen(_menuEntries[_selectedEntry].Screen);
|
||||
if (_menuEntries[_selectedEntry].Screen is IDemoScreen)
|
||||
{
|
||||
ScreenManager.AddScreen(
|
||||
new MessageBoxScreen((_menuEntries[_selectedEntry].Screen as IDemoScreen).GetDetails()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (input.IsMenuCancel())
|
||||
{
|
||||
if (this.ScreenState == SamplesFramework.ScreenState.Active)
|
||||
{
|
||||
if (ScreenManager.GetScreens().Length == 2)
|
||||
ScreenManager.Game.Exit();
|
||||
else
|
||||
this.ExitScreen();
|
||||
}
|
||||
//ScreenManager.Game.Exit();
|
||||
}
|
||||
|
||||
if (input.IsMenuPressed())
|
||||
{
|
||||
if (_scrollUp.Hover)
|
||||
{
|
||||
_menuOffset = Math.Max(_menuOffset - 200f * (float)gameTime.ElapsedGameTime.TotalSeconds, 0f);
|
||||
_scrollLock = false;
|
||||
}
|
||||
if (_scrollDown.Hover)
|
||||
{
|
||||
_menuOffset = Math.Min(_menuOffset + 200f * (float)gameTime.ElapsedGameTime.TotalSeconds, _maxOffset);
|
||||
_scrollLock = false;
|
||||
}
|
||||
if (_scrollSlider.Hover)
|
||||
{
|
||||
_scrollLock = true;
|
||||
}
|
||||
}
|
||||
if (input.IsMenuReleased())
|
||||
{
|
||||
_scrollLock = false;
|
||||
}
|
||||
if (_scrollLock)
|
||||
{
|
||||
_scrollSlider.Hover = true;
|
||||
_menuOffset = Math.Max(Math.Min(((input.Cursor.Y - _menuBorderTop) / (_menuBorderBottom - _menuBorderTop)) * _maxOffset, _maxOffset), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the screen the chance to position the menu entries. By default
|
||||
/// all menu entries are lined up in a vertical list, centered on the screen.
|
||||
/// </summary>
|
||||
protected virtual void UpdateMenuEntryLocations()
|
||||
{
|
||||
// Make the menu slide into place during transitions, using a
|
||||
// power curve to make things look more interesting (this makes
|
||||
// the movement slow down as it nears the end).
|
||||
float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
|
||||
|
||||
Vector2 position = Vector2.Zero;
|
||||
position.Y = _menuBorderTop - _menuOffset;
|
||||
|
||||
// update each menu entry's location in turn
|
||||
for (int i = 0; i < _menuEntries.Count; ++i)
|
||||
{
|
||||
position.X = ScreenManager.GraphicsDevice.Viewport.Width / 2f;
|
||||
if (ScreenState == ScreenState.TransitionOn)
|
||||
{
|
||||
position.X -= transitionOffset * 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
position.X += transitionOffset * 256;
|
||||
}
|
||||
|
||||
// set the entry's position
|
||||
_menuEntries[i].Position = position;
|
||||
|
||||
if (position.Y < _menuBorderTop)
|
||||
{
|
||||
_menuEntries[i].Alpha = 1f -
|
||||
Math.Min(_menuBorderTop - position.Y, _menuBorderMargin) / _menuBorderMargin;
|
||||
}
|
||||
else if (position.Y > _menuBorderBottom)
|
||||
{
|
||||
_menuEntries[i].Alpha = 1f -
|
||||
Math.Min(position.Y - _menuBorderBottom, _menuBorderMargin) /
|
||||
_menuBorderMargin;
|
||||
}
|
||||
else
|
||||
{
|
||||
_menuEntries[i].Alpha = 1f;
|
||||
}
|
||||
|
||||
// move down for the next entry the size of this entry
|
||||
position.Y += _menuEntries[i].GetHeight();
|
||||
}
|
||||
Vector2 scrollPos = _scrollSlider.Position;
|
||||
scrollPos.Y = MathHelper.Lerp(_menuBorderTop, _menuBorderBottom, _menuOffset / _maxOffset);
|
||||
_scrollSlider.Position = scrollPos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the menu.
|
||||
/// </summary>
|
||||
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
|
||||
bool coveredByOtherScreen)
|
||||
{
|
||||
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
||||
|
||||
// Update each nested MenuEntry object.
|
||||
for (int i = 0; i < _menuEntries.Count; ++i)
|
||||
{
|
||||
bool isSelected = IsActive && (i == _selectedEntry);
|
||||
_menuEntries[i].Update(isSelected, gameTime);
|
||||
}
|
||||
|
||||
_scrollUp.Update(gameTime);
|
||||
_scrollDown.Update(gameTime);
|
||||
_scrollSlider.Update(gameTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the menu.
|
||||
/// </summary>
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
// make sure our entries are in the right place before we draw them
|
||||
UpdateMenuEntryLocations();
|
||||
|
||||
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
|
||||
SpriteFont font = ScreenManager.Fonts.MenuSpriteFont;
|
||||
|
||||
spriteBatch.Begin();
|
||||
// Draw each menu entry in turn.
|
||||
for (int i = 0; i < _menuEntries.Count; ++i)
|
||||
{
|
||||
bool isSelected = IsActive && (i == _selectedEntry);
|
||||
_menuEntries[i].Draw();
|
||||
}
|
||||
|
||||
// Make the menu slide into place during transitions, using a
|
||||
// power curve to make things look more interesting (this makes
|
||||
// the movement slow down as it nears the end).
|
||||
Vector2 transitionOffset = new Vector2(0f, (float)Math.Pow(TransitionPosition, 2) * 100f);
|
||||
|
||||
spriteBatch.DrawString(font, _menuTitle, _titlePosition - transitionOffset + Vector2.One * 2f, Color.Black, 0,
|
||||
_titleOrigin, 1f, SpriteEffects.None, 0);
|
||||
spriteBatch.DrawString(font, _menuTitle, _titlePosition - transitionOffset, new Color(255, 210, 0), 0,
|
||||
_titleOrigin, 1f, SpriteEffects.None, 0);
|
||||
_scrollUp.Draw();
|
||||
_scrollSlider.Draw();
|
||||
_scrollDown.Draw();
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
99
axios/ScreenSystem/MessageBoxScreen.cs
Normal file
99
axios/ScreenSystem/MessageBoxScreen.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// A popup message box screen, used to display "are you sure?"
|
||||
/// confirmation messages.
|
||||
/// </summary>
|
||||
public class MessageBoxScreen : GameScreen
|
||||
{
|
||||
protected Rectangle _backgroundRectangle;
|
||||
protected Texture2D _gradientTexture;
|
||||
protected string _message;
|
||||
protected Vector2 _textPosition;
|
||||
|
||||
public MessageBoxScreen(string message)
|
||||
{
|
||||
_message = message;
|
||||
|
||||
IsPopup = true;
|
||||
HasCursor = true;
|
||||
|
||||
TransitionOnTime = TimeSpan.FromSeconds(0.4);
|
||||
TransitionOffTime = TimeSpan.FromSeconds(0.4);
|
||||
}
|
||||
|
||||
public MessageBoxScreen()
|
||||
{
|
||||
IsPopup = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads graphics content for this screen. This uses the shared ContentManager
|
||||
/// provided by the Game class, so the content will remain loaded forever.
|
||||
/// Whenever a subsequent MessageBoxScreen tries to load this same content,
|
||||
/// it will just get back another reference to the already loaded data.
|
||||
/// </summary>
|
||||
public override void LoadContent()
|
||||
{
|
||||
SpriteFont font = ScreenManager.Fonts.DetailsFont;
|
||||
ContentManager content = ScreenManager.Game.Content;
|
||||
_gradientTexture = content.Load<Texture2D>("Common/popup");
|
||||
|
||||
// Center the message text in the viewport.
|
||||
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
|
||||
Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
|
||||
Vector2 textSize = font.MeasureString(_message);
|
||||
_textPosition = (viewportSize - textSize) / 2;
|
||||
|
||||
// The background includes a border somewhat larger than the text itself.
|
||||
const int hPad = 32;
|
||||
const int vPad = 16;
|
||||
|
||||
_backgroundRectangle = new Rectangle((int)_textPosition.X - hPad,
|
||||
(int)_textPosition.Y - vPad,
|
||||
(int)textSize.X + hPad * 2,
|
||||
(int)textSize.Y + vPad * 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Responds to user input, accepting or cancelling the message box.
|
||||
/// </summary>
|
||||
public override void HandleInput(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
|
||||
if (input.IsMenuSelect() || input.IsMenuCancel() ||
|
||||
input.IsNewMouseButtonPress(MouseButtons.LeftButton))
|
||||
{
|
||||
ExitScreen();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the message box.
|
||||
/// </summary>
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
|
||||
SpriteFont font = ScreenManager.Fonts.DetailsFont;
|
||||
|
||||
// Fade the popup alpha during transitions.
|
||||
Color color = Color.White * TransitionAlpha * (2f / 3f);
|
||||
|
||||
spriteBatch.Begin();
|
||||
|
||||
// Draw the background rectangle.
|
||||
spriteBatch.Draw(_gradientTexture, _backgroundRectangle, color);
|
||||
|
||||
// Draw the message box text.
|
||||
spriteBatch.DrawString(font, _message, _textPosition + Vector2.One, Color.Black);
|
||||
spriteBatch.DrawString(font, _message, _textPosition, Color.White);
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
332
axios/ScreenSystem/PhysicsGameScreen.cs
Normal file
332
axios/ScreenSystem/PhysicsGameScreen.cs
Normal file
@@ -0,0 +1,332 @@
|
||||
using System;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.DebugViews;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Joints;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public class PhysicsGameScreen : GameScreen
|
||||
{
|
||||
public Camera2D Camera;
|
||||
protected DebugViewXNA DebugView;
|
||||
public World World;
|
||||
|
||||
private float _agentForce;
|
||||
private float _agentTorque;
|
||||
#if DEBUG
|
||||
private FixedMouseJoint _fixedMouseJoint;
|
||||
#endif
|
||||
private Body _userAgent;
|
||||
|
||||
protected PhysicsGameScreen()
|
||||
{
|
||||
TransitionOnTime = TimeSpan.FromSeconds(0.75);
|
||||
TransitionOffTime = TimeSpan.FromSeconds(0.75);
|
||||
HasCursor = true;
|
||||
EnableCameraControl = true;
|
||||
_userAgent = null;
|
||||
World = null;
|
||||
Camera = null;
|
||||
DebugView = null;
|
||||
}
|
||||
|
||||
public bool EnableCameraControl { get; set; }
|
||||
|
||||
protected void SetUserAgent(Body agent, float force, float torque)
|
||||
{
|
||||
_userAgent = agent;
|
||||
_agentForce = force;
|
||||
_agentTorque = torque;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void LoadContent()
|
||||
{
|
||||
base.LoadContent();
|
||||
|
||||
//We enable diagnostics to show get values for our performance counters.
|
||||
Settings.EnableDiagnostics = true;
|
||||
|
||||
if (World == null)
|
||||
{
|
||||
World = new World(Vector2.Zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
World.Clear();
|
||||
}
|
||||
|
||||
if (DebugView == null)
|
||||
{
|
||||
if (!Axios.Settings.ScreenSaver)
|
||||
{
|
||||
DebugView = new DebugViewXNA(World);
|
||||
DebugView.RemoveFlags(DebugViewFlags.Shape);
|
||||
DebugView.RemoveFlags(DebugViewFlags.Joint);
|
||||
DebugView.DefaultShapeColor = Color.White;
|
||||
DebugView.SleepingShapeColor = Color.LightGray;
|
||||
DebugView.LoadContent(ScreenManager.GraphicsDevice, ScreenManager.Content);
|
||||
}
|
||||
}
|
||||
|
||||
if (Camera == null)
|
||||
{
|
||||
Camera = new Camera2D(ScreenManager.GraphicsDevice);
|
||||
}
|
||||
else
|
||||
{
|
||||
Camera.ResetCamera();
|
||||
}
|
||||
|
||||
// Loading may take a while... so prevent the game from "catching up" once we finished loading
|
||||
ScreenManager.Game.ResetElapsedTime();
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
|
||||
{
|
||||
if (!coveredByOtherScreen && !otherScreenHasFocus)
|
||||
{
|
||||
// variable time step but never less then 30 Hz
|
||||
World.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
World.Step(0f);
|
||||
}
|
||||
Camera.Update(gameTime);
|
||||
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
||||
}
|
||||
|
||||
public virtual void CleanUp()
|
||||
{
|
||||
|
||||
}
|
||||
public override void HandleInput(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
// Control debug view
|
||||
if (input.IsNewButtonPress(Buttons.Start))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.Shape);
|
||||
EnableOrDisableFlag(DebugViewFlags.DebugPanel);
|
||||
EnableOrDisableFlag(DebugViewFlags.PerformanceGraph);
|
||||
EnableOrDisableFlag(DebugViewFlags.Joint);
|
||||
EnableOrDisableFlag(DebugViewFlags.ContactPoints);
|
||||
EnableOrDisableFlag(DebugViewFlags.ContactNormals);
|
||||
EnableOrDisableFlag(DebugViewFlags.Controllers);
|
||||
}
|
||||
|
||||
if (input.IsNewKeyPress(Keys.F1))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.Shape);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F2))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.DebugPanel);
|
||||
EnableOrDisableFlag(DebugViewFlags.PerformanceGraph);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F3))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.Joint);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F4))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.ContactPoints);
|
||||
EnableOrDisableFlag(DebugViewFlags.ContactNormals);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F5))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.PolygonPoints);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F6))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.Controllers);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F7))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.CenterOfMass);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.F8))
|
||||
{
|
||||
EnableOrDisableFlag(DebugViewFlags.AABB);
|
||||
}
|
||||
|
||||
if (input.IsNewButtonPress(Buttons.Back) || input.IsNewKeyPress(Keys.Escape))
|
||||
{
|
||||
if (this.ScreenState == SamplesFramework.ScreenState.Active && this.TransitionPosition == 0 && this.TransitionAlpha == 1)
|
||||
{ //Give the screens a chance to transition
|
||||
|
||||
CleanUp();
|
||||
ExitScreen();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (HasCursor)
|
||||
{
|
||||
HandleCursor(input);
|
||||
}
|
||||
|
||||
if (_userAgent != null)
|
||||
{
|
||||
HandleUserAgent(input);
|
||||
}
|
||||
|
||||
if (EnableCameraControl)
|
||||
{
|
||||
HandleCamera(input, gameTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
base.HandleInput(input, gameTime);
|
||||
}
|
||||
|
||||
public virtual void HandleCursor(InputHelper input)
|
||||
{
|
||||
#if DEBUG
|
||||
Vector2 position = Camera.ConvertScreenToWorld(input.Cursor);
|
||||
|
||||
if ((input.IsNewButtonPress(Buttons.A) ||
|
||||
input.IsNewMouseButtonPress(MouseButtons.LeftButton)) &&
|
||||
_fixedMouseJoint == null)
|
||||
{
|
||||
Fixture savedFixture = World.TestPoint(position);
|
||||
if (savedFixture != null)
|
||||
{
|
||||
Body body = savedFixture.Body;
|
||||
_fixedMouseJoint = new FixedMouseJoint(body, position);
|
||||
_fixedMouseJoint.MaxForce = 1000.0f * body.Mass;
|
||||
World.AddJoint(_fixedMouseJoint);
|
||||
body.Awake = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((input.IsNewButtonRelease(Buttons.A) ||
|
||||
input.IsNewMouseButtonRelease(MouseButtons.LeftButton)) &&
|
||||
_fixedMouseJoint != null)
|
||||
{
|
||||
World.RemoveJoint(_fixedMouseJoint);
|
||||
_fixedMouseJoint = null;
|
||||
}
|
||||
|
||||
if (_fixedMouseJoint != null)
|
||||
{
|
||||
_fixedMouseJoint.WorldAnchorB = position;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void HandleCamera(InputHelper input, GameTime gameTime)
|
||||
{
|
||||
Vector2 camMove = Vector2.Zero;
|
||||
|
||||
#if DEBUG
|
||||
if (input.KeyboardState.IsKeyDown(Keys.Up))
|
||||
{
|
||||
camMove.Y -= 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.Down))
|
||||
{
|
||||
camMove.Y += 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.Left))
|
||||
{
|
||||
camMove.X -= 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.Right))
|
||||
{
|
||||
camMove.X += 10f * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.PageUp))
|
||||
{
|
||||
Camera.Zoom += 5f * (float)gameTime.ElapsedGameTime.TotalSeconds * Camera.Zoom / 20f;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.PageDown))
|
||||
{
|
||||
Camera.Zoom -= 5f * (float)gameTime.ElapsedGameTime.TotalSeconds * Camera.Zoom / 20f;
|
||||
}
|
||||
if (camMove != Vector2.Zero)
|
||||
{
|
||||
Camera.MoveCamera(camMove);
|
||||
}
|
||||
if (input.IsNewKeyPress(Keys.Home))
|
||||
{
|
||||
Camera.ResetCamera();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void HandleUserAgent(InputHelper input)
|
||||
{
|
||||
#if DEBUG
|
||||
Vector2 force = _agentForce * new Vector2(input.GamePadState.ThumbSticks.Right.X,
|
||||
-input.GamePadState.ThumbSticks.Right.Y);
|
||||
float torque = _agentTorque * (input.GamePadState.Triggers.Right - input.GamePadState.Triggers.Left);
|
||||
|
||||
_userAgent.ApplyForce(force);
|
||||
_userAgent.ApplyTorque(torque);
|
||||
|
||||
float forceAmount = _agentForce * 0.6f;
|
||||
|
||||
force = Vector2.Zero;
|
||||
torque = 0;
|
||||
|
||||
if (input.KeyboardState.IsKeyDown(Keys.A))
|
||||
{
|
||||
force += new Vector2(-forceAmount, 0);
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.S))
|
||||
{
|
||||
force += new Vector2(0, forceAmount);
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.D))
|
||||
{
|
||||
force += new Vector2(forceAmount, 0);
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.W))
|
||||
{
|
||||
force += new Vector2(0, -forceAmount);
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.Q))
|
||||
{
|
||||
torque -= _agentTorque;
|
||||
}
|
||||
if (input.KeyboardState.IsKeyDown(Keys.E))
|
||||
{
|
||||
torque += _agentTorque;
|
||||
}
|
||||
|
||||
_userAgent.ApplyForce(force);
|
||||
_userAgent.ApplyTorque(torque);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void EnableOrDisableFlag(DebugViewFlags flag)
|
||||
{
|
||||
if ((DebugView.Flags & flag) == flag)
|
||||
{
|
||||
DebugView.RemoveFlags(flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugView.AppendFlags(flag);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
Matrix projection = Camera.SimProjection;
|
||||
Matrix view = Camera.SimView;
|
||||
|
||||
if (!Axios.Settings.ScreenSaver)
|
||||
DebugView.RenderDebugData(ref projection, ref view);
|
||||
base.Draw(gameTime);
|
||||
}
|
||||
}
|
||||
}
|
303
axios/ScreenSystem/ScreenManagerComponent.cs
Normal file
303
axios/ScreenSystem/ScreenManagerComponent.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// The screen manager is a component which manages one or more GameScreen
|
||||
/// instances. It maintains a stack of screens, calls their Update and Draw
|
||||
/// methods at the appropriate times, and automatically routes input to the
|
||||
/// topmost active screen.
|
||||
/// </summary>
|
||||
public class ScreenManager : DrawableGameComponent
|
||||
{
|
||||
private AssetCreator _assetCreator;
|
||||
private ContentManager _contentManager;
|
||||
|
||||
private InputHelper _input;
|
||||
private bool _isInitialized;
|
||||
private LineBatch _lineBatch;
|
||||
|
||||
private List<GameScreen> _screens;
|
||||
private List<GameScreen> _screensToUpdate;
|
||||
|
||||
private SpriteBatch _spriteBatch;
|
||||
|
||||
/// <summary>
|
||||
/// Contains all the fonts avaliable for use.
|
||||
/// </summary>
|
||||
private SpriteFonts _spriteFonts;
|
||||
|
||||
private List<RenderTarget2D> _transitions;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new screen manager component.
|
||||
/// </summary>
|
||||
public ScreenManager(Game game)
|
||||
: base(game)
|
||||
{
|
||||
// we must set EnabledGestures before we can query for them, but
|
||||
// we don't assume the game wants to read them.
|
||||
//game.Components.
|
||||
TouchPanel.EnabledGestures = GestureType.None;
|
||||
_contentManager = game.Content;
|
||||
_contentManager.RootDirectory = "Content";
|
||||
_input = new InputHelper(this);
|
||||
|
||||
_screens = new List<GameScreen>();
|
||||
_screensToUpdate = new List<GameScreen>();
|
||||
_transitions = new List<RenderTarget2D>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A default SpriteBatch shared by all the screens. This saves
|
||||
/// each screen having to bother creating their own local instance.
|
||||
/// </summary>
|
||||
public SpriteBatch SpriteBatch
|
||||
{
|
||||
get { return _spriteBatch; }
|
||||
}
|
||||
|
||||
public LineBatch LineBatch
|
||||
{
|
||||
get { return _lineBatch; }
|
||||
}
|
||||
|
||||
public ContentManager Content
|
||||
{
|
||||
get { return _contentManager; }
|
||||
}
|
||||
|
||||
public SpriteFonts Fonts
|
||||
{
|
||||
get { return _spriteFonts; }
|
||||
}
|
||||
|
||||
public AssetCreator Assets
|
||||
{
|
||||
get { return _assetCreator; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the screen manager component.
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
if (!Axios.Settings.ScreenSaver)
|
||||
_spriteFonts = new SpriteFonts(_contentManager);
|
||||
base.Initialize();
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load your graphics content.
|
||||
/// </summary>
|
||||
protected override void LoadContent()
|
||||
{
|
||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||
_lineBatch = new LineBatch(GraphicsDevice);
|
||||
|
||||
if (!Axios.Settings.ScreenSaver)
|
||||
{
|
||||
_assetCreator = new AssetCreator(GraphicsDevice);
|
||||
_assetCreator.LoadContent(_contentManager);
|
||||
|
||||
_input.LoadContent();
|
||||
}
|
||||
// Tell each of the screens to load their content.
|
||||
foreach (GameScreen screen in _screens)
|
||||
{
|
||||
screen.LoadContent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unload your graphics content.
|
||||
/// </summary>
|
||||
protected override void UnloadContent()
|
||||
{
|
||||
// Tell each of the screens to unload their content.
|
||||
foreach (GameScreen screen in _screens)
|
||||
{
|
||||
screen.UnloadContent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows each screen to run logic.
|
||||
/// </summary>
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
// Read the keyboard and gamepad.
|
||||
_input.Update(gameTime);
|
||||
|
||||
// Make a copy of the master screen list, to avoid confusion if
|
||||
// the process of updating one screen adds or removes others.
|
||||
_screensToUpdate.Clear();
|
||||
|
||||
if (_screens.Count == 0)
|
||||
//I'm done, exit
|
||||
this.Game.Exit();
|
||||
|
||||
foreach (GameScreen screen in _screens)
|
||||
{
|
||||
_screensToUpdate.Add(screen);
|
||||
}
|
||||
|
||||
bool otherScreenHasFocus = !Game.IsActive;
|
||||
bool coveredByOtherScreen = false;
|
||||
|
||||
// Loop as long as there are screens waiting to be updated.
|
||||
while (_screensToUpdate.Count > 0)
|
||||
{
|
||||
// Pop the topmost screen off the waiting list.
|
||||
GameScreen screen = _screensToUpdate[_screensToUpdate.Count - 1];
|
||||
|
||||
_screensToUpdate.RemoveAt(_screensToUpdate.Count - 1);
|
||||
|
||||
// Update the screen.
|
||||
screen.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
||||
|
||||
if (screen.ScreenState == ScreenState.TransitionOn ||
|
||||
screen.ScreenState == ScreenState.Active)
|
||||
{
|
||||
// If this is the first active screen we came across,
|
||||
// give it a chance to handle input.
|
||||
if (!otherScreenHasFocus || screen.AlwaysHasFocus)
|
||||
{
|
||||
|
||||
if (!otherScreenHasFocus)
|
||||
{
|
||||
_input.ShowCursor = screen.HasCursor;
|
||||
_input.EnableVirtualStick = screen.HasVirtualStick;
|
||||
|
||||
otherScreenHasFocus = true;
|
||||
}
|
||||
screen.HandleInput(_input, gameTime);
|
||||
}
|
||||
|
||||
// If this is an active non-popup, inform any subsequent
|
||||
// screens that they are covered by it.
|
||||
if (!screen.IsPopup)
|
||||
{
|
||||
coveredByOtherScreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells each screen to draw itself.
|
||||
/// </summary>
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
int transitionCount = 0;
|
||||
foreach (GameScreen screen in _screens)
|
||||
{
|
||||
if (screen.ScreenState == ScreenState.TransitionOn ||
|
||||
screen.ScreenState == ScreenState.TransitionOff)
|
||||
{
|
||||
++transitionCount;
|
||||
if (_transitions.Count < transitionCount)
|
||||
{
|
||||
PresentationParameters _pp = GraphicsDevice.PresentationParameters;
|
||||
_transitions.Add(new RenderTarget2D(GraphicsDevice, _pp.BackBufferWidth, _pp.BackBufferHeight,
|
||||
false,
|
||||
SurfaceFormat.Color, _pp.DepthStencilFormat,
|
||||
_pp.MultiSampleCount,
|
||||
RenderTargetUsage.DiscardContents));
|
||||
}
|
||||
GraphicsDevice.SetRenderTarget(_transitions[transitionCount - 1]);
|
||||
GraphicsDevice.Clear(Color.Transparent);
|
||||
screen.Draw(gameTime);
|
||||
GraphicsDevice.SetRenderTarget(null);
|
||||
}
|
||||
}
|
||||
|
||||
//GraphicsDevice.Clear(Color.Black);
|
||||
|
||||
transitionCount = 0;
|
||||
foreach (GameScreen screen in _screens)
|
||||
{
|
||||
if (screen.ScreenState == ScreenState.Hidden)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (screen.ScreenState == ScreenState.TransitionOn ||
|
||||
screen.ScreenState == ScreenState.TransitionOff)
|
||||
{
|
||||
_spriteBatch.Begin(0, BlendState.AlphaBlend);
|
||||
_spriteBatch.Draw(_transitions[transitionCount], Vector2.Zero, Color.White * screen.TransitionAlpha);
|
||||
_spriteBatch.End();
|
||||
|
||||
++transitionCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.Draw(gameTime);
|
||||
}
|
||||
}
|
||||
_input.Draw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new screen to the screen manager.
|
||||
/// </summary>
|
||||
public void AddScreen(GameScreen screen)
|
||||
{
|
||||
screen.ScreenManager = this;
|
||||
screen.IsExiting = false;
|
||||
|
||||
// If we have a graphics device, tell the screen to load content.
|
||||
if (_isInitialized)
|
||||
{
|
||||
screen.LoadContent();
|
||||
}
|
||||
|
||||
_screens.Add(screen);
|
||||
|
||||
// update the TouchPanel to respond to gestures this screen is interested in
|
||||
TouchPanel.EnabledGestures = screen.EnabledGestures;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a screen from the screen manager. You should normally
|
||||
/// use GameScreen.ExitScreen instead of calling this directly, so
|
||||
/// the screen can gradually transition off rather than just being
|
||||
/// instantly removed.
|
||||
/// </summary>
|
||||
public void RemoveScreen(GameScreen screen)
|
||||
{
|
||||
// If we have a graphics device, tell the screen to unload content.
|
||||
if (_isInitialized)
|
||||
{
|
||||
screen.UnloadContent();
|
||||
}
|
||||
|
||||
_screens.Remove(screen);
|
||||
_screensToUpdate.Remove(screen);
|
||||
|
||||
// if there is a screen still in the manager, update TouchPanel
|
||||
// to respond to gestures that screen is interested in.
|
||||
if (_screens.Count > 0)
|
||||
{
|
||||
TouchPanel.EnabledGestures = _screens[_screens.Count - 1].EnabledGestures;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expose an array holding all the screens. We return a copy rather
|
||||
/// than the real master list, because screens should only ever be added
|
||||
/// or removed using the AddScreen and RemoveScreen methods.
|
||||
/// </summary>
|
||||
public GameScreen[] GetScreens()
|
||||
{
|
||||
return _screens.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
19
axios/ScreenSystem/SpriteFonts.cs
Normal file
19
axios/ScreenSystem/SpriteFonts.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public class SpriteFonts
|
||||
{
|
||||
public SpriteFont DetailsFont;
|
||||
public SpriteFont FrameRateCounterFont;
|
||||
public SpriteFont MenuSpriteFont;
|
||||
|
||||
public SpriteFonts(ContentManager contentManager)
|
||||
{
|
||||
MenuSpriteFont = contentManager.Load<SpriteFont>("Fonts/menuFont");
|
||||
FrameRateCounterFont = contentManager.Load<SpriteFont>("Fonts/frameRateCounterFont");
|
||||
DetailsFont = contentManager.Load<SpriteFont>("Fonts/detailsFont");
|
||||
}
|
||||
}
|
||||
}
|
46
axios/ScreenSystem/VirtualButton.cs
Normal file
46
axios/ScreenSystem/VirtualButton.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public sealed class VirtualButton
|
||||
{
|
||||
private Texture2D _sprite;
|
||||
private Vector2 _origin;
|
||||
private Rectangle _normal;
|
||||
private Rectangle _pressed;
|
||||
private Vector2 _position;
|
||||
|
||||
public bool Pressed;
|
||||
|
||||
public VirtualButton(Texture2D sprite, Vector2 position, Rectangle normal, Rectangle pressed)
|
||||
{
|
||||
_sprite = sprite;
|
||||
_origin = new Vector2(normal.Width / 2f, normal.Height / 2f);
|
||||
_normal = normal;
|
||||
_pressed = pressed;
|
||||
Pressed = false;
|
||||
_position = position;
|
||||
}
|
||||
|
||||
public void Update(TouchLocation touchLocation)
|
||||
{
|
||||
if (touchLocation.State == TouchLocationState.Pressed ||
|
||||
touchLocation.State == TouchLocationState.Moved)
|
||||
{
|
||||
Vector2 delta = touchLocation.Position - _position;
|
||||
if (delta.LengthSquared() <= 400f)
|
||||
{
|
||||
Pressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch batch)
|
||||
{
|
||||
batch.Draw(_sprite, _position, Pressed ? _pressed : _normal, Color.White, 0f, _origin, 1f, SpriteEffects.None, 0f);
|
||||
}
|
||||
}
|
||||
}
|
70
axios/ScreenSystem/VirtualStick.cs
Normal file
70
axios/ScreenSystem/VirtualStick.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public sealed class VirtualStick
|
||||
{
|
||||
private Sprite _socketSprite;
|
||||
private Sprite _stickSprite;
|
||||
private int _picked;
|
||||
private Vector2 _position;
|
||||
private Vector2 _center;
|
||||
|
||||
public Vector2 StickPosition;
|
||||
|
||||
public VirtualStick(Texture2D socket, Texture2D stick, Vector2 position)
|
||||
{
|
||||
_socketSprite = new Sprite(socket);
|
||||
_stickSprite = new Sprite(stick);
|
||||
_picked = -1;
|
||||
_center = position;
|
||||
_position = position;
|
||||
StickPosition = Vector2.Zero;
|
||||
}
|
||||
|
||||
public void Update(TouchLocation touchLocation)
|
||||
{
|
||||
if (touchLocation.State == TouchLocationState.Pressed && _picked < 0)
|
||||
{
|
||||
Vector2 delta = touchLocation.Position - _position;
|
||||
if (delta.LengthSquared() <= 2025f)
|
||||
{
|
||||
_picked = touchLocation.Id;
|
||||
}
|
||||
}
|
||||
if ((touchLocation.State == TouchLocationState.Pressed ||
|
||||
touchLocation.State == TouchLocationState.Moved) && touchLocation.Id == _picked)
|
||||
{
|
||||
Vector2 delta = touchLocation.Position - _center;
|
||||
if (delta != Vector2.Zero)
|
||||
{
|
||||
float _length = delta.Length();
|
||||
if (_length > 25f)
|
||||
{
|
||||
delta *= (25f / _length);
|
||||
}
|
||||
StickPosition = delta / 25f;
|
||||
StickPosition.Y *= -1f;
|
||||
_position = _center + delta;
|
||||
}
|
||||
}
|
||||
if (touchLocation.State == TouchLocationState.Released && touchLocation.Id == _picked)
|
||||
{
|
||||
_picked = -1;
|
||||
_position = _center;
|
||||
StickPosition = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch batch)
|
||||
{
|
||||
batch.Draw(_socketSprite.Texture, _center, null, Color.White, 0f,
|
||||
_socketSprite.Origin, 1f, SpriteEffects.None, 0f);
|
||||
batch.Draw(_stickSprite.Texture, _position, null, Color.White, 0f,
|
||||
_stickSprite.Origin, 1f, SpriteEffects.None, 0f);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user