¿Cuál es la mejor manera de crear un efecto de paralaje en un juego XNA? Me gustaría que la cámara siga a mi sprite a medida que se mueve por el mundo, de esa forma puedo crear efectos como zoom, paneo, sacudidas y otros efectos. ¿Alguien tiene un ejemplo sólido de cómo se hace esto, preferiblemente en un GameComponent?Motor de cámara XNA 2D que sigue a Sprite
Respuesta
Así que lo he descubierto utilizando una combinación de los tutoriales arriba y han creado la clase abajo. Ajardina hacia su objetivo y lo sigue. Pruébalo.
public interface IFocusable
{
Vector2 Position { get; }
}
public interface ICamera2D
{
/// <summary>
/// Gets or sets the position of the camera
/// </summary>
/// <value>The position.</value>
Vector2 Position { get; set; }
/// <summary>
/// Gets or sets the move speed of the camera.
/// The camera will tween to its destination.
/// </summary>
/// <value>The move speed.</value>
float MoveSpeed { get; set; }
/// <summary>
/// Gets or sets the rotation of the camera.
/// </summary>
/// <value>The rotation.</value>
float Rotation { get; set; }
/// <summary>
/// Gets the origin of the viewport (accounts for Scale)
/// </summary>
/// <value>The origin.</value>
Vector2 Origin { get; }
/// <summary>
/// Gets or sets the scale of the Camera
/// </summary>
/// <value>The scale.</value>
float Scale { get; set; }
/// <summary>
/// Gets the screen center (does not account for Scale)
/// </summary>
/// <value>The screen center.</value>
Vector2 ScreenCenter { get; }
/// <summary>
/// Gets the transform that can be applied to
/// the SpriteBatch Class.
/// </summary>
/// <see cref="SpriteBatch"/>
/// <value>The transform.</value>
Matrix Transform { get; }
/// <summary>
/// Gets or sets the focus of the Camera.
/// </summary>
/// <seealso cref="IFocusable"/>
/// <value>The focus.</value>
IFocusable Focus { get; set; }
/// <summary>
/// Determines whether the target is in view given the specified position.
/// This can be used to increase performance by not drawing objects
/// directly in the viewport
/// </summary>
/// <param name="position">The position.</param>
/// <param name="texture">The texture.</param>
/// <returns>
/// <c>true</c> if the target is in view at the specified position; otherwise, <c>false</c>.
/// </returns>
bool IsInView(Vector2 position, Texture2D texture);
}
public class Camera2D : GameComponent, ICamera2D
{
private Vector2 _position;
protected float _viewportHeight;
protected float _viewportWidth;
public Camera2D(Game game)
: base(game)
{}
#region Properties
public Vector2 Position
{
get { return _position; }
set { _position = value; }
}
public float Rotation { get; set; }
public Vector2 Origin { get; set; }
public float Scale { get; set; }
public Vector2 ScreenCenter { get; protected set; }
public Matrix Transform { get; set; }
public IFocusable Focus { get; set; }
public float MoveSpeed { get; set; }
#endregion
/// <summary>
/// Called when the GameComponent needs to be initialized.
/// </summary>
public override void Initialize()
{
_viewportWidth = Game.GraphicsDevice.Viewport.Width;
_viewportHeight = Game.GraphicsDevice.Viewport.Height;
ScreenCenter = new Vector2(_viewportWidth/2, _viewportHeight/2);
Scale = 1;
MoveSpeed = 1.25f;
base.Initialize();
}
public override void Update(GameTime gameTime)
{
// Create the Transform used by any
// spritebatch process
Transform = Matrix.Identity*
Matrix.CreateTranslation(-Position.X, -Position.Y, 0)*
Matrix.CreateRotationZ(Rotation)*
Matrix.CreateTranslation(Origin.X, Origin.Y, 0)*
Matrix.CreateScale(new Vector3(Scale, Scale, Scale));
Origin = ScreenCenter/Scale;
// Move the Camera to the position that it needs to go
var delta = (float) gameTime.ElapsedGameTime.TotalSeconds;
_position.X += (Focus.Position.X - Position.X) * MoveSpeed * delta;
_position.Y += (Focus.Position.Y - Position.Y) * MoveSpeed * delta;
base.Update(gameTime);
}
/// <summary>
/// Determines whether the target is in view given the specified position.
/// This can be used to increase performance by not drawing objects
/// directly in the viewport
/// </summary>
/// <param name="position">The position.</param>
/// <param name="texture">The texture.</param>
/// <returns>
/// <c>true</c> if [is in view] [the specified position]; otherwise, <c>false</c>.
/// </returns>
public bool IsInView(Vector2 position, Texture2D texture)
{
// If the object is not within the horizontal bounds of the screen
if ((position.X + texture.Width) < (Position.X - Origin.X) || (position.X) > (Position.X + Origin.X))
return false;
// If the object is not within the vertical bounds of the screen
if ((position.Y + texture.Height) < (Position.Y - Origin.Y) || (position.Y) > (Position.Y + Origin.Y))
return false;
// In View
return true;
}
}
Y aquí es cómo utilizaría con SpriteBatch
:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
SpriteSortMode.FrontToBack,
SaveStateMode.SaveState,
Camera.Transform);
spriteBatch.Draw(_heliTexture,
_heliPosition,
heliSourceRectangle,
Color.White,
0.0f,
new Vector2(0,0),
0.5f,
SpriteEffects.FlipHorizontally,
0.0f);
spriteBatch.End();
Avisadme si esto te ayuda, y gracias a StackOverflow y la comunidad. W00t!
Éstos son algunos tutoriales sobre cómo implementar una cámara 2D en XNA:
genial, gracias. Tengo que mirarlos y ver si van a funcionar primero. –
El segundo enlace ya no funciona. – Brampage
Sé que es una vieja pregunta, pero yo tenía la misma y he encontrado este gran biblioteca de la cámara monogame así que pensé que debería compartir ...
https://github.com/aloisdeniel/Comora
es muy fácil de instalar y de seguir sprite que sólo tendrá que añadir
this.camera.Position = position de tu sprite;
- 1. Xna agregando gravedad a un sprite 2d
- 2. XNA sprite sort mode
- 3. XNA 2D Game Engines
- 4. ¿Qué debería estar en un motor de juego 2D?
- 5. ¿Superponer 2d sprite de arma sobre sprite de personaje?
- 6. XNA Girar textura 2D
- 7. C# XNA: ¿Motor AI?
- 8. XNA 3d motor de física
- 9. Motor de partículas - XNA/C#
- 10. XNA C# 2D juego de plataformas
- 11. XNA Platformer (2D) - Frameraterate/FPS fluctuations
- 12. Creando un polígono 2D en XNA
- 13. ¿Cómo puedo teñir un sprite en blanco en XNA?
- 14. Quiere aprender a escribir juegos 2d
- 15. Motor de juego en 2D ejemplar
- 16. XNA: Reducir la textura de los antialias 2D?
- 17. 2D XNA ratón del juego, haga clic en
- 18. Cómo dibujar 2D píxel por píxel en XNA?
- 19. AABB de sprite girado?
- 20. Depuración de Xna
- 21. Enlace de proyecto de contenido (XNA) a un proyecto que no sea XNA
- 22. Motor no rígido Motores de física 2D en C++
- 23. Matriz de proyección 3d a 2d
- 24. ¿Cuál es el mejor motor portátil gratuito de 3D/2D?
- 25. Motor de juego Java 2D para juegos basados en fichas
- 26. Simulando la gravedad en XNA
- 27. Movimiento de 2D a 3D
- 28. XNA, X directa, OpenGL
- 29. SVG está muriendo? ¿Que sigue?
- 30. __bases__ no funciona! ¿Que sigue?
Estaba intentando este código, pero cuando lo inicialicé 'Camera2D camera = new Camera2D', noté que necesitaba pasar una variable del juego. ¿Qué variable sería eso? – DMan
Si la propiedad 'IFocusable' Focus nunca debe estar vacío, sería mejor si el ctor era:' Camera2D (Juego juego, IFocusable centró) ' –
En el método de actualización, lo que probablemente va a querer para calcular la propiedad Origen antes de calcular la matriz de transformación. De lo contrario, habrá una disparidad temporal entre el origen utilizado la transformación y el último origen calculado en función de la escala. Además, puede hacer Matrix.CreateScale (Scale) sin crear explícitamente un nuevo Vector3. –