📄 tankgamecomponent.cs
字号:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SceneryComponent;
using Microsoft.Xna.Framework.Content;
using CustomProcessors;
using Microsoft.Xna.Framework.Input;
using SceneryComponent.Components.Animation;
namespace SceneryComponent.Components
{
/// <summary>
/// Componente tanque
/// </summary>
public partial class TankGameComponent : Microsoft.Xna.Framework.DrawableGameComponent
{
// Gestor de contenidos
protected ContentManager content = null;
// Escenario
protected SceneryGameComponent scenery = null;
// Controlador de entrada de usuario
protected Input input = null;
// Modelo
protected Model m_Model = null;
// Posici髇
protected Vector3 m_Position = Vector3.Zero;
// Rotaci髇
protected Quaternion m_Rotation = Quaternion.Identity;
// Inclinaci髇
protected Quaternion m_Inclination = Quaternion.Identity;
// Escala
protected float m_Scale = 1.0f;
// Vector velocidad
protected Vector3 m_Direction = Vector3.Forward;
// Velocidad de traslaci髇
protected float m_Velocity = 0.0f;
// Velocidad m醲ima que puede alcanzar el modelo
protected float m_MaxVelocity = 1.0f;
// Modificador de aceleraci髇
protected float m_AccelerationModifier = 0.01f;
// Modificador de frenado
protected float m_BrakeModifier = 0.05f;
// Velocidad angular
protected float m_AngularVelocity = 0.01f;
/// <summary>
/// Obtiene la informaci髇 de primitivas del modelo
/// </summary>
public PrimitiveInfo PrimitiveInfo
{
get
{
if ((this.m_Model != null) && (this.m_Model.Tag != null))
{
return this.m_Model.Tag as PrimitiveInfo;
}
return null;
}
}
// Lista de transformaciones del modelo
protected Matrix[] m_BoneTransforms;
// Controlador de animaci髇
protected AnimationController m_AnimationController = new AnimationController();
// Lista de posibles posiciones de jugador
protected List<PlayerPosition> m_PlayerControlList = new List<PlayerPosition>();
// Posici髇 actual del jugador en el modelo
protected PlayerPosition m_CurrentPlayerControl = null;
// Indica si el tanque tiene el foco
public bool HasFocus = false;
/// <summary>
/// Obtiene la matriz mundo actual del modelo
/// </summary>
public Matrix CurrentModelMatrix
{
get
{
return GetModelTransform();
}
}
/// <summary>
/// Obtiene la matriz de vista actual del modelo
/// </summary>
public Matrix CurrentViewMatrix
{
get
{
return GetModelView();
}
}
/// <summary>
/// Obtiene o establece la posici髇
/// </summary>
public Vector3 Position
{
get
{
return m_Position;
}
set
{
m_Position = value;
}
}
/// <summary>
/// Obtiene o establece la rotaci髇
/// </summary>
public Quaternion Rotation
{
get
{
return m_Rotation;
}
}
/// <summary>
/// Obtiene o establece la escala
/// </summary>
public float Scale
{
get
{
return m_Scale;
}
set
{
m_Scale = value;
}
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="game">Juego</param>
public TankGameComponent(Game game)
: base(game)
{
content = (ContentManager)game.Services.GetService(typeof(ContentManager));
scenery = (SceneryGameComponent)game.Services.GetService(typeof(SceneryGameComponent));
input = (Input)game.Services.GetService(typeof(Input));
input.KeyDown += new KeyboardEventDelegate(KeyboardInput_KeyDown);
input.KeyUp += new KeyboardEventDelegate(KeyboardInput_KeyUp);
}
/// <summary>
/// Carga de contenido gr醘ico
/// </summary>
/// <param name="loadAllContent">Tipo de contenido a cargar</param>
protected override void LoadGraphicsContent(bool loadAllContent)
{
base.LoadGraphicsContent(loadAllContent);
}
/// <summary>
/// Actualiza el estado del componente
/// </summary>
/// <param name="gameTime">Tiempo de juego</param>
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
// Trasladar la posici髇
m_Position += Vector3.Multiply(m_Direction, m_Velocity);
// Actualizar inclinaci髇 y altura
Primitive tri = null;
Vector3? point = scenery.GetPoint(m_Position.X, m_Position.Z, out tri);
if (tri != null)
{
// Establecer la posici髇 definitiva
m_Position = point.Value;
// Obtener la normal actual
Vector3 currentNormal = Matrix.CreateFromQuaternion(m_Rotation).Up;
// Obtener la normal del tri醤gulo
Vector3 newNormal = tri.Normal;
// Calcular inclinaci髇 a aplicar
Quaternion newInclination = Quaternion.Identity;
Vector3 axis = Vector3.Normalize(Vector3.Cross(currentNormal, newNormal));
float angle = (float)Math.Acos(Vector3.Dot(currentNormal, newNormal));
if (angle != 0.0f)
{
newInclination = Quaternion.CreateFromAxisAngle(axis, angle);
}
// Establecer la interpolaci髇 entre la inclinaci髇 actual y la nueva
m_Inclination = Quaternion.Slerp(m_Inclination, newInclination, 0.08f);
}
m_AnimationController.Update(gameTime);
}
/// <summary>
/// Dibujar
/// </summary>
/// <param name="gameTime">Tiempo de juego</param>
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
if ((m_Model != null) && (scenery != null))
{
Matrix modelTransform = this.GetModelTransform();
m_AnimationController.CopyAbsoluteBoneTransformsTo(m_Model, m_BoneTransforms);
foreach (ModelMesh mesh in m_Model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
SceneryEnvironment.Fog.SetFogToEffect(effect);
//SceneryEnvironment.Ambient.SetAmbientToEffect(effect);
effect.View = BaseCameraGameComponent.gViewMatrix;
effect.Projection = BaseCameraGameComponent.gGlobalProjectionMatrix;
effect.World = m_BoneTransforms[mesh.ParentBone.Index] * modelTransform;
}
mesh.Draw();
}
}
}
/// <summary>
/// Evento disparado a soltar una tecla
/// </summary>
/// <param name="e">Argumentos</param>
protected virtual void KeyboardInput_KeyUp(KeyboardEventArgs e)
{
}
/// <summary>
/// Evento disparado a pulsar una tecla
/// </summary>
/// <param name="e">Argumentos</param>
protected virtual void KeyboardInput_KeyDown(KeyboardEventArgs e)
{
}
/// <summary>
/// Obtiene la matriz de transformaci髇 del modelo
/// </summary>
/// <returns>Devuelve la matriz de transformaci髇 del modelo</returns>
private Matrix GetModelTransform()
{
Matrix world = Matrix.CreateScale(m_Scale);
world *= Matrix.CreateFromQuaternion(m_Rotation);
world *= Matrix.CreateFromQuaternion(m_Inclination);
world *= Matrix.CreateTranslation(m_Position);
return world;
}
/// <summary>
/// Obtiene la matriz de vista desde la posici髇 actual del modelo
/// </summary>
/// <returns>Devuelve la matriz de vista desde la posici髇 actual del modelo</returns>
private Matrix GetModelView()
{
return m_CurrentPlayerControl.GetViewMatrix(this.m_AnimationController, this.GetModelTransform());
}
/// <summary>
/// Aumenta la velocidad de traslaci髇 del modelo
/// </summary>
public void Accelerate()
{
this.AddToVelocity(this.m_AccelerationModifier);
}
/// <summary>
/// Disminuye la velocidad de traslaci髇 del modelo
/// </summary>
public void Brake()
{
this.AddToVelocity(-this.m_BrakeModifier);
}
/// <summary>
/// Establece la velocidad de traslaci髇 del modelo
/// </summary>
/// <param name="velocity">Velocidad</param>
protected void SetVelocity(float velocity)
{
this.m_Velocity = velocity;
}
/// <summary>
/// A馻de la cantidad especificada a la velocidad de traslaci髇 del modelo
/// </summary>
/// <param name="velocity">Velocidad</param>
protected void AddToVelocity(float velocity)
{
this.m_Velocity += velocity;
if (this.m_Velocity > this.m_MaxVelocity)
{
this.m_Velocity = this.m_MaxVelocity;
}
if (this.m_Velocity < 0f)
{
this.m_Velocity = 0f;
}
}
/// <summary>
/// Gira el modelo a la izquierda
/// </summary>
public void TurnLeft()
{
this.RotateByUp(this.m_AngularVelocity);
}
/// <summary>
/// Gira el modelo a la derecha
/// </summary>
public void TurnRight()
{
this.RotateByUp(-this.m_AngularVelocity);
}
/// <summary>
/// Gira el modelo en el eje Y utilizando el 醤gulo especificado
/// </summary>
/// <param name="angle">羘gulo de rotaci髇 en radianes</param>
protected void RotateByUp(float angle)
{
// Modificar la rotaci髇
this.m_Rotation *= Quaternion.CreateFromAxisAngle(Vector3.Up, angle);
// Modificar la direcci髇
this.m_Direction = Vector3.Transform(this.m_Direction, Matrix.CreateFromAxisAngle(Vector3.Up, angle));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -