Estoy haciendo un juego de prueba donde quiero que el nivel se desplace constantemente. Para crear este efecto, he establecido una clase de cámara que simplemente almacena una posición vector2 y una dirección de enumeración. También contiene un método público para 'moverse' que simplemente cambia la posición a una tasa fija. Luego uso esta posición cuando recorro mi conjunto de mosaicos cuando dibujo. Todo esto funciona bien.
Sin embargo, me han dicho que debería usar una matriz de transformación para mover la cámara, y que debería proporcionar esto cuando empiece el spritebatch. Estoy un poco confundido a.) ¿Cómo funciona esto? como si solo lo estuviera dando cuando comience el spritebatch, ¿cómo sabe seguir cambiando de posición? b.) ¿Por qué lo hago con tanta seguridad que todavía necesito la posición de la cámara cuando paso por los mosaicos?
Por el momento no puedo hacer que funcione, pero eso no es una sorpresa, ya que no entiendo completamente cómo debe funcionar. Actualmente, en mi intento (código para seguir), los mosaicos que se dibujan cambian, lo que significa que la posición de las cámaras está cambiando, pero la posición de la ventana gráfica permanece sin cambios (es decir, en el origen de la cámara). Realmente agradecería algún consejo / guía sobre cómo se supone que debe usarse?
Cámara:
class Camera {
// The position of the camera.
public Vector2 Position {
get { return mCameraPosition; }
set { mCameraPosition = value; }
}
Vector2 mCameraPosition;
public Vector2 Origin { get; set; }
public float Zoom { get; set; }
public float Rotation { get; set; }
public ScrollDirection Direction { get; set; }
private Vector2 mScrollSpeed = new Vector2(20, 18);
public Camera() {
Position = Vector2.Zero;
Origin = Vector2.Zero;
Zoom = 1;
Rotation = 0;
}
public Matrix GetTransform() {
return Matrix.CreateTranslation(new Vector3(mCameraPosition, 0.0f)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(Zoom, Zoom, 1.0f) *
Matrix.CreateTranslation(new Vector3(Origin, 0.0f));
}
public void MoveCamera(Level level) {
if (Direction == ScrollDirection.Up)
{
mCameraPosition.Y = MathHelper.Clamp(mCameraPosition.Y - mScrollSpeed.Y, 0, (level.Height * Tile.Height - level.mViewport.Height));
}
}
Nivel:
public void Update(GameTime gameTime, TouchCollection touchState) {
Camera.MoveCamera(this);
}
public void Draw(SpriteBatch spriteBatch) {
//spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise, null, mCamera.GetTransform());
DrawTiles(spriteBatch);
spriteBatch.End();
}
Juego: solo llama al sorteo dentro del nivel:
protected override void Draw(GameTime gameTime) {
mGraphics.GraphicsDevice.Clear(Color.Black);
//mSpriteBatch.Begin();
// Draw the level.
mLevel.Draw(mSpriteBatch);
//mSpriteBatch.End();
base.Draw(gameTime);
}
================================================== =============================== EDITAR:
En primer lugar, gracias craftworkgames por tu ayuda hasta ahora.
Jugué con la sugerencia. Cuando dibujé todas las fichas, el franco se redujo a alrededor de 15 desde 30, probablemente porque los niveles son bastante grandes.
Entonces, lo que he hecho es aplicar la matriz y moverme en la actualización (como se sugiere), pero en el dibujo uso la posición de la cámara para recorrer los mosaicos (es decir, iniciar el contador a la izquierda y terminar en el mosaico derecho). Todo esto funciona bien y estoy feliz con eso :-)
Mi nuevo problema radica en el jugador. Obviamente, como ahora estoy moviendo la cámara en lugar del nivel, el jugador se queda atrás por la cámara mientras su posición permanece fija. He pensado en dos soluciones a este problema, la primera es simplemente considerar la posición de las cámaras al dibujar el reproductor. Es decir, en la función de sorteo simplemente agregue la posición de la cámara a la posición del jugador. El segundo es comenzar un nuevo lote de sprites para el jugador que no tiene transformación. es decir, finalizar el spritebatch después de dibujar las fichas y luego comenzar una nueva al dibujar el jugador. Sé que ambos funcionarán, pero no puedo determinar cuál sería mejor en términos de rendimiento / buena codificación. No estoy seguro de cuáles son las implicaciones de rendimiento al comenzar el lote dos veces.