2016-04-27 3 views
1

Привет, я пытаюсь сделать программу рисования с помощью XNA, и я следовал за гидом, найденным здесь здесь, как можно больше: How to create Paint-like app with XNA? И все это отлично работало, однако есть одна проблема: the drawn rectangles dont connect together to form a line. I я не знаю, и я был бы признателен за любую помощь. Вот мой код ниже. Пожалуйста, также взгляните на изображение, прикрепленное, чтобы получить лучшее понимание.Создание программы рисования с использованием XNA

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using System; 
using System.Collections.Generic; 

namespace ProfAnas 
{ 
/// <summary> 
/// This is the main type for your game. 
/// </summary> 
public class Game1 : Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 
    Texture2D canvas; 
    Vector2 brushPos; 

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

     graphics.PreferredBackBufferWidth = 1920; // set this value to the desired width of your window 
     graphics.PreferredBackBufferHeight = 1080; // set this value to the desired height of your window 
     graphics.ApplyChanges(); 
    } 

    /// <summary> 
    /// Allows the game to perform any initialization it needs to before starting to run. 
    /// This is where it can query for any required services and load any non-graphic 
    /// related content. Calling base.Initialize will enumerate through any components 
    /// and initialize them as well. 
    /// </summary> 
    protected override void Initialize() 
    { 
     // TODO: Add your initialization logic here 
     base.Initialize(); 

     Color[] pixel = new Color[1920 * 1080]; 
     for (int i = 0; i < pixel.Length; i++) 
     { 
      pixel[i] = Color.White; 

     } 

     pixel[1919] = Color.Red; 

     spriteBatch = new SpriteBatch(GraphicsDevice); 
     canvas = new Texture2D(this.GraphicsDevice, 1920, 1080); 
     canvas.SetData<Color>(pixel); 

    } 

    /// <summary> 
    /// LoadContent will be called once per game and is the place to load 
    /// all of your content. 
    /// </summary> 
    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 

     // TODO: use this.Content to load your game content here 
    } 

    /// <summary> 
    /// UnloadContent will be called once per game and is the place to unload 
    /// game-specific content. 
    /// </summary> 
    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 

    /// <summary> 
    /// Allows the game to run logic such as updating the world, 
    /// checking for collisions, gathering input, and playing audio. 
    /// </summary> 
    /// <param name="gameTime">Provides a snapshot of timing values.</param> 
    protected override void Update(GameTime gameTime) 
    { 
     MouseState state = Mouse.GetState(); 

     Color[] pixel = new Color[1920 * 1080]; 
     canvas.GetData<Color>(pixel); 

     if (state.LeftButton == ButtonState.Pressed) 
     { 
      brushPos.X = state.X; 
      brushPos.Y = state.Y; 

      double piOn4 = Math.PI/4; 

      int xComponent; 
      int yComponent; 

      int screenWidth = 1920; 
      int screenHeight = 1080; 

      int regionXHalfed = (int)Math.Ceiling((10.0 * Math.Cos(piOn4) + 30.0 * Math.Cos(piOn4))/2); 
      int regionYHalfed = (int)Math.Ceiling((10.0 * Math.Sin(piOn4) + 30.0 * Math.Sin(piOn4))/2); 

      double angle; 
      double centerToBoundary; 
      double pixelToCenter; 
      List<int> boundedPixel = new List<int>(); 


      for (int row=(state.Y-regionYHalfed); row < (state.Y + regionYHalfed); row++) 
      { 
       for (int column= (state.X - regionXHalfed); column < (state.X + regionXHalfed); column++) 
       { 


        xComponent=column - state.X+1; 
        yComponent=row - state.Y+1; 

        if (xComponent == 0) 
        { 
         pixelToCenter = Math.Sqrt((double)xComponent*xComponent + (double)yComponent*yComponent); 

         if (Math.Abs(pixelToCenter) <= 5*Math.Sqrt(2)) 
         { 
          boundedPixel.Add(((row) * screenWidth + column) + 1); 
         } 

         continue; 
        } 

        angle=Math.Atan((double)yComponent/(double)xComponent); 



        if (angle>= (piOn4 - Math.Atan(1.0/3)) && angle<= (piOn4 + Math.Atan(1.0/3))) 
        { 
         centerToBoundary = 15/Math.Cos(angle - piOn4); 
         pixelToCenter= xComponent/Math.Cos(angle); 

         if(Math.Abs(pixelToCenter) <= Math.Abs(centerToBoundary)) 
         { 
          boundedPixel.Add(((row)* screenWidth + column)+1); 
         } 
        } 

        if (angle >= (piOn4 + Math.Atan(1.0/3)) && angle <= Math.PI/2) 
        { 
         centerToBoundary = 5/Math.Cos(angle + piOn4); 
         pixelToCenter = xComponent/Math.Cos(angle); 

         if (Math.Abs(pixelToCenter) <= Math.Abs(centerToBoundary)) 
         { 
          boundedPixel.Add(((row) * screenWidth + column) + 1); 
         } 
        } 
        if (angle >= 0.0 && angle <= (piOn4 - Math.Atan(1.0/3))) 
        { 
         centerToBoundary = 5/Math.Cos(angle + piOn4); 
         pixelToCenter = xComponent/Math.Cos(angle); 

         if (Math.Abs(pixelToCenter) <= Math.Abs(centerToBoundary)) 
         { 
          boundedPixel.Add(((row) * screenWidth + column) + 1); 
         } 
        } 

        if (angle >= -Math.PI/2 && angle <= 0.0) 
        { 
         centerToBoundary = 5/Math.Cos(angle + piOn4); 
         pixelToCenter = xComponent/Math.Cos(angle); 

         if (Math.Abs(pixelToCenter) <= Math.Abs(centerToBoundary)) 
         { 
          boundedPixel.Add(((row) * screenWidth + column) + 1); 
         } 
        } 

       } 
      } 

      foreach (int i in boundedPixel) 
      { 
       if(i>=0) 
        pixel[i] = Color.Red; 

      } 
     } 

     canvas.SetData<Color>(pixel); 

     // TODO: Add your update logic here 

     base.Update(gameTime); 
    } 

    /// <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); 

     // TODO: Add your drawing code here 
     spriteBatch.Begin(); 
     spriteBatch.Draw(canvas, new Vector2(0, 0)); 
     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 
} 
} 

Спасибо :)

+1

Это происходит потому, что расстояние между шагами между кадрами больше, чем ширина вашей «кисти». Приведенный ниже пример просто не учитывает эту ситуацию. Тебе придется попробовать что-то более интересное. – adv12

ответ

0

Как @ adv12 предложил метод Обновление XNA игр не так быстро, как один из MSPaint, и именно поэтому вы никогда не будете иметь линию, если рисунок пикселя -by-pixel (или в вашем случае прямоугольник-по-прямоугольнику), если вы быстро перемещаете мышь по холсту.

Возможное решение состоит в том, чтобы нарисовать новые прямоугольники, когда вы отпускаете левую кнопку мыши, между прямоугольниками, которые были созданы при нажатии левой кнопки мыши. Это даст вам дважды -1 прямоугольников, которые вы сейчас рисуете, и у вас будет строка, независимо от того, как быстро вызывается Update.