我的敌人精灵在到达可变端点后一直在振动。怎么啦?为什么它在震动?此外,变量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);
}
}发布于 2012-12-09 08:36:29
我对这条线有点困惑
if (Vector2.Dot(endposition - position, endposition - position) > 0 || Vector2.Dot(endposition - position, endposition - position) < 0)应该做的就是。从代码的其余部分看,你要用它来实现的是检查精灵的位置是否是敌人的位置。这条线实际做的是计算相反方向的向量的点积,它永远不会是零,除非向量是零。因此从理论上讲,这实际上可能是可行的,但前提是位置必须与敌人的位置精确相等。
但是,你是在单位时间内移动精灵一个固定的距离,所以它实际上不会到达敌人,而是超过了敌人。然后发现自己在另一边,它会回到它来自的地方,并再次超过它。这会持续下去,并导致你所描述的振动。
现在,你想要实现的行为通常是计算两个对象(精灵和敌人)之间的距离,使用毕达哥拉斯定理,然后在距离低于某个阈值(容易但容易出错)或小于对象可以通过此特定更新的距离时接受对象的到达(在您的情况下,由于您移动的是归一化向量乘以100f * delta,此距离等于100f * delta)。
我希望我的解释对你有所帮助。当然,请随时要求澄清。
编辑(回复评论):
您正在创建的limit向量相对没有意义,因为它只是max_distance在x和y方向上的位置偏移。没有必要做这样的事情。但是,另一个if()几乎包含了您想要的代码,请查看以下内容:
// first you calculate the distance we can move this update
float max_distance = 100f * delta;
// now, we compare the actual distance to the end position to that maximum
// if the actual distance is larger, then we are not there yet
// otherwise, (if the actual distance is smaller) we will overshoot the target,
// thus we are in fact there! (=close enough to continue)
// (note: we compare the distances squared to avoid a square root,
// which makes this check much faster, which is good practice,
// in case we ever scale this up to more objects)
if ((position - endposition).LengthSquared() > max_distance * max_distance)
{
/* we are not yet there, continue moving! */
}
else
{
/* we are there! */
}它真的很简单,不需要其他的检查。如果这对你有用,请让我知道!
发布于 2012-12-10 03:31:27
现在好多了,但还不够完美。敌人的精灵不再振动,但当它到达终点位置时,它总是向右移动一些像素。为什么它总是向右移动一些像素?其余的都运行得很好。
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);
}
}https://stackoverflow.com/questions/13783244
复制相似问题