Robię grę testową, w której chcę, aby poziom ciągle się przewijał. Aby stworzyć ten efekt, stworzyłem klasę kamery, która po prostu przechowuje pozycję vector2 i kierunek wyliczania. Zawiera także publiczną metodę „przemieszczania się”, która po prostu zmienia pozycję według stałej stawki. Następnie używam tej pozycji, gdy przeglądam moją tablicę kafelków. To wszystko działa dobrze.
Jednak powiedziano mi, że powinienem używać matrycy transformacji do poruszania kamerą i że powinienem to zapewnić, kiedy uruchamiam spritebatch. Jestem trochę zdezorientowany.) Jak to działa? tak jakbym dawał to dopiero, gdy spritebatch zaczyna się, skąd wiadomo, że ciągle zmienia pozycję? b.) Dlaczego robię to tak pewnie, że nadal potrzebuję pozycji kamery, gdy przechodzę przez płytki?
W tej chwili nie mogę zmusić go do działania, ale nie jest to zaskoczeniem, ponieważ nie do końca rozumiem, jak to ma działać. Obecnie w mojej próbie (kod do naśladowania) narysowane kafelki zmieniają się, co oznacza, że zmienia się pozycja kamer, ale pozycja rzutni pozostaje niezmieniona (tj. W punkcie początkowym kamery). Byłbym naprawdę wdzięczny za porady / wskazówki, w jaki sposób powinno się go używać?
Aparat fotograficzny:
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));
}
}
Poziom:
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();
}
Gra - po prostu sprawdza losowanie na poziomie:
protected override void Draw(GameTime gameTime) {
mGraphics.GraphicsDevice.Clear(Color.Black);
//mSpriteBatch.Begin();
// Draw the level.
mLevel.Draw(mSpriteBatch);
//mSpriteBatch.End();
base.Draw(gameTime);
}
================================================== =============================== EDYCJA:
Po pierwsze, dziękuję gry rzemieślnicze za pomoc do tej pory.
Bawiłem się z sugestią. Kiedy narysowałem wszystkie płytki, fr zagrał do około 15 z 30 - prawdopodobnie dlatego, że poziomy są dość duże.
Więc zastosowałem macierz i poruszałem się w aktualizacji (zgodnie z sugestią), ale w losowaniu używam pozycji kamery do zapętlania płytek (tj. Start licznika po lewej i koniec po prawej płytce). To wszystko działa dobrze i jestem z tego zadowolony :-)
Mój nowy problem leży w odtwarzaczu. Oczywiście, ponieważ teraz poruszam kamerą, a nie poziomem, gracz zostaje w tyle za kamerą, gdy jego pozycja pozostaje stała. Pomyślałem o dwóch rozwiązaniach tego problemu. Pierwszym z nich jest po prostu wzięcie pod uwagę położenia kamery podczas rysowania odtwarzacza. Tj. W funkcji losowania po prostu dodaj pozycję kamery do pozycji gracza. Drugim jest rozpoczęcie nowej partii sprite dla gracza, który nie ma transformacji. tzn. zakończ sprite po wylosowaniu kafelków, a następnie rozpocznij nowy podczas losowania gracza. Wiem, że oba będą działać, ale nie mogę zrobić ogonów, które byłyby lepsze pod względem wydajności / dobrego kodowania? Nie jestem pewien, jakie są konsekwencje dla wydajności od dwukrotnego uruchomienia partii?