我的敌人精灵在到达变量endposition后一直振动。怎么了?它为什么会振动? 另外,变量next_position永远不会成立。但为什么?我希望敌人精灵在到达当前结束位置后移动到新的随机结束位置。
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D enemy;
Vector2 position, endposition;
bool next_position = false;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
enemy = Content.Load<Texture2D>("zombie");
Random randomstart = new Random();
position = new Vector2(randomstart.Next(100, 200), randomstart.Next(100, 200));
endposition = new Vector2(randomstart.Next(100, 600), randomstart.Next(100, 400));
}
protected override void Update(GameTime gameTime)
{
float delta = (float)gameTime.ElapsedGameTime.TotalSeconds;
Random random = new Random();
position.X += 5 * delta;
position.Y += 3 * delta;
if (next_position == true)
{
endposition = new Vector2(random.Next(100, 600), random.Next(100, 400));
next_position = false;
}
if (Vector2.Dot(endposition - position, endposition - position) > 0 || Vector2.Dot(endposition - position, endposition - position) < 0)
{
Vector2 enemyDirection = Vector2.Normalize(endposition - position) * 100f;
position += enemyDirection * delta;
}
else
{
next_position = true;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(enemy, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
答案 0 :(得分:4)
我对这行
感到有些困惑if (Vector2.Dot(endposition - position, endposition - position) > 0 || Vector2.Dot(endposition - position, endposition - position) < 0)
应该完全做到。 从代码的其余部分开始,您正在尝试使用它来检查精灵的位置是否是敌人的位置。 该线实际上做的是计算相反方向的矢量的点积,除非矢量为零,否则它们永远不会为零。所以从理论上讲,这可能确实有效,但前提是这个位置恰好等于敌人的位置。
但是,你将精灵每单位时间移动一个固定的距离,所以它实际上并没有到达敌人,而是超过了它。找到自己然后在另一边它向后移动,它来自哪里,并再次超过它。这种情况会持续下去并导致您描述的振动。
现在,你想要实现的行为通常是使用毕达哥拉斯定理计算两个物体(精灵和敌人)之间的距离,然后当距离低于a时接受物体的到达某个阈值(容易但容易出错),或者比对象可以通过此特定更新的距离短(在您的情况下,因为您按标准化向量移动100f * delta
,此距离等于{{1} })。
我希望我的解释很有帮助。 当然,请随时要求澄清。
修改(回复评论):
您正在创建的100f * delta
向量相对没有意义,因为它只是在x和y方向上偏移limit
的位置。没有必要这样的东西。
但是,其他max_distance
包含了您想要的代码,请查看:
if()
这真的很简单,不需要其他检查。如果这对您有用,请告诉我!
答案 1 :(得分:0)
现在好多了,但并不完美。敌人精灵不再振动,但如果它到达终点位置,它总会向右移动一些像素。为什么它总是向右移动一些像素? 其余的工作正常。
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D enemy;
Vector2 position, endposition;
bool next_position = false;
int count_nextposition;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
enemy = Content.Load<Texture2D>("zombie");
Random randomstart = new Random();
position = new Vector2(randomstart.Next(100, 200), randomstart.Next(100, 200));
endposition = new Vector2(randomstart.Next(100, 600), randomstart.Next(100, 400));
count_nextposition = randomstart.Next(90, 121);
}
protected override void Update(GameTime gameTime)
{
float delta = (float)gameTime.ElapsedGameTime.TotalSeconds;
count_nextposition -= 1;
Random random = new Random();
position.X += 5 * delta;
position.Y += 3 * delta;
if (count_nextposition <= 0)
{
if (next_position == true)
{
endposition = new Vector2(random.Next(100, 600), random.Next(100, 400));
next_position = false;
}
float max_distance = 100f * delta;
if ((position - endposition).LengthSquared() > max_distance * max_distance)
{
Vector2 enemyDirection = Vector2.Normalize(endposition - position) * 100f;
position += enemyDirection * delta;
}
else
{
next_position = true;
count_nextposition = random.Next(90, 121);
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(enemy, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}