モノゲーム (XNA API インターフェイスを使用) を使用してゲームを作成しています。これまでのところは素晴らしいですが、単純であるべき何かに引っかかりました。
2次元の正方形を描く必要があります。しかし、境界線のみが必要です(塗りつぶしなし)。
塗りつぶしを行う方法を示す多くの例を見てきました。しかし、境界線のみを表示するものはありません。
画像を作成して使用できると思います。しかし、私はそれがうまくサイズ変更されるとは思えません。
モノゲーム (XNA API インターフェイスを使用) を使用してゲームを作成しています。これまでのところは素晴らしいですが、単純であるべき何かに引っかかりました。
2次元の正方形を描く必要があります。しかし、境界線のみが必要です(塗りつぶしなし)。
塗りつぶしを行う方法を示す多くの例を見てきました。しかし、境界線のみを表示するものはありません。
画像を作成して使用できると思います。しかし、私はそれがうまくサイズ変更されるとは思えません。
この方法で拡張メソッドを作成しましたTexture2D
:
static class Utilities {
public static void CreateBorder( this Texture2D texture, int borderWidth, Color borderColor ) {
Color[] colors = new Color[ texture.Width * texture.Height ];
for ( int x = 0; x < texture.Width; x++ ) {
for ( int y = 0; y < texture.Height; y++ ) {
bool colored = false;
for ( int i = 0; i <= borderWidth; i++ ) {
if ( x == i || y == i || x == texture.Width - 1 - i || y == texture.Height - 1 - i ) {
colors[x + y * texture.Width] = borderColor;
colored = true;
break;
}
}
if(colored == false)
colors[ x + y * texture.Width ] = Color.Transparent;
}
}
texture.SetData( colors );
}
}
それから私はそれをテストしました:
//...
protected override void Initialize( ) {
// TODO: Add your initialization logic here
square = new Texture2D( GraphicsDevice, 100, 100 );
square.CreateBorder( 5, Color.Red );
base.Initialize( );
}
//...
protected override void Draw( GameTime gameTime ) {
GraphicsDevice.Clear( Color.CornflowerBlue );
// TODO: Add your drawing code here
spriteBatch.Begin( );
spriteBatch.Draw( square, new Vector2( 0.0f, 0.0f ), Color.White );
spriteBatch.End( );
base.Draw( gameTime );
}
結果は次のとおりです。
おそらく、1x1 ピクセル テクスチャを使用して、スプライト バッチで個々のエッジを描画できます。XNA では、これを行うことができます。
class RectangleSprite
{
static Texture2D _pointTexture;
public static void DrawRectangle(SpriteBatch spriteBatch, Rectangle rectangle, Color color, int lineWidth)
{
if (_pointTexture == null)
{
_pointTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1);
_pointTexture.SetData<Color>(new Color[]{Color.White});
}
spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y, lineWidth, rectangle.Height + lineWidth), color);
spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width + lineWidth, lineWidth), color);
spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X + rectangle.Width, rectangle.Y, lineWidth, rectangle.Height + lineWidth), color);
spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y + rectangle.Height, rectangle.Width + lineWidth, lineWidth), color);
}
}
結果として得られる描画はlineWidth
、渡された四角形よりもピクセル幅 (および高さ) になります。
上記は次のコードで描画されました。
sb.Begin(); //spritebatch
RectangleSprite.DrawRectangle(sb, new Rectangle(10, 10, 50, 100), Color.Red, 1);
RectangleSprite.DrawRectangle(sb, new Rectangle(30, 20, 80, 15), Color.Green, 4);
RectangleSprite.DrawRectangle(sb, new Rectangle(70, 40, 40, 70), Color.Blue, 6);
sb.End();
プリミティブを描画するためのユーティリティクラスを作成しました。あなたはそれが役に立つと思うかもしれません
static public class PrimiviteDrawing
{
static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area, int width, Color color)
{
batch.Draw(whitePixel, new Rectangle(area.X, area.Y, area.Width, width), color);
batch.Draw(whitePixel, new Rectangle(area.X, area.Y, width, area.Height), color);
batch.Draw(whitePixel, new Rectangle(area.X + area.Width - width, area.Y, width, area.Height), color);
batch.Draw(whitePixel, new Rectangle(area.X, area.Y + area.Height - width, area.Width, width), color);
}
static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area)
{
DrawRectangle(whitePixel, batch, area, 1, Color.White);
}
public static void DrawCircle(Texture2D whitePixel, SpriteBatch spritbatch, IntegerVector2 center, float radius, Color color, int lineWidth = 2, int segments = 16)
{
Vector2[] vertex = new Vector2[segments];
double increment = Math.PI * 2.0 / segments;
double theta = 0.0;
for (int i = 0; i < segments; i++)
{
vertex[i] = center.ToVector2() + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
theta += increment;
}
DrawPolygon(whitePixel, spritbatch, vertex, segments, color, lineWidth);
}
public static void DrawPolygon(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2[] vertex, int count, Color color, int lineWidth)
{
if (count > 0)
{
for (int i = 0; i < count - 1; i++)
{
DrawLineSegment(whitePixel, spriteBatch, vertex[i], vertex[i + 1], color, lineWidth);
}
DrawLineSegment(whitePixel, spriteBatch, vertex[count - 1], vertex[0], color, lineWidth);
}
}
public static void DrawLineSegment(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, int lineWidth)
{
float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
float length = Vector2.Distance(point1, point2);
spriteBatch.Draw(whitePixel, point1, null, color,
angle, Vector2.Zero, new Vector2(length, lineWidth),
SpriteEffects.None, 0f);
}
}
これが私がそれを行う方法です:
private void OutLine_Box(SpriteBatch sbatch, Rectangle rect)
{
List<Vector2> pixels = new List<Vector2>();
for (int x = rect.X; x < rect.X + rect.Width; x++)
{
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
{
if (y == rect.Y || y == rect.Y + rect.Height - 1)
pixels.Add(new Vector2(x, y));
if (x == rect.X || x == rect.X + rect.Width - 1)
pixels.Add(new Vector2(x, y));
}
}
foreach (Vector2 v in pixels)
sbatch.Draw(PixelTexture, v, OutLineColor);
}