In het vorige deel leerde je textures op het scherm zetten. Maar je kon ook zien dat er een probleem is: de positie van de textures wijzigt niet met de grootte van je window, wat bijvoorbeeld als probleem kan geven dat textures verdwijnen als je van fullscreen naar windowed mode overschakelt. Ook zou de y-as beter omgekeerd werken omdat dit het gebruik van de pijltoetsen meer intuïtief maakt. Verder kunnen we objecten beter schalen met het snijpunt van de assen in het centrum. De reden van deze problemen is dat we de default pixel space gebruiken.
Die pixel space is de meest primitieve manier om met coördinaten om te gaan. Omdat niet elk coördinaten systeem het meest geschikt is voor eender welke game, gebruikt monogame de pixel space. Het is aan jou om daar op verder te bouwen. In dit voorbeeld stellen we vier eisen:
Dat laatste punt zorgt er voor dat we de Textures nu met veel kleinere afmetingen moeten maken. We zullen dus eerst het laden van de textures aanpassen:
Textures.Add(new Support.Texture("balloon", new Vector2(0, 0), new Vector2(0.3f, 0.3f)));
Textures.Add(new Support.Texture("balloon", new Vector2(-0.5f, -0.5f), new Vector2(0.3f, 0.3f)));
Textures.Add(new Support.Texture("balloon", new Vector2(0.7f, 0.7f), new Vector2(0.1f, 0.1f)));
Textures.Add(new Support.Texture("balloon", new Vector2(-0.5f, 0.5f), new Vector2(0.4f, 0.2f)));
Dan maken we in de Support
folder een class Camera
. Omdat we altijd slechts 1 camera willen, wordt dit een static class. De class heeft twee variabelen nodig:
static public class Camera
{
static private float sScale;
static private Point sOffset;
}
De eerste functie die we toevoegen zet een Vector2
grootte om naar een Point
pixel coordinaat. Deze functie gebruiken we niet voor posities, maar om de grootte (size) van een Rectangle
te converteren. De offset hebben we daarom niet nodig.
static private Point ConvertToSize(Vector2 value)
{
Point point = new Point();
point.X = (int)(value.X * sScale);
point.Y = (int)(value.Y * sScale);
return point;
}
Daarnaast hebben we ook een functie nodig om een echte schermpositie te berekenen. Hier heb je wel een offset nodig. Ook moeten we hier de Y
waarde omkeren omdat we die van beneden naar boven willen.
static private Point ConvertToPosition(Vector2 value)
{
Point point = new Point();
point.X = (int)(value.X * sScale);
point.Y = (int)(-value.Y * sScale);
return sOffset + point;
}
Dan volgt de publieke functie die we buiten de class zullen aanroepen ScreenRectangle
. Die zet een positie en een schaling om naar een rechthoek in pixel space. Om de positie samen te laten vallen met het midden van de rechthoek in plaats van de linkerbovenhoek, trekken we de helft van de schaal af van de positie.
static public Rectangle ScreenRectangle(Vector2 position, Vector2 size)
{
Point p = ConvertToPosition(position);
Point s = ConvertToSize(size);
return new Rectangle(p - new Point(s.X / 2, s.Y / 2), s);
}
Tot slot schrijven we een Setup
functie. Telkens als we de resolutie van het window wijzigen (of overschakelen naar fullscreen) moeten we de offset en de schaal berekenen.
static public void Setup()
{
sOffset.X = Game1.sGraphics.PreferredBackBufferWidth / 2;
sOffset.Y = Game1.sGraphics.PreferredBackBufferHeight / 2;
sScale = sOffset.Y;
}
De bovenstaande functie moet je dan in de class Game1
uitvoeren. Dit doe je op het eind de Initialize
functie:
protected override void Initialize()
{
base.Initialize();
Support.Camera.Setup();
}
We begonnen met de Textures
andere coordinaten te geven. De laatste stap bestaat er nu in om die coordinaten om te zetten naar de pixel space. Dat doen we pas op het laatste moment, net voordat we de rechthoek tekenen. De Draw
functie van de Texture
class kan je zo aanpassen:
public void Draw()
{
Rectangle destRect = Camera.ScreenRectangle(position, size);
Game1.sSpriteBatch.Draw(image, destRect, Color.White);
}
Camera
class. Een beetje zoals de functies in Texture
waarmee je de positie en de schaal kan aanpassen. Ook zal je in Game1
twee toetsen moeten gebruiken om de zoom groter en kleiner te maken.N
toets telkens een extra Texture toevoegt aan je game. Elke texture moet een Random positie en schaal hebben.