2016-08-28 6 views
0

У меня есть Тип класса, который имеет 4 балла (Vector2). Таким образом, форму можно манипулировать в любых целях. Я хочу иметь возможность заполнить эту фигуру цветом, но не знаю, с чего начать. Я нашел ссылки на что-то под названием «VertexPositionColorTexture», но вскоре понял, что это только для 3D-пространства. Моя программа только 2D, и я в недоумении.Как заполнить 2D-форму?

Если у кого-то есть предложения, чтобы добраться до места, где я пытаюсь, я по достоинству оценю помощь.

public class CShape 
{ 
    public Vector2 PointA { get; set; } 
    public Vector2 PointB { get; set; } 
    public Vector2 PointC { get; set; } 
    public Vector2 PointD { get; set; } 

    public Color Color { get; set; } 

    public float GetWidth() 
    { 
     Vector2 Left, Right; 
     Left = PointA; 
     if (PointB.X < Left.X) { Left = PointB; } 
     if (PointC.X < Left.X) { Left = PointC; } 
     if (PointD.X < Left.X) { Left = PointD; } 

     Right = PointA; 
     if (PointB.X > Right.X) { Right = PointB; } 
     if (PointC.X > Right.X) { Right = PointC; } 
     if (PointD.X > Right.X) { Right = PointD; } 

     return (Left.X - Right.X); 
    } 

    public float GetHeight() 
    { 
     Vector2 Top, Bottom; 
     Top = PointA; 
     if (PointB.Y < Top.Y) { Top = PointB; } 
     if (PointC.Y < Top.Y) { Top = PointC; } 
     if (PointD.Y < Top.Y) { Top = PointD; } 

     Bottom = PointA; 
     if (PointB.Y > Bottom.Y) { Bottom = PointB; } 
     if (PointC.Y > Bottom.Y) { Bottom = PointC; } 
     if (PointD.Y > Bottom.Y) { Bottom = PointD; } 

     return (Top.Y - Bottom.Y); 
    } 

    public CShape(Vector2 Location, int Width, int Height, Color Color) 
    { 
     PointA = Location; 
     PointB = new Vector2(PointA.X + Width, PointA.Y); 
     PointC = new Vector2(PointA.X, PointA.Y + Height); 
     PointD = new Vector2(PointA.X + Width, PointA.Y + Height); 
     this.Color = Color; 
    } 
    public void Move(Vector2 Velocity) 
    { 
     PointA = new Vector2(PointA.X + Velocity.X, PointA.Y + Velocity.Y); 
     PointB = new Vector2(PointB.X + Velocity.X, PointB.Y + Velocity.Y); 
     PointC = new Vector2(PointC.X + Velocity.X, PointC.Y + Velocity.Y); 
     PointD = new Vector2(PointD.X + Velocity.X, PointD.Y + Velocity.Y); 
    } 
    public void Draw(SpriteBatch sb) 
    { 
     sb.Begin(); 
     SpriteBatchEx.DrawLine(sb, PointA, PointB, Color, 3); 
     SpriteBatchEx.DrawLine(sb, PointB, PointD, Color, 3); 
     SpriteBatchEx.DrawLine(sb, PointD, PointC, Color, 3); 
     SpriteBatchEx.DrawLine(sb, PointC, PointA, Color, 3); 
     sb.End(); 
    } 


} 

ответ

2

Общий подход просто рисовать в 3D, но с использованием 2D-проекции, это действительно просто один раз установить и есть преимущества в этом (TODO узнать больше по этой теме, есть много учебников там) !

Так вот простой код, который рисует квадраты в любом месте и вы можете подкрасить их:

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 

namespace Game1 
{ 
    public class Game1 : Game 
    { 
     private BasicEffect _basicEffect; 
     private GraphicsDeviceManager _graphics; 


     public Game1() 
     { 
      _graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 
     } 

     protected override void Initialize() 
     { 
      _basicEffect = new BasicEffect(GraphicsDevice) {VertexColorEnabled = true}; 
      base.Initialize(); 
     } 


     protected override void Update(GameTime gameTime) 
     { 
      if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || 
       Keyboard.GetState().IsKeyDown(Keys.Escape)) 
       Exit(); 
      base.Update(gameTime); 
     } 

     private void DrawSquare(BasicEffect basicEffect, Vector2 position, Vector2 size, Color tint) 
     { 
      // square made out of 2 triangles 
      var colors = new[] 
      { 
       new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), Color.White), 
       new VertexPositionColor(new Vector3(+0.5f, -0.5f, 0.0f), Color.White), 
       new VertexPositionColor(new Vector3(+0.5f, +0.5f, 0.0f), Color.White), 
       new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), Color.White), 
       new VertexPositionColor(new Vector3(+0.5f, +0.5f, 0.0f), Color.White), 
       new VertexPositionColor(new Vector3(-0.5f, +0.5f, 0.0f), Color.White) 
      }; 

      basicEffect.World = // NOTE: the correct order for matrices is SRT (scale, rotate, translate) 
       Matrix.CreateTranslation(0.5f, 0.5f, 0.0f)* // offset by half pixel to get pixel perfect rendering 
       Matrix.CreateScale(size.X, size.Y, 1.0f)* // set size 
       Matrix.CreateTranslation(position.X, position.Y, 0.0f)* // set position 
       Matrix.CreateOrthographicOffCenter // 2d projection 
        (
         0.0f, 
         GraphicsDevice.Viewport.Width, // NOTE : here not an X-coordinate (i.e. width - 1) 
         GraphicsDevice.Viewport.Height, 
         0.0f, 
         0.0f, 
         1.0f 
        ); 

      // tint it however you like 
      basicEffect.DiffuseColor = tint.ToVector3(); 

      var passes = _basicEffect.CurrentTechnique.Passes; 
      foreach (var pass in passes) 
      { 
       pass.Apply(); 
       GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, colors, 0, colors.Length/3); 
      } 
     } 

     /// <summary> 
     ///  This is called when the game should draw itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Draw(GameTime gameTime) 
     { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 

      DrawSquare(_basicEffect, new Vector2(10, 10), new Vector2(100, 100), Color.Red); 
      DrawSquare(_basicEffect, new Vector2(200, 200), new Vector2(50, 50), Color.Green); 

      base.Draw(gameTime); 
     } 
    } 
} 

enter image description here

+0

Спасибо за замечательный ответ. Как я могу заставить VertexPositionColors быть прямо пропорциональным размеру фигуры? Я пытался найти алгоритм в течение нескольких часов. –

+0

Что вам нужно сделать, так это держать вещи в диапазоне от -0,5 до +0,5 во всех осях, вы видите, что мой прямоугольник точно равен 1,0 единицам, как это http://www.csharphelper.com/platonic_3_1.png. Затем вы видите, что мировая матрица основного эффекта имеет масштаб, который масштабирует его. Потому что, используя масштаб 1 при умножении, вы получаете точный размер в пикселях ... надеюсь, что это имеет смысл! PS. поскольку вы делаете 2d, на самом деле не важно устанавливать компоненты Z, я поставил их на ноль. – Aybe

+0

Конечно, массив вершин (или буфер вершин + индекс) должен быть кэширован в классе Shape в реальном коде. Отличный пример: +1. –

Смежные вопросы