c# - 将 GameObjects 分配给列表并给它们一个索引
问题描述
所以基本上,我有一个每个数字有 2 个的列表,我想将其中一个数字随机分配给每张实例化的卡片。这是一个益智记忆游戏,您可以在其中找到匹配项。
当我有 2 个 gridRows 和 4 个 gridCols 时,游戏运行良好,但如果我更改行数或列数,我会得到:ArgumentOutOfRangeException:索引超出范围。必须是非负数且小于集合的大小。参数名:index,阻止我扩展游戏。我尝试在当前列表中添加其他数字,但这似乎不起作用,而且如果我想要有很多行和列,这种方式似乎也不是很有效
我想要做的是获取一个列表,然后在每次开始比赛时对其内容进行洗牌,然后在我实例化时按顺序循环索引(内容已经洗牌),这是我的逻辑,但无法让它工作一些原因....
有人可以帮我扩展它并找到存储索引的更好方法吗?
这是代码:
public const int gridRows = 2;
public const int gridCols = 4;
public const float offsetX = 4f;
public const float offsetY = 5f;
public MainCard originalCard;
public Sprite[] images;
private void Start()
{
Vector3 startPos = originalCard.transform.position;
List<int> numbers = new List<int> { 0, 0, 1, 1, 2, 2, 3, 3 };
numbers = Shuffle(numbers);
for (int i = 0; i < gridCols; i++)
{
for (int x = 0; x < gridRows; x++)
{
MainCard card;
if (i == 0 && x == 0)
{
card = originalCard;
}
else
{
card = Instantiate(originalCard) as MainCard;
}
int index = x * gridCols + i;
int id = numbers[index];
card.ChangeSprite(id, images[id]);
float posX = (offsetX * i) + startPos.x;
float posY = (offsetX * x) + startPos.y;
card.transform.position = new Vector3(posX, posY, startPos.z);
}
}
List<T> Shuffle<T>(List<T> cards)
{
for (int i = 0; i < cards.Count; i++)
{
T temp = cards[i];
int randomIndex = Random.Range(i, cards.Count);
cards[i] = cards[randomIndex];
cards[randomIndex] = temp;
}
return cards;
}
}
}
解决方案
一种解决方案是将您的项目分成更多部分:
using System.Linq;//to Add
public int gridRows = 2;
public int gridCols = 4;
public List<int> numbers;
public void Start()
{
int[,] cards = new int[gridRows, gridCols];
//just put different numbers not needed to duplicate
//except if you want to increase the probability
// to have lot of same number
numbers = new List<int> { 0, 1, 2, 3 };
InitializeGame(cards);
}
private void InitializeGame(int[,] cards)
{
//1 you could shuffle your number if you want
//numbers = Shuffle(numbers);
//2 you initialize cards to value not used (-1 here)
for (int r = 0; r < gridRows; r++)
{
for (int c = 0; c < gridCols; c++)
{
cards[r, c] = -1;
}
}
// Test if you have filled up all cards
//Is there again one card with the value -1?
while (cards.Cast<int>().Any(x => x == -1))
{
//3 you pick randomnly a number
var numCard = numbers[Random.Range(0, numbers.Count)];
//4 you fill same number to 2 different cards here
var nbcardTofill = 2;
while (nbcardTofill != 0)
{
//you choose randomny card (row and col) which is free (value = -1) not need but add fun
var colRandom = Random.Range(0, gridCols);
var rowRandom = Random.Range(0, gridRows);
if(cards[rowRandom, colRandom] == -1)
{
nbcardTofill--;
cards[rowRandom, colRandom] = numCard;
}
}
}
}
现在你有了填满数字的阵列卡,你现在可以抽奖了..
因此您可以根据需要更改列数/行数和数字列表...
只是一种编程方式,但我认为它更具可读性。我添加了很多随机化来增加乐趣......
另一种方法是按顺序填写您的卡片(2 x 2 相同的数字)并在最后对所有卡片进行洗牌......
推荐阅读
- angular - Observable 查找嵌套属性
- apache-storm - 是否有特殊原因将pendingEmits 队列限制为1024 个元素
- javascript - Bootstrap Modal + Carousel Gallery 未显示图像
- oop - 用于在错误时释放资源的 goto 链的 OOP 等效项?
- linux - In Bash, is there a way to expand variables twice in double quotes?
- c++ - 如何抽象模板函数中使用的simd代码
- swift - 如何在 Xcode 9 中将键盘类型数字键盘限制为仅限英文数字
- apache-kafka - 如何部署 Yolean Kubernetes Kafka?
- gradle - AnnotationProcessor 和依赖项
- ios - 表达式太复杂,无法在合理的时间内解决(xcode)