C# 使用XNA制作绘画程序

C# 使用XNA制作绘画程序,c#,mono,xna,paint,C#,Mono,Xna,Paint,您好,我正在尝试使用XNA制作一个绘画程序,我尽可能地遵循这里的指南: 到目前为止,这一切都很好,但有一个问题:我没有主意了,如果能提供任何帮助,我将不胜感激。下面是我的密码。请也看一下所附的图片,以便更好地理解 using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collecti

您好,我正在尝试使用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);
    }
}
}
使用Microsoft.Xna.Framework;
使用Microsoft.Xna.Framework.Graphics;
使用Microsoft.Xna.Framework.Input;
使用制度;
使用System.Collections.Generic;
名称空间普罗法纳
{
/// 
///这是游戏的主要类型。
/// 
公共类游戏1:游戏
{
图形管理器图形;
SpriteBatch SpriteBatch;
纹理2D帆布;
向量2;
公共游戏1()
{
graphics=新的GraphicsDeviceManager(此);
Content.RootDirectory=“Content”;
graphics.PreferredBackBufferWidth=1920;//将此值设置为所需的窗口宽度
graphics.PreferredBackBufferHeight=1080;//将此值设置为所需的窗口高度
graphics.ApplyChanges();
}
/// 
///允许游戏在开始运行之前执行任何需要的初始化。
///在这里,它可以查询任何必需的服务,并加载任何非图形化的服务
///相关内容。调用base.Initialize将枚举所有组件
///并对它们进行初始化。
/// 
受保护的覆盖无效初始化()
{
//TODO:在此处添加初始化逻辑
base.Initialize();
颜色[]像素=新颜色[1920*1080];
对于(int i=0;i如果(Math.Abs(pixelToCenter)=(piOn4-Math.Atan(1.0/3))&&angle如@adv12所示,XNA游戏的更新方法不如MSPaint的更新方法快,这就是为什么如果你在画布上快速移动鼠标,一个像素一个像素(或者在你的例子中是一个矩形一个矩形)地绘制,你永远不会有一条线


可能的解决方案是在按下鼠标左键时创建的矩形之间,释放鼠标左键时绘制新的矩形。这将为您提供两倍-1当前绘制的矩形,并且无论调用
更新
的速度有多快,您都将有一条线。

正如@adv12所建议的,UpdaXNA游戏的te方法不如MSPaint的方法快,这就是为什么如果你在画布上快速移动鼠标,一个像素一个像素(或者在你的例子中是矩形一个矩形)地画,你永远不会有一条线


可能的解决方案是,当您松开鼠标左键时,在按下鼠标左键时创建的矩形之间绘制新的矩形。这将为您提供两倍-1当前绘制的矩形,并且您将有一条线,无论调用
更新的速度有多快。

这是因为鼠标在帧之间移动的距离大于“画笔”的宽度。您所使用的示例无法解释这种情况。您必须尝试更高级的方法。之所以会出现这种情况,是因为鼠标在帧之间移动的距离大于“画笔”的宽度你所遵循的例子根本不能解释这种情况。你必须尝试一些更奇特的东西。