使用XNA制作绘图程序

时间:2016-04-27 18:21:29

标签: c# mono xna paint

您好我正在尝试使用XNA制作绘图程序,我尽可能地遵循此处的指南:How to create Paint-like app with XNA? 到目前为止它仍然很有效,但是有一个问题:the drawn rectangles dont connect together to form a line.我没有想法,我将不胜感激任何帮助。下面是我的代码。另请查看附图,以便更好地理解。

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 个答案:

答案 0 :(得分:0)

正如@ adv12建议的那样,XNA游戏的更新方法并不像MSPaint那样快,这就是为什么如果绘制像素你永远不会有一条线的原因如果您在画布上快速移动鼠标,则逐像素(或在矩形中逐个矩形)。

可能的解决方案是在释放鼠标左键时,在按下鼠标左键时创建的矩形之间绘制新的矩形。这将给你两倍-1你正在绘制的矩形,无论调用Update多快,你都会有一条线。