所以这是我的第一个XNA项目,即我是一个完整的菜鸟。我正在制作一个基本的太空入侵者游戏,但我不能为如何为入侵者制作矩形阵列做出头脑或尾巴;我目前所使用的代码只是在一条长线中绘制了它我看了其他答案,但到目前为止似乎都没有。
我初步确定了这个:
InvaderArray = new Invader[5, 11];
int XPos = 200;
for (int rows = 0; rows < 5; rows++)
for (int cols = 0; cols < 11; cols++)
{
InvaderArray[rows, cols] = new Invader();
InvaderArray[rows, cols].SetXPos(XPos);
InvaderArray[rows, cols].SetYPos(100);
XPos = XPos + 50;
}
这在Draw()方法中:
for (int rows = 0; rows < 5; rows++)
for (int cols = 0; cols < 11; cols++)
{
spriteBatch.Draw(Invader, InvaderArray[rows, cols].GetPos(), Color.White);
}
我正在使用&#39; Invader&#39;课程,如果有帮助:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace SpaceInvaders
{
class Invader
{
Vector2 InvaderPos;
public Invader()
{
InvaderPos = new Vector2();
InvaderPos.X = 0;
InvaderPos.Y = 0;
}
public void MoveHorizontal(int amount)
{
InvaderPos.X = InvaderPos.X + amount;
}
public void MoveVertical(int amount)
{
InvaderPos.Y = InvaderPos.Y + amount;
}
public void SetXPos(int pos)
{
InvaderPos.X = pos;
}
public int GetXPos()
{
return (int)InvaderPos.X;
}
public void SetYPos(int pos)
{
InvaderPos.Y = pos;
}
public int GetYPos()
{
return (int)InvaderPos.Y;
}
public Vector2 GetPos()
{
return InvaderPos;
}
}
}
非常感谢任何帮助。
答案 0 :(得分:5)
他们排在长队,因为这段代码
InvaderArray[rows, cols].SetYPos(100);
为每一个人提供相同的Y位置。也许把它设置为类似
InvaderArray[rows, cols].SetYPos(100 + row * 50);
此外,您需要在绘制每一行后将XPos重置为其初始值200。
for (int rows = 0; rows < 5; rows++)
{
XPos = 200;
for (int cols = 0; cols < 11; cols++)
答案 1 :(得分:1)
Eric J已经回答了您的代码中的具体错误,但我想首先解决为什么会出现这个问题。基本上你试图在2个循环中创建一个特定的几何体,有几种方法可以做到这一点。有几种方法可供选择,但无论采用何种方法,都必须小心遵循相同的逻辑。我将分享一些可能的方法。首先,我将使用您共享的方法,并为您缺少的一些关键部分添加注释:
int YPos = 100; // Set the initial Y position
for (int rows = 0; rows < 5; rows++)
{
int XPos = 200; // Set the initial X position at the beginning of each row
for (int cols = 0; cols < 11; cols++)
{
InvaderArray[rows, cols] = new Invader();
InvaderArray[rows, cols].SetXPos(XPos);
// Your code used 100 here so every invader had a Y position of 100:
InvaderArray[rows, cols].SetYPos(YPos);
XPos = XPos + 50;
}
YPos = YPos + 50; // Increment the Y position after each row
}
在此示例中,您将循环遍历行和列,并按X和Y保持运行位置。
另一个在数学上更复杂的选项是使用X和Y位置的方程,这个方程稍微简洁但由于乘法和加法需要更多的计算:
for (int rows = 0; rows < 5; rows++)
{
for (int cols = 0; cols < 11; cols++)
{
InvaderArray[rows, cols] = new Invader();
InvaderArray[rows, cols].SetXPos(200 + 50 * cols);
InvaderArray[rows, cols].SetYPos(100 + 50 * rows);
}
}
这里的一个优点是移动部件较少&#34;因为你不必拥有存储X和Y位置的变量,但是你必须进行数学处理,处理器也必须进行乘法,这种情况在这种情况下是次要的,但它确实有所作为。
如果用这样的通用列表替换2维入侵者数组:
List<Invader> InvaderList = new List<Invader()
您的循环可以这样写:
for (int y = 100; y <= 300; y += 50)
{
for (int X = 200; x <= 700; x += 50)
{
Invader invader = new Invader();
InvaderList.Add(invader);
invader.SetXPos(x);
invader.SetYPos(y);
}
}
然后在你的绘制方法中:
foreach (Invader invader in InvaderList)
{
spriteBatch.Draw(invader, invader.GetPos(), Color.White);
}
这很简洁,因为它只使用2个变量(x和y)。你必须事先做数学,但你做的很明显。没有额外的计算或额外的变量。另外一个好处是,通过使用通用列表,您的绘制方法也得到了简化。此外,如果您想要除了矩形之外还有其他船舶布置,您可以使用相同的方法绘制它们,因为您的绘制方法不再关心您拥有多少行或列的船只 - 它只会将每艘船在其给定位置绘制