2016-04-27 14 views
2

Hier ist mein Problem, ich möchte in der Lage sein, mein Sprite zu skalieren und sie an der gleichen Stelle zu halten, wie sie vor der Skala waren. Ich benutze die Mitte des Sprites für den Ursprungsparameter, weil ich auch mein Sprite drehen möchte.MonoGame/XNA Skalierung und Ursprung

Ich bin sicher, dass die Lösung trivial sein wird, aber ich kann keine richtige/allgemeine Lösung finden, um dieses Problem zu lösen.

Wenn es nicht wirklich klar ist, habe ich ein paar Bilder gemacht, um meinen Code, das Ergebnis dieses Codes und was ich erreichen möchte, zu zeigen.

1 - Das ist mein Code und das Ergebnis ist das, was ich, wenn ich das Sprite skaliert, wie Sie das Sprite skaliert wird sehen können, aber es „bewegt“: http://pasteboard.co/uOogJeL.png

Wie hier im Kommentar vorgeschlagen ist Code:

Vector2 scale = Vector2.One; 
    float rotation = 0; 

    public void Update(GameTime gameTime) 
    { 
     if (Input.IsKeyPressed(Keys.P)) 
      scale += new Vector2(0.05f, 0.0f); 
     if (Input.IsKeyPressed(Keys.M)) 
      scale -= new Vector2(0.05f, 0.0f); 

     if (Input.IsKeyPressed(Keys.O)) 
      scale += new Vector2(0.0f, 0.05f); 
     if (Input.IsKeyPressed(Keys.L)) 
      scale -= new Vector2(0.0f, 0.05f); 

     if (Input.IsKeyPressed(Keys.D)) 
      rotation += MathHelper.ToRadians(5); 
     if (Input.IsKeyPressed(Keys.Q)) 
      rotation -= MathHelper.ToRadians(5); 

     Input.Update(gameTime); 
    } 

    public void Draw(GameTime gameTime, SpriteBatch spriteBatch) 
    { 
     spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(4)); 

     spriteBatch.Draw(Sprites.BACKGROUND, Vector2.Zero, new Rectangle(0, 0, 128, 128), Color.White); 

     Vector2 marioPosition = new Vector2(64, 112 - 32); 
     Rectangle source = new Rectangle(0,0,16,32); 

     Vector2 origin = source.Size.ToVector2()/2; 

     spriteBatch.Draw(Sprites.MARIO, marioPosition + origin, source, Color.White, rotation, origin, scale, SpriteEffects.None, 0f); 

     spriteBatch.End(); 
    } 

2 - um diesen Punkt Dies ist, was ich zu erreichen, mag ich weiß, dass ich diese meinen Ursprungspunkt tun kann, indem ich will es in der Mitte des Sprites halten, so kann ich Drehung anwenden : http://pasteboard.co/rzMfc0p.png

Danke.

+0

Willkommen bei Stackoverflow. Könnten Sie Ihren Code in den Hauptteil der Frage einfügen, so wird es einfacher, Ihre Frage zu lesen, ohne zwischen den Seiten zu wechseln, und für den Fall, dass die Seite, die Sie verlinkt haben, jemals entfernt wird, haben wir den Code für zukünftige Leser . –

Antwort

1

Jemand half mir und fand eine Lösung für mein Problem (Pema99 @pemathedev), wie von anderen Leuten vorgeschlagen die Lösung war in der Tat das Sprite zu bewegen und hier ist, wie viel Sie brauchen, um Ihre SP zu bewegen Ritus:

public void Update(GameTime gameTime) 
{ 
    if (Input.IsKeyPressed(Keys.P)) 
     scale.X += .05f; 
    if (Input.IsKeyPressed(Keys.M)) 
     scale.X -= .05f; 

    //Solution --------------------------------------------------- 
    if (Input.IsKeyPressed(Keys.O)) 
    { 
     float previousSize = source.Height * scale.Y; 
     float newSize = source.Height * (scale.Y + .05f); 
     scale.Y += .05f; 
     marioPosition.Y -= (Math.Abs(previousSize - newSize)/2) 
    } 
    if (Input.IsKeyPressed(Keys.L)) 
    { 
     float previousSize = source.Height * scale.Y; 
     float newSize = source.Height * (scale.Y - .05f); 
     scale.Y -= .05f; 
     marioPosition.Y += (Math.Abs(previousSize - newSize)/2) 
    } 
    //-------------------------------------------------------------- 

    if (Input.IsKeyPressed(Keys.D)) 
     rotation += MathHelper.ToRadians(5); 
    if (Input.IsKeyPressed(Keys.Q)) 
     rotation -= MathHelper.ToRadians(5); 

    Input.Update(gameTime); 
} 

Vielen Dank an alle!

0

Nun, Sie behalten Ihren Charakter auf jeden Fall. Buchstäblich. Was Sie brauchen, ist eigentlich bewegen Ihren Charakter, damit seine Beine immer auf dem Boden bleiben.

Wenn dies Ihr ganzer Code ist, bedeutet das, dass Sie (noch) keine Physik haben. In diesem Fall müssen Sie die Position Ihres Charakters um die Hälfte der Bildschirmhöhe (image.height * scale) nach oben/unten verschieben, und zwar nur dann, wenn sich seine vertikale Skalierung ändert. Das wird nicht gut funktionieren, wenn Sie erst einmal Physik eingeführt haben, aber im Moment ist hier der nicht getestete, aber vorgeschlagene Code.

public void Update(GameTime gameTime) 
{ 
    if (Input.IsKeyPressed(Keys.P)) 
     scale.X += .05f; 
    if (Input.IsKeyPressed(Keys.M)) 
     scale.X -= .05f; 

    if (Input.IsKeyPressed(Keys.O)) 
    { 
     scale.Y += .05f; 
     marioPosition.Y -= scale.Y * (Sprites.MARIO.Height/2f); 
    } 
    if (Input.IsKeyPressed(Keys.L)) 
    { 
     scale.Y -= .05f; 
     marioPosition.Y += scale.Y * (Sprites.MARIO.Height/2f); 
    } 

    if (Input.IsKeyPressed(Keys.D)) 
     rotation += MathHelper.ToRadians(5); 
    if (Input.IsKeyPressed(Keys.Q)) 
     rotation -= MathHelper.ToRadians(5); 

    Input.Update(gameTime); 
} 

Der einzige Grund, warum ich scale += new Vector2(0.0f, 0.05f);-scale.Y += .05f; geändert ist für Sie, dass es schneller getan werden kann, um zu sehen, und Sie können Ihren Code besser lesbar machen.

Auch wegen der invertierten vertikalen (Y) Achse in XNA, für das Zeichen nach oben zu bewegen, müssen Sie von seiner Position subtrahieren, und umgekehrt.

Einige zusätzliche Tipps:

  • Eine Klasse für alle Sprites ist eine großartige Idee, auch, ist die Klasse für alle Eingabe (Input) groß zu

  • Statt in 4 des Schreibens .05f Orte, erstellen Sie eine Variable, die sich an diesen Stellen befindet, und legen Sie ihren Wert fest.

    05f
0

Ich tat, was Sie vorgeschlagen, aber es bewegen eigentlich nur das Sprite:/

Hier sind die Änderungen, die ich gemacht habe:

 Vector2 scale = Vector2.One; 
     float rotation = 0; 
     Vector2 marioPosition = new Vector2(64, 112 - 32); 
     Rectangle source = new Rectangle(0, 0, 16, 32); 

     public void Update(GameTime gameTime) 
     { 
      if (Input.IsKeyPressed(Keys.P)) 
       scale.X += 0.05f; 
      if (Input.IsKeyPressed(Keys.M)) 
       scale.X -= 0.05f; 

      if (Input.IsKeyPressed(Keys.O)) 
      { 
       scale.Y += 0.05f; 
       marioPosition.Y -= scale.Y * (source.Height/2f); 
      } 

      if (Input.IsKeyPressed(Keys.L)) 
      { 
       scale.Y -= 0.05f; 
       marioPosition.Y += scale.Y * (source.Height/2f); 
      } 


      if (Input.IsKeyPressed(Keys.D)) 
       rotation += MathHelper.ToRadians(5); 
      if (Input.IsKeyPressed(Keys.Q)) 
       rotation -= MathHelper.ToRadians(5); 

      Input.Update(gameTime); 
     } 

     public void Draw(GameTime gameTime, SpriteBatch spriteBatch) 
     { 
      spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(4)); 

      spriteBatch.Draw(Sprites.BACKGROUND, Vector2.Zero, new Rectangle(0, 0, 128, 128), Color.White); 


      Vector2 origin = source.Size.ToVector2()/2; 

      spriteBatch.Draw(Sprites.MARIO, marioPosition + origin, source, Color.White, rotation, origin, scale, SpriteEffects.None, 0f); 

      spriteBatch.End(); 
     } 

Hier ist das Ergebnis: http://pasteboard.co/vqTN2vX.png