2010-01-20 5 views
1

XNA 프레임 워크에 문제가 있습니다. 여기에 내 코드를 보여줄 수있는 스트립 된 버전이 있습니다. 마우스를 클릭하면 해당 마우스 클릭 점에서 객체가 만들어지고 객체는 자체 그리기 방법을 통해 표시됩니다.XNA 마우스 코즈 대 객체 문제

첫 번째 개체가 올바른 위치에 작성되었지만 (현재 마우스 좌표가 텍스트로 표시됨) 첫 번째 개체가 만들어지면 현재 마우스 좌표는 창 위치를 기준으로 상쇄됩니다. 객체의 후속 생성은 화면에서 객체의 대각선을 얻을 때까지 다시 오프셋합니다. 오브젝트를 생성하기위한 메소드를 제거하면, 모든 것이 잘 맞습니다. 윈도우에 비해 마우스가 잘 유지됩니다.

다음은 코드입니다. 기본 메소드, 객체를 만드는 메소드, 객체의 클래스 및 마우스를 찾을 클래스가 있습니다. 다른 사람이이 문제가 있거나 내가 뭘 잘못하고 있는지 알 수 있습니까?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 
using Microsoft.Xna.Framework.Net; 
using Microsoft.Xna.Framework.Storage; 

namespace mousetest 
{ 
/// <summary> 
/// This is the main type for your game 
/// </summary> 
public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 
    public SpriteFont defaultFont; 

    public static Vector2 mousepos; 

    public Texture2D anobjectTexture; 

    public List<anobject> anobjectList = new List<anobject>(); 

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

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

     //make the mouse pointer visible 
     this.IsMouseVisible = true; 

     base.Initialize(); 
    } 

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

     defaultFont = Content.Load<SpriteFont>(@"fonts\arial"); 

     anobjectTexture = Content.Load<Texture2D>("reddot"); 
    } 

    /// <summary> 
    /// UnloadContent will be called once per game and is the place to unload 
    /// all 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) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 

     mouseUpdate(); 

     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 

     //draw the mouse coords 
     //Draw the debug text 
     // 
     spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.FrontToBack, SaveStateMode.None); 

     spriteBatch.DrawString(defaultFont, "mousex: " + mousepos.X + " mousey: " +mousepos.Y, 
      new Vector2(10, 10), Color.Black, 0, Vector2.Zero, 1, SpriteEffects.None, 1); 


     int i = 0; 
     foreach (anobject theobject in anobjectList) 
     { 
      theobject.drawObject(spriteBatch); 
      i++; 
     } 

     spriteBatch.DrawString(defaultFont, "objects: " + i, 
     new Vector2(10, 20), Color.Black, 0, Vector2.Zero, 1, SpriteEffects.None, 1); 

     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 

    //mouse test method 
    public Vector2 mouseUpdate() 
    { 
     MouseInput.CheckMouse(800, 600); 
     mousepos.X = MouseInput.mouseState.X; 
     mousepos.Y = MouseInput.mouseState.Y; 

     if (MouseInput.ismouse_leftbuttonpressed == 1) 
     { 
      if (MouseInput.ismouse_leftbuttonheld == 0) 
      { 
       doSomething(); 
      } 
     } 

     return mousepos; 
    } 


    public void doSomething() 
    { 
     //create an instance of the 'anobject' class when the mouse is clicked 

     anobject testobject = new anobject(mousepos, anobjectTexture); 
     anobjectList.Add(testobject); 

    } 
} 


public class anobject : Game1 
{ 
    public Vector2 position; 
    public Texture2D anobjectTexture; 

    //constructor 
    public anobject(Vector2 inpos, Texture2D inTexture) 
    { 
     position = inpos; 
     anobjectTexture = inTexture; 

    } 

    public void drawObject(SpriteBatch inspritebatch) 
    { 

     inspritebatch.Draw(anobjectTexture, 
        new Vector2(
        (position.X), 
        (position.Y)), 
        null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0.99f); 
    } 

    }//end of class 
} 


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework; 

namespace mousetest 
{ 
    class MouseInput: Game1 
    { 
     public static MouseState mouseState; 

     // might need this just cause the way the api mouse call works 
     public static Vector2 mouseLocation; 
     // these are Mouse position values 
     public static int mousePosition_X = 0; 
     public static int mousePosition_Y = 0; 
     public static float virt_mousePosition_X = 0.0f; // this is calculated to were the mouse is as a percentage of screen width height 
     public static float virt_mousePosition_Y = 0.0f; // this is very useful for seting positions of boxes and buttons ect... 
     // left mouse button 
     public static int ismouse_leftbuttonpressed = 0; // is left being pressed at this moment 
     public static int leftmouselastpressedatX = 0; 
     public static int leftmouselastpressedatY = 0; 
     public static int leftmouselastdragreleasedX = 0; 
     public static int leftmouselastdragreleasedY = 0; 
     public static int ismouse_leftbuttonheld = 0; // is left being held down 
     // right mouse button 
     public static int ismouse_rightbuttonpressed = 0; // is right being pressed at this moment 
     public static int rightmouselastpressedatX = 0; 
     public static int rightmouselastpressedatY = 0; 
     public static int rightmouselastdragreleasedX = 0; 
     public static int rightmouselastdragreleasedY = 0; 
     public static int ismouse_rightbuttonheld = 0; // is right being held down 
     // this is the scroll wheel 
     public static int mousewheel_value = 0; // this will mainly affect the zoomvalue its multiplyed by a small number to get the below 
     public static int mouseoldwheel_value = 0; 
     public static float zoomwheel_value = 0; // this is a value that relects the % of zoom 
     public static float zoomvalue = 1.0F; // this we modify later on for mouse scrolling zooming 


     /// <summary> 
     /// one lil problem this is still in this function SGMKS.screenWidth; so ill have to deal with that later on 
     /// as the screen size might change and thus ruin alot of info if we dont update that 
     /// 
     /// get the mouse values and save them into a static class to track those variables 
     /// </summary> 
     public static void CheckMouse(int sW, int sH) 
     { 
      // grab the mouse state from the input class 
      mouseState = Mouse.GetState(); 
      // save the current mouse position into another variable for later use 
      mousePosition_X = mouseState.X; 
      mousePosition_Y = mouseState.Y; 
      virt_mousePosition_X = (float)mousePosition_X/(float)sW; 
      virt_mousePosition_Y = (float)mousePosition_Y/(float)sH; 
      // or we could put this in a vector instead 
      mouseLocation = new Vector2(mousePosition_X, mousePosition_Y); 

      // Processing when carrying out the left click of the mouse 
      //_______________________________________________ 
      if (mouseState.LeftButton == ButtonState.Pressed) 
      { 
       //NOTE THESE ARE PLACED IN A SPECIFIC ORDER TO ENSURE THAT DRAG CLICK LOGIC IS CORRECT 
       // Never *** it up note to self thanks 
       // on the first pass the below will set the lastposmousepressed to the current position 
       if (ismouse_leftbuttonheld == 0) // this executes on the first pass and the second pass but not the third pass 
       { 
        if (ismouse_leftbuttonpressed == 1) // this condition will not execute untill the second pass thru the function 
        { 
         ismouse_leftbuttonheld = 1; // now we mark it as being held on the second pass       
        } 
        else // this executes on the first pass only 
        { 
         leftmouselastpressedatX = mousePosition_X; // and we save the click of the first point of holding 
         leftmouselastpressedatY = mousePosition_Y; // so when released we know were we draged from 
        } 
       } 
       // set at the end of but still in the first pass 
       ismouse_leftbuttonpressed = 1;// we SET this after the call to is leftbutton pressed now to to ensure next pass its active 
      } 
      else 
      { // mouse itself is no longer registering the button pressed so.. toggle held and button pressed off 
       ismouse_leftbuttonpressed = 0; 
       if (ismouse_leftbuttonheld == 1) 
       { 
        leftmouselastdragreleasedX = mousePosition_X; 
        leftmouselastdragreleasedY = mousePosition_Y; 
       } 
       ismouse_leftbuttonheld = 0; 
      } 

      // Processing when carrying out the right click of the mouse 
      //________________________________________________ 
      if (mouseState.RightButton == ButtonState.Pressed) 
      { 
       //NOTE THESE ARE PLACED IN A SPECIFIC ORDER TO ENSURE THAT DRAG CLICK LOGIC IS CORRECT 
       // on the first pass the below will set the lastposmousepressed to the current position 
       if (ismouse_rightbuttonheld == 0) // this executes on the first pass and the second pass but not the third pass 
       { 
        if (ismouse_rightbuttonpressed == 1) // this condition will not execute untill the second pass thru the function 
        { 
         ismouse_rightbuttonheld = 1; // now we mark it as being held on the second pass 
        } 
        else // this executes on the first pass only 
        { 
         rightmouselastpressedatX = mousePosition_X; // and we save the click of the first point of holding 
         rightmouselastpressedatY = mousePosition_Y; // so when released we know were we draged from 
        } 
       } 
       // set at the end of the first pass 
       ismouse_rightbuttonpressed = 1;// we SET this after the call to is rightbutton pressed now to to ensure next pass its active 
      } 
      else 
      { // right mouse button itself is no longer registering the button pressed so.. toggle held and button pressed off 
       ismouse_rightbuttonpressed = 0; 
       if (ismouse_rightbuttonheld == 1) 
       { 
        rightmouselastdragreleasedX = mousePosition_X; 
        rightmouselastdragreleasedY = mousePosition_Y; 
       } 
       ismouse_rightbuttonheld = 0; 
      } 

     }//endof method 


    } 
} 
+0

질문을 이해하는 데 어려움을 겪고 있습니다. 오프셋이 잘못되었다고 말하는거야? 프로젝트의 모든 클래스를 붙여 넣는 대신 문제가 발생한 코드의 일부를 지적 할 수 있습니까? –

+0

아, 죄송합니다. 문제는 오프셋이 전혀 없다는 것입니다. 좌표는 '대상'의 인스턴스가 만들어 질 때까지는 괜찮습니다. 오프셋이 좌표에 추가됩니다. – jon

답변

1

귀하의 MouseInput 및 anObject를 클래스는 GAME1 클래스에서 하강하는, 그래서 당신은 anObject를의 인스턴스를 만들 때마다 당신은 게임의 인스턴스를 생성하고 있습니다. Mouse.GetState의

부()는 다음과 같습니다 : 그래서

if (hHookedHandle != null) 
{ 
    ScreenToClient(hHookedHandle, &gpoint); 
} 

, 게임 클래스는 마우스 화면으로 변환됩니다 너무 많이 더 깊이 그것으로 보지 않고 창 좌표로 조정합니다. 따라서 새 게임 인스턴스를 만들 때마다 이전 인스턴스의 자식 일 가능성이 높습니다. 따라서 해당 좌표는 부모 인스턴스 내에 있습니다.

해결 방법은 클래스에서 ": Game1"을 제거하는 것입니다. 일반적으로 프로젝트에는 하나의 Game 클래스 만 있으면됩니다.

+0

문제는 많은 감사드립니다. – jon