2016-04-27 8 views
1

Hallo Ich versuche, ein Malprogramm mit XNA zu machen und ich folgte der Anleitung hier so viel wie möglich: How to create Paint-like app with XNA? Und es funktionierte alle großen bisher jedoch gibt es ein Problem: the drawn rectangles dont connect together to form a line. I bin aus Ideen und ich würde jede Hilfe, die angeboten wird, schätzen. Hier ist mein Code unten. Bitte werfen Sie auch einen Blick auf das beigefügte Bild, um ein besseres Verständnis zu erhalten.Machen Sie ein Malprogramm mit 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); 
    } 
} 
} 

Danke :)

+1

Dies passiert, weil die Entfernung, die die Maus zwischen Frames bewegt, länger ist als die Breite Ihres "Pinsels". Das Beispiel, das Sie befolgt haben, berücksichtigt diese Situation nicht. Sie müssen etwas Züchtiger versuchen. – adv12

Antwort

0

Als @ adv12 vorgeschlagen, ist die Update-Methode von XNA-Spiele nicht so schnell wie die von MSPaint ist, und das ist, warum Sie nie eine Zeile, wenn Zeichnungspixel haben werden Pixelweise (oder in Ihrem Fall Rechteck um Rechteck), wenn Sie Ihre Maus schnell über die Zeichenfläche bewegen.

Die mögliche Lösung besteht darin, neue Rechtecke zu zeichnen, wenn Sie die linke Maustaste zwischen den Rechtecken loslassen, die erstellt wurden, als die linke Maustaste gedrückt wurde. Das gibt Ihnen zweimal -1 der Rechtecke, die Sie gerade zeichnen, und Sie werden eine Linie haben, egal wie schnell die Update aufgerufen wird.