在Monogame(c#)中,我无法弄清楚如何保持一个物体(在这种情况下是一个汉堡)留在游戏窗口的边界内,这样它就不会在光标移动时离开游戏窗口。或者换句话说,将一个对象“夹住”到游戏窗口。
public class Burger
{
#region Fields
// graphic and drawing info
Texture2D sprite;
Rectangle drawRectangle;
// burger stats
int health = 100;
// shooting support
bool canShoot = true;
int elapsedCooldownMilliseconds = 0;
// sound effect
SoundEffect shootSound;
#endregion
#region Constructors
/// <summary>
/// Constructs a burger
/// </summary>
/// <param name="contentManager">the content manager for loading content</param>
/// <param name="spriteName">the sprite name</param>
/// <param name="x">the x location of the center of the burger</param>
/// <param name="y">the y location of the center of the burger</param>
/// <param name="shootSound">the sound the burger plays when shooting</param>
public Burger(ContentManager contentManager, string spriteName, int x, int y,
SoundEffect shootSound)
{
LoadContent(contentManager, spriteName, x, y);
this.shootSound = shootSound;
}
#endregion
#region Properties
/// <summary>
/// Gets the collision rectangle for the burger
/// </summary>
public Rectangle CollisionRectangle
{
get { return drawRectangle; }
}
#endregion
#region Public methods
/// <summary>
/// Updates the burger's location based on mouse. Also fires
/// french fries as appropriate
/// </summary>
/// <param name="gameTime">game time</param>
/// <param name="mouse">the current state of the mouse</param>
public void Update(GameTime gameTime, MouseState mouse)
{
// burger should only respond to input if it still has health
// move burger using mouse
if (health > 0)
{
drawRectangle.X = mouse.X;
drawRectangle.Y = mouse.Y;
}
// clamp burger in window
[THIS IS WHERE THE CODE SHOULD GO]
// update shooting allowed
// timer concept (for animations) introduced in Chapter 7
// shoot if appropriate
}
/// <summary>
/// Draws the burger
/// </summary>
/// <param name="spriteBatch">the sprite batch to use</param>
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(sprite, drawRectangle, Color.CornflowerBlue);
}
#endregion
#region Private methods
/// <summary>
/// Loads the content for the burger
/// </summary>
/// <param name="contentManager">the content manager to use</param>
/// <param name="spriteName">the name of the sprite for the burger</param>
/// <param name="x">the x location of the center of the burger</param>
/// <param name="y">the y location of the center of the burger</param>
private void LoadContent(ContentManager contentManager, string spriteName,
int x, int y)
{
// load content and set remainder of draw rectangle
sprite = contentManager.Load<Texture2D>(spriteName);
drawRectangle = new Rectangle(x - sprite.Width / 2,
y - sprite.Height / 2, sprite.Width,
sprite.Height);
}
#endregion
}
我有什么想法可以解决这个问题?我已经尝试过使用mouse.Getstate并尝试将鼠标光标锁定到窗口,但这似乎不起作用。
答案 0 :(得分:1)
问题似乎是你正在控制你汉堡课程内的坐标(很好的问题)而且你似乎没有任何对窗口边界的引用。
我看到它的方式是你有两个选择:
选项1.它不错,但在较大的项目中,它可能会适得其反的项目阶段:
public void Update(GameTime gameTime, MouseState mouse)
{
if (health > 0)
{
//Simple version
//if mouse is within borders, continue with position update.
if(mouse.X > 0 && mouse.X < windowWidth && mouse.Y > 0 && mouse.Y < windowHeight){
drawRectangle.X = mouse.X;
drawRectangle.Y = mouse.Y;
}else{
//stuff to do if it it's not updating
}
//a little different (better) version that should trace walls
if(mouse.X < 0){
drawRectangle.X = 0;
}else if(mouse.X + drawRectangle.width > windowWidth){ //if I made no mistakes it should subtract the size of the picture and trace the inside border if mouse is outside
drawRectangle.X = windowWidth - drawRectangle.width;
}else{
drawRectangle.X = mouse.X
}
if(mouse.Y < 0){
drawRectangle.Y = 0;
}else if(mouse.Y + drawRectangle.height > windowHeight ){
drawRectangle.Y = windowHeight - drawRectangle.height;
}else{
drawRectangle.Y = mouse.Y
}
}
}
当鼠标位于边框之外时,选项2限制主更新功能中的更新调用:
class YourApp{
....
public void Update(GameTime gameTime, MouseState mouse)
{
if([mouse is within the window]){
burger.Update(...);
//+most of your updates here
}else{
//pause game or just display a warning that mouse is outside of the window
}
}
...
}
答案 1 :(得分:0)
当您为drawRectangle的X和Y属性赋值时,您应该执行Min和Max函数以确保其位置在窗口内。
drawRectangle.X = Math.Min(Math.Max(mouse.X, 0), GraphicsDevice.Viewport.Width);
drawRectangle.Y = Math.Min(Math.Max(mouse.Y, 0), GraphicsDevice.Viewport.Height);
如果你想让精灵完全受限,你必须考虑精灵/矩形自身的高度和宽度(假设X和Y位置是矩形的左上角,我可以&# 39;记住XNA的矩形是否与System.Drawing中的矩形不同。
drawRectangle.X = Math.Min(Math.Max(mouse.X, 0), (GraphicsDevice.Viewport.Width - drawRectangle.Width));
drawRectangle.Y = Math.Min(Math.Max(mouse.Y, 0), (GraphicsDevice.Viewport.Height - drawRectangle.Height));
答案 2 :(得分:0)
您可以使用MathHelper.Clamp()
进行裁剪,使用GraphicsDevice.Viewport
作为屏幕尺寸:
public void Update(GameTime gameTime, MouseState mouse)
{
if (health > 0)
{
drawRectangle.X = (int) MathHelper.Clamp(mouse.X, 0,
GraphicsDevice.Viewport.Width - drawRectangle.Width);
drawRectangle.Y = (int) MathHelper.Clamp(mouse.Y, 0,
GraphicsDevice.Viewport.Height - drawRectangle.Height);
}
// ...
}