Estou fazendo um jogo de teste onde quero que o nível esteja constantemente rolando. Para criar esse efeito, estabeleci uma classe de câmera que simplesmente armazena uma posição vector2 e uma direção enum. Ele também contém um método público para 'mover', que simplesmente altera a posição a uma taxa fixa. Eu então uso essa posição ao percorrer minha matriz de peças ao desenhar. Tudo isso funciona bem.
No entanto, me disseram que eu deveria usar uma matriz Transform para mover a câmera e que eu deveria fornecer isso quando eu iniciar o spritebatch. Estou um pouco confuso a.) Como isso funciona? como se eu estivesse dando apenas quando o spritebatch começa, como ele sabe continuar mudando de posição? b.) Por que, com certeza, ainda preciso da posição da câmera para fazer um loop nos ladrilhos?
No momento, não consigo fazê-lo funcionar, mas isso não é surpresa, pois não entendo completamente como isso deve funcionar. Atualmente, na minha tentativa (código a seguir), as peças desenhadas mudam, o que significa que a posição da câmera está mudando, mas a posição da janela de visualização permanece inalterada (ou seja, na origem da câmera). Eu realmente aprecio alguns conselhos / orientações sobre como deve ser usado?
Câmera:
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));
}
}
Nível:
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();
}
Jogo - apenas chama o empate dentro do nível:
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:
Em primeiro lugar, obrigado craftworkgames por sua ajuda até agora.
Eu brinquei com a sugestão. Quando eu desenhei todas as peças, o fr caiu para cerca de 15 a 30 - provavelmente porque os níveis são bem grandes.
Então, o que fiz foi aplicar a matriz e mover-me na atualização (como sugerido), mas no sorteio eu uso a posição da câmera para percorrer os ladrilhos (ou seja, iniciar o contador à esquerda e terminar no lado direito). Isso tudo funciona bem e eu estou feliz com isso :-)
Minha nova edição está no player. Obviamente, agora que estou movendo a câmera e não o nível, o jogador é deixado para trás pelo camer enquanto sua posição permanece fixa. Eu pensei em duas soluções para esse problema, a primeira é simplesmente considerar a posição das câmeras ao desenhar o player. Ou seja, na função de desenho, basta adicionar a posição da câmera à posição do jogador. O segundo é iniciar um novo lote de sprites para o jogador que não tem transformação. ou seja, finalize o spritebatch depois de desenhar as peças e inicie uma nova ao desenhar o jogador. Eu sei que os dois funcionarão, mas não posso fazer cara de rabo, o que seria melhor em termos de desempenho / boa codificação? Não sei ao certo quais são as implicações de desempenho ao iniciar o lote duas vezes?