Присвоение случайного изображения с помощью arc4random?
Вопрос
Хорошо, я попытаюсь сделать это более понятным, потому что мой последний вопрос был чрезвычайно запутанным.На этот раз я включил фотографию.Каждый из этих кругов является UIImageView, и каждому из них присваивается случайное изображение, которое является одним из 7 цветов.Таким образом, каждый круг может быть одного из 7 цветов.Я хочу сделать так, чтобы пользователь должен был нажимать на круги в заранее определенном порядке в соответствии с цветом.Например, синий, зеленый, желтый, розовый, фиолетовый, оранжевый, красный.Моя ОГРОМНАЯ проблема заключается в том, что я, кажется, не могу понять, как определить, попал ли цвет, который не должен быть выбран, или нет.Есть ли способ присвоить нескольким представлениям изображений одно и то же значение, а затем каким-то образом создать оператор if, который гласит....
if(a blue circle is hit && ANY ORANGE CIRCLE IS STILL IN VIEW){
do something
}
Единственный известный мне способ закодировать это - это безумное количество кода из-за того, что назначаются все случайные изображения.
bluebubble = [UIImage imageNamed:@"bluebubble.png"];
greenbubble = [UIImage imageNamed:@"greenbubble.png"];
redbubble = [UIImage imageNamed:@"redbubble.png"];
yellowbubble = [UIImage imageNamed:@"yellowbubble.png"];
orangebubble = [UIImage imageNamed:@"orangebubble.png"];
pinkbubble = [UIImage imageNamed:@"pinkbubble.png"];
purplebubble = [UIImage imageNamed:@"purplebubble.png"];
image1 = arc4random()%7;
if(image1 == 0){
[test setImage:bluebubble];
}
else if(image1 == 1){
[test setImage:greenbubble];
}
else if(image1 == 2){
[test setImage:redbubble];
}
else if(image1 == 3){
[test setImage:yellowbubble];
}
else if(image1 == 4){
[test setImage:orangebubble];
}
else if(image1 == 5){
[test setImage:pinkbubble];
}
else if(image1 == 6){
[test setImage:purplebubble];
}
image2 = arc4random()%7;
if(image2 == 0){
[test2 setImage:bluebubble];
}
else if(image2 == 1){
[test2 setImage:greenbubble];
}
else if(image2 == 2){
[test2 setImage:redbubble];
}
else if(image2 == 3){
[test2 setImage:yellowbubble];
}
else if(image2 == 4){
[test2 setImage:orangebubble];
}
else if(image2 == 5){
[test2 setImage:pinkbubble];
}
else if(image2 == 6){
[test2 setImage:purplebubble];
}
Решение
Я думаю, что также разумно создать более разумный способ присвоения изображений разного цвета вашим видам изображений, поэтому это решение выполняет и то, и другое.
Они должны быть объявлены в заголовке класса
NSArray *allCircleImagesViews; // These are suppose to be the onscreen UIImagesViews
NSArray *circlesByColor;
NSMutableArray *correctCircles; // The current circles the user is allowed to click
NSArray *colorOrder; // The order of the colors to click
int currentColorIndex; // The current index in the order of colors
Теперь перейдем к функциям:Первый создает назначение изображений разных цветов, устанавливает правильный порядок цветов и устанавливает механизм для определения, был ли выбран правильный цвет
- (void) populateImages
{
NSArray *images = [NSArray arrayWithObjects:
[UIImage imageNamed:@"bluebubble.png"],
[UIImage imageNamed:@"redbubble.png"],
[UIImage imageNamed:@"yellowbubble.png"],
[UIImage imageNamed:@"greenbubble.png"],
[UIImage imageNamed:@"orangebubble.png"],
[UIImage imageNamed:@"pinkbubble.png"],
[UIImage imageNamed:@"purplebubble.png"],
nil];
NSArray *circlesByColor=[NSArray arrayWithObjects:
[NSMutableArray array],
[NSMutableArray array],
[NSMutableArray array],
[NSMutableArray array],
[NSMutableArray array],
[NSMutableArray array],
[NSMutableArray array],
nil];
[circlesByColor retain];
// Assign images to circles and set the
for (UIImageView *currCircle in allCircleImagesViews)
{
int nextIndex = arc4random()%7;
currCircle.image = [images objectAtIndex:0];
[(NSMutableArray *)[circlesByColor objectAtIndex:nextIndex] addObject:currCircle];
}
// Set the correct order
NSArray *colorOrder = [NSArray arrayWithObjects:
[NSNumber numberWithInt:5], // Pink
[NSNumber numberWithInt:0], // Blue
[NSNumber numberWithInt:1], // etc.
[NSNumber numberWithInt:4],
[NSNumber numberWithInt:2],
[NSNumber numberWithInt:3],
[NSNumber numberWithInt:6],nil];
[colorOrder retain];
currentColorIndex = 0;
correctCircles = [circlesByColor objectAtIndex:[[colorOrder objectAtIndex:currentColorIndex] intValue]];
}
Следующая функция проверяет, был ли нажат правильный круг
- (void) checkCircle:(UIImageView *)clickedImageView
{
BOOL result;
if ([correctCircles containsObject:clickedImageView])
{
[correctCircles removeObject:clickedImageView];
result = YES;
}
else {
result = NO;
}
if ([correctCircles count] == 0)
{
currentColorIndex++;
if (currentColorIndex < 7)
correctCircles = [circlesByColor objectAtIndex:[[colorOrder objectAtIndex:currentColorIndex] intValue]];
else
correctCircles = nil;
}
if (!result)
{
// Wrong circle clicked logic
}
else {
if (!correctCircles)
{
// Game won logic
}
else {
// Correct circle clicked logic
}
}
}
Другие советы
Да, вы можете установить image
свойство UIImageView для того же UIImage.На самом деле, вы уже делаете это!
В imageNamed:
метод класса вернет ссылку на тот же объект при повторном вызове с тем же именем файла изображения.
Однако вы должны получить четыре ссылки на UIImage один раз, а затем использовать их.Вам также следует использовать массив и цикл или, по крайней мере, функцию, чтобы сделать этот код короче и проще.
На самом деле, похоже, вы захотите, чтобы ваши четыре ссылки на UIImage были переменными экземпляра, чтобы вы могли сравнивать image
свойство объектов UIImageView, сопоставленных с ними позже.
Если ваша цель - просто предложение if, то то, что я бы сделал, это определить два словаря с ключом в качестве цвета и значениями в виде массивов фрагментов, значение которых является местоположением фрагмента.
NSDictionary *hitDictionaryOfBurbles;
NSDictionary *notCurrentlyBeingHitDictionaryOfBurbles;
С определением этого словаря у вас есть все предметы всех цветов, которые в данный момент не подвергаются удару.Затем вы можете легко проверить по этому словарю значение массива оранжевого цвета, чтобы увидеть, сколько в нем элементов.
Конечно, как только вы нажмете на кнопку burble, вы должны изменить значение этих двух словарей, чтобы отразить изменение.
Es.
hitDictioanryOfBurbles:
"blue", [0,7,13]
"green", [2,6,16]
etc...
notCurrentlyBeingHitDictioanryOfBurbles:
"blue", [25,33,37]
"green", [19,27,29]
etc...
Если у вас есть другая логика для поддержки, то вам следует определить больше структур данных.
Вы всегда собираетесь использовать их в определенном порядке, один за другим, где одновременно допустим только один цвет?Если это так, вы можете создать стек UIImage
s (Я не думаю, что существует встроенный тип данных стека, но вы можете легко смоделировать его с помощью NSMutableArray
), состоящий из цветов по порядку.
Вы также отслеживаете все подвиды цветовых кругов на экране в отдельном NSMutableArray
.Затем, всякий раз, когда пользователь попадает в круг, выполните следующий код:
if(hitImageView.image == [imageStack peek]) {
//"hit the right one" logic
//you hit it, so remove it from the screen
[allImageViews removeObject:hitImageView];
[hitImageView removeFromSuperView];
//if it was the last imageview of the "correct" color...
BOOL wasLast = YES;
for(UIImageView *imageView in allImageViews) {
if(imageView.image == [imageStack peek]) {
wasLast = NO;
break;
}
}
//...then set the correct color to whatever is next
if(wasLast)
[imageStack pop];
if(![imageStack hasItems])
;//"won the game" logic
}
else {
//"hit the wrong one" logic
}
(Это O (N) для определения оставшихся кругов, но если вы имеете дело с таким маленьким набором, то это действительно не имеет значения.Если бы вам нужно было его оптимизировать, вы, конечно, могли бы отслеживать оставшееся количество каждого цвета.)
С другой стороны, вы будете намного счастливее, если вместо того, чтобы использовать этот гигантский if-else
блок, чтобы определить правильный цвет, вы просто называете файлы color1.png
, color2.png
, и т.д.и сказать [UIImage imageNamed:[NSString stringWithFormat:@"color%i.png", randNum]];