【问题标题】:XNA - Intersecting classes - 2DXNA - 相交类 - 2D
【发布时间】:2014-01-16 19:15:51
【问题描述】:

好的,所以我一直在寻找几个小时没有任何结果,真的希望你能帮助我。我在让交叉点工作时遇到了一些麻烦。当我的课程发生冲突时什么都没有发生,这可能是我失明但对 XNA 来说真的很陌生。我创建了一个 Shoot-Em-Up 游戏,我希望游戏在玩家控制的航天飞机与敌人相撞时结束。

使用类; Game1.cs、Player.cs 和 Enemy.cs。请注意,我只粘贴了我认为解决此问题所必需的信息。

Game1.cs

protected override void LoadContent()
{
    shuttle = new Player(Content.Load<Texture2D>(@"spaceship"), new Vector2(300, 400), new Vector2(24, 24), spriteBatch);
}

protected override void Update(GameTime gameTime)
{
    if (random.Next(0, 70) < droprate)
    {
        int posX = random.Next(20, 580);
        enemyList.Add(new Enemy(Content.Load<Texture2D>(@"enemy1"), new Vector2(posX, -50), new Vector2(24, 24), spriteBatch));
        droprate += 0.10;
    }

    foreach (Enemy e in enemyList)
    {
        if (shuttle.rectangle.Intersects(e.rectangle))
        Exit();
    }
}

播放器.cs

    public Rectangle rectangle;

    public Player(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
    {
        this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);
    }
    public override void Update(GameTime gameTime)
    {

        KeyboardState keyboardState = Keyboard.GetState();
        if (keyboardState.IsKeyDown(Keys.Right))
        {
            initialPos.X += 9;
        }
        if (keyboardState.IsKeyDown(Keys.Left))
        {
            initialPos.X -= 9;
        }
        if (keyboardState.IsKeyDown(Keys.Up))
        {
            initialPos.Y -= 5;
        }
        if (keyboardState.IsKeyDown(Keys.Down))
        {
            initialPos.Y += 5;
        }

        initialPos.X = MathHelper.Clamp(initialPos.X, 18, screenWidth - 18);
        initialPos.Y = MathHelper.Clamp(initialPos.Y, 24, screenHeight - 24);
        base.Update(gameTime);
    }

敌人.cs

public Rectangle rectangle;

public Enemy(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
{
    this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);
}
    public override void Update(GameTime gameTime)
    {
        initialPos.Y += 3.5f;
        if (initialPos.X < 300)
            initialPos.X += 0.41f;
        if (initialPos.X > 300)
            initialPos.X -= 0.41f;
    }

【问题讨论】:

  • 玩家或敌人会移动吗?在最初创建它们之后,您似乎从未更新它们的碰撞边界。
  • 玩家/穿梭机由我控制,而敌方飞船不断向屏幕底部移动。
  • 您是否曾经为您的Enemy 和Player 对象更新rectangle 的值?您正确使用了Intersects() 方法,这意味着您提供的数据是错误的。
  • 这个我不确定。我可以发布我的更新功能,也许你会更好地理解。
  • 您是否使用过调试器?可能有助于查看您是否正在使用您认为自己正在使用的数据

标签: c# class vector xna rectangles


【解决方案1】:
public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;
    if (initialPos.X < 300)
        initialPos.X += 0.41f;
    if (initialPos.X > 300)
        initialPos.X -= 0.41f;

您应该移动玩家和敌人类的矩形成员。您在构造函数中设置它们一次。屏幕底部的初始玩家矩形永远不会与您在顶部标记的初始敌人位置相交。

我什至不确定 initialPos 是什么,但是如果你想这样做并且精灵正在移动,你需要确保你的 hitboxes 与精灵一起移动。

public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;
    rectangle.Y +=  3.5f;
    if (initialPos.X < 300){
        initialPos.X += 0.41f;
        rectangle.X += 0.41f;
}
    if (initialPos.X > 300)
        initialPos.X -= 0.41f;
        rectangle.X -= 0.41f;
}

编辑:将 RectangleF 用于浮点精度。

Edit2:在游戏中,hitbox 通常比精灵/模型的大小小一点。这将阻止命中从非矩形精灵(如宇宙飞船)中的开放空间注册。 :)

Edit3:或

public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;

    if (initialPos.X < 300) initialPos.X += 0.41f;
    if (initialPos.X > 300) initialPos.X -= 0.41f;


    rectangle.X -= Convert.ToInt32(initialPos.X);
    rectangle.Y += Convert.ToInt32(initialPos.Y);

}

编辑 4:矩形会移动吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestBench{
    class Program{
        static void Main(string[] args){
        float f = 0.0F;
        int Y = 0;

        for (int i = 0; i < 10; i++) {
            f += 0.41F;
            Y = Convert.ToInt32(f);

            Debug.WriteLine("Float: " + f + " Int32 " + Y);

        }

        }
    }
}

结果:

Float: 0.41 Int32 0
Float: 0.82 Int32 1
Float: 1.23 Int32 1
Float: 1.64 Int32 2
Float: 2.05 Int32 2
Float: 2.46 Int32 2
Float: 2.87 Int32 3
Float: 3.28 Int32 3
Float: 3.69 Int32 4
Float: 4.1 Int32 4

【讨论】:

  • 是的,我明白你的意思。但我不能矩形的坐标不能用浮点数表示。它必须在 int 中,我该如何绕过这个?
  • @TheC4Fox,XNA 没有 RectangleF。 @ArvinAshrafi,您可以做的只是像您正在做的那样将位置存储为浮点数,并在每次更新调用结束时,将浮点值转换为一个矩形,就像您在初始化 Players/Enemy 时所做的那样:this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);
  • @davidsbro 使用 XNA 框架意味着他不能使用绘图库?
  • @TheC4Fox 不,但我认为将浮点值转换为 XNA 矩形更容易,因为如果他想使用它,他不必将 RectangleF 转换为矩形,比如说, spritebatch.Draw() 和其他 XNA 函数,人类无法检测到碰撞矩形是否偏离了 0.9f。我只是把它扔在那里,因为它会以任何一种方式完成
【解决方案2】:

如果您想使用浮点值,您可以简单地将initialPos 中的浮点值每次转换为一个矩形。 initialPos 将保持其准确性,矩形将仅对浮点值进行四舍五入。或者您可以创建自己的RectangleF 结构,该结构适用于所有XNA 的其他对象(感谢@TheC4Fox,因为我借鉴了他关于浮点矩形的想法......只是为了让 RectangleF 与 XNA 兼容其他功能很容易。+1 为您的答案兄弟,因为它回答了 OP 的原始 Q)。例如:

public struct RectangleF
{
    float w = 0;
    float h = 0;
    float x = 0;
    float y = 0;

    public float Height
    {
        get { return h; }
        set { h = value; }
    }

    //put Width, X, and Y properties here

    public RectangleF(float X, float Y, float width, float height)
    {
        w = width;
        h = height;
        x = X;
        y = Y;
    }

    public bool Intersects(Rectangle refRectangle)
    {
        Rectangle rec = new Rectangle((int)x, (int)y, (int)w, (int)h);
        if (rec.Intersects(refRectangle)) return true;
        else return false;
    }
}

然后你会在你的 Player 和 Enemy 类中声明这个:

public RectangleF rectangle;

public Enemy(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
{
    this.rectangle = new RectangleF(initialPos.X, initialPos.Y, 48, 48);
}
public override void Update(GameTime gameTime)
{
    rectangle.Y += 3.5f;
    if (rectangle.X < 300)
        rectangle.X += 0.41f;
    if (rectangle.X > 300)
        rectangle.X -= 0.41f;
}

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多