Mam więc tę klasę paneli. To trochę jak okno, w którym można zmienić rozmiar, zamknąć, dodać przyciski, suwaki itp. Podobnie jak ekran stanu w Morrowind, jeśli któryś z was pamięta. Zachowanie, którego pragnę, polega na tym, że gdy duszek znajduje się poza granicami panelu, nie zostaje wyciągnięty, a jeśli jest częściowo na zewnątrz, tylko część wewnątrz zostanie narysowana. Więc to, co teraz robi, to najpierw prostokąt, który reprezentuje granice panelu, a prostokąt dla sprite'a, znajduje prostokąt przecięcia między tymi dwoma, a następnie tłumaczy to przecięcie na lokalne współrzędne prostokąta i używa dla tego prostokąta źródłowego:. Działa i jest tak inteligentny, jak uważam, że kod jest nieporozumieniem, że istnieje lepszy sposób na zrobienie tego. Ponadto, przy tej konfiguracji nie mogę wykorzystać globalnej macierzy transformacji dla mojej kamery 2D, wszystko w "świecie" musi zostać przekazane argumentowi kamery do narysowania. Tak czy inaczej, oto kod mam:
na skrzyżowaniu:Jak wykonać obcinanie na obróconych prostokątach?
public static Rectangle? Intersection(Rectangle rectangle1, Rectangle rectangle2)
{
if (rectangle1.Intersects(rectangle2))
{
if (rectangle1.Contains(rectangle2))
{
return rectangle2;
}
else if (rectangle2.Contains(rectangle1))
{
return rectangle1;
}
else
{
int x = Math.Max(rectangle1.Left, rectangle2.Left);
int y = Math.Max(rectangle1.Top, rectangle2.Top);
int height = Math.Min(rectangle1.Bottom, rectangle2.Bottom) - Math.Max(rectangle1.Top, rectangle2.Top);
int width = Math.Min(rectangle1.Right, rectangle2.Right) - Math.Max(rectangle1.Left, rectangle2.Left);
return new Rectangle(x, y, width, height);
}
}
else
{
return null;
}
}
i faktycznie rysowania na panelu:
public void DrawOnPanel(IDraw sprite, SpriteBatch spriteBatch)
{
Rectangle panelRectangle = new Rectangle(
(int)_position.X,
(int)_position.Y,
_width,
_height);
Rectangle drawRectangle = new Rectangle();
drawRectangle.X = (int)sprite.Position.X;
drawRectangle.Y = (int)sprite.Position.Y;
drawRectangle.Width = sprite.Width;
drawRectangle.Height = sprite.Height;
if (panelRectangle.Contains(drawRectangle))
{
sprite.Draw(
spriteBatch,
drawRectangle,
null);
}
else if (Intersection(panelRectangle, drawRectangle) == null)
{
return;
}
else if (Intersection(panelRectangle, drawRectangle).HasValue)
{
Rectangle intersection = Intersection(panelRectangle, drawRectangle).Value;
if (Intersection(panelRectangle, drawRectangle) == drawRectangle)
{
sprite.Draw(spriteBatch, intersection, intersection);
}
else
{
sprite.Draw(
spriteBatch,
intersection,
new Rectangle(
intersection.X - drawRectangle.X,
intersection.Y - drawRectangle.Y,
intersection.Width,
intersection.Height));
}
}
}
więc myślę, że moje pytanie jest, czy istnieje lepszy sposób to zrobić to?
Aktualizacja: Właśnie się dowiedziałem o właściwości ScissorRectangle. Wydaje się, że to dobry sposób na zrobienie tego; wymaga on utworzenia obiektu RasterizerState i przekazania go do obciążenia spritebatch.Begin, które je akceptuje. Wydaje się jednak, że to może być najlepszy zakład. Jest tam także Viewport, który mogę najwyraźniej zmienić. Myśli? :)
Proponuję użyć bardziej jednoznacznego sformułowania w pytaniu, coś w stylu "Jak wykonać obcinanie na obróconych prostokątach?". – Joh
Och, wow, nawet nie myślałem o rotacji. Dzięki –