所以我必须为学校开发XNA游戏,我认为Space Invaders是一件好事。但现在我遇到了问题。我有一个List
来自另一个班级的'外星人'。每秒它向右移动20像素,我希望它在接触屏幕右侧时下降(不是问题)。但是我希望它一碰到墙壁就向相反的方向移动(向左)。这就是问题所在。
一旦它接触到墙壁,它仍然会移动20px一次,改变方向,向后移动20px并再次改变方向。这一直在重复。
那么问题在哪里呢。我认为如果其中一个外星人触摸屏幕但不知道如何实现这一目标,我必须先检查一下,并认为也许你们中的一个可以帮助我,因为它非常令人沮丧!
我包含了更新方法
if (xPos % step == 0)
{
if (!isDescending)
{
for (int k = 0; k < sprites.Count; k++)
{
Sprite sprite = sprites[k];
if (touchedRight) sprite.position.X += step;
else sprite.position.X -= step;
}
for (int k = 0; k < sprites.Count; k++)
{
Sprite sprite = sprites[k];
bool hitLeft = sprite.position.X == 0;
bool hitRight = sprite.rect.Right == screenWidth;
if ((hitLeft) || (hitRight))
{
touchedRight = !touchedRight;
isDescending = true;
}
}
}
else
{
isDescending = false;
for (int k = 0; k < sprites.Count; k++)
{
sprites[k].position.Y += sprites[k].rect.Height;
}
}
}
// CheckCollision(alienBounds, k-1);
// sprite.rect = new Rectangle((int)sprite.position.X, (int)sprite.position.Y, 20, 20);
// alienBounds = sprite.rect;
xPos += 1;
答案 0 :(得分:1)
嗯,这是错误的:
if ((hitLeft) || (hitRight))
向右移动时,您只关心hitRight
。向左移动时,您只关心hitLeft
。
所以试试
if (touchedRight? hitLeft: hitRight)
这也将解决多个外星人同时撞墙的问题。
答案 1 :(得分:0)
我不确定,但是我在太空入侵者中咆哮,如果你杀死所有列但是最左边的,它在切换方向之前不会完全移动到屏幕的右侧。
所以我建议你创建一个名为Invader的Sprite派生词:
class Invader : Sprite
{
readonly float distanceFromCenterHorizontal;
public Invader(float distanceFromCenterHorizontal)
{
this.distanceFromCenterHorizontal= distanceFromCenterHorizontal;
}
public void UpdatePosition(Point center)
{
this.Position.X = center.X + distanceFromCenterHorizontal;
this.Position.Y = center.Y;
}
}
// global variables:
Point center = ....
bool moveLeft = false;
void createInvaders()
{
int invaderWidth = 20; // whatever your value is
float columnCenter = ((float) columnMax) / 2 * invaderWidth;
for(var column = 0; column < columnMax ; column++)
{
float invaderX = (column * invaderWidth);
float distanceFromCenterHorizontal = invaderX - columnCenter;
for(var row = 0; row < rowMax; row ++)
{
Invader invader = new Invader(distanceFromCenterHorizontal);
invader.Position.Y = row * invaderHeight // Needs adjustment here!
}
}
}
void update()
{
if(center.X == screenWidth) moveLeft = true;
else if(center.X <= 0) moveLeft = false;
center.X += moveLeft? -step : step;
foreach(var invader in invaders) invader.UpdatePosition(center);
}
您希望移动“centerPoint”并根据新中心更新所有Invaders。
我不确定XNA是否使用double或float值,所以你可能需要调整它。
然后,您可以轻松扩展它以创建一些向上/向下摆动。
答案 2 :(得分:0)
所以我创造了一个名为'bounds'的新矩形,它与外星人一样宽,并且像外星人一样移动。并让它工作! (一半)。它向右移动直到它接触到右侧,然后它向左移动但继续向左移动并且从不向右移动。那么这次我哪里出错了?
if (xPos % step == 0)
{
if (!isDescending)
{
for (int k = 0; k < sprites.Count; k++)
{
Sprite sprite = sprites[k];
sprite.position.X += step;
}
if (bounds.Right == screenWidth || bounds.Left == 0)
{
touchedRight = !touchedRight;
step *= -1;
}
if (!touchedRight) bounds.X += step;
if (touchedRight) bounds.X -= step;
// for (int k = 0; k < sprites.Count; k++)
// {
// Sprite sprite = sprites[k];
// bool hitLeft = sprite.position.X == 0;
// bool hitRight = sprite.rect.Right == screenWidth;
// if ((hitLeft) || (hitRight))
// {
// touchedRight = !touchedRight;
// isDescending = true;
// }
// }
}