У меня проблема с платформой XNA, у меня есть урезанная версия моего кода для демонстрации.При щелчке мыши объект создается в этой точке щелчка мыши, и объект отображается с помощью собственного метода рисования.
В результате получается, что первый объект создается в правильной позиции (отображаются текущие координаты мыши).как текст), но когда создается первый объект, текущие координаты мыши смещаются относительно положения окна.Последующее создание объектов компенсирует это снова, пока я не получу довольно диагональ объекта по экрану.Если я удаляю метод для создания объекта, то все хорошо - мышиные координаты остаются хорошими относительно окна.
Вот код, есть базовые методы, метод для создания объекта, класс дляобъект и класс, чтобы найти мышь inout.Кто-нибудь еще имел эту проблему или может видеть, что я делаю неправильно?
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
}
}