-2

ジグソーアプリケーションを作成しています。各ピースに触れると、正しい場所に配置され、間違った場所にドロップされた場合にブール(droppedInPlace)が割り当てられるという考え方です。次に、40個のブール(ジグソーピースの数)の配列を作成する必要があると思います。これらの各エントリは、最初はNOに設定されます。YESNO

次に、このブール値(droppedInPlace)は、を使用して配列に挿入されreplaceObjectAtIndexます。次に、この配列をループします。すべてのエントリがtrue/yes / 1の場合、ジグソーパズルは完了し、いくつかのコードを実行します。

これを行うのに問題があります。上記のアイデアをコーディングする方法がわかりません。以下は私のコードです:

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
UIView *touchedView = [touch view];
// filename to be read from
NSString *filePath = [[NSBundle mainBundle]
                      pathForResource: 
                      @"jigsawHomeCenterPoints" 
                      ofType:@"plist"];
// array of cgpoints in string format
NSArray *jigsawHomeCentersArray = [NSArray arrayWithContentsOfFile:filePath];
// the tag number of the selected image
int tag = touchedView.tag;
NSLog(@"tag: %i", tag);
// says that the piece has not been dropped in it's holder
bool droppedInPlace = NO;
// if what has been touched is part of the array of images
if ([imagesJigsawPieces indexOfObject:touchedView] != NSNotFound) {
    // preparing new snap-to-center position
    // using (tag-1) as an index in the HomeCentersArray corresponds to where the image should be placed
    // this was a conscious decision to make the process easier
    CGPoint newcenter = CGPointFromString([jigsawHomeCentersArray objectAtIndex:tag-1]);
    // the location of the current touch
    CGPoint location = [touch locationInView:self.view];
    // call the animate method upon release
    [self animateReleaseTouch:touchedView withLocation:location];
    // setting a proximity range - if it is within this 80x80 area the image will snap to it's corresponding holder (HomeCenter)
    if (location.x > newcenter.x-40 && location.x < newcenter.x+40 
        && location.y > newcenter.y-40 && location.y < newcenter.y+40) {
        touchedView.center = newcenter;
        touchedView.alpha = 1.0;
        droppedInPlace = YES;
    } else {
        touchedView.alpha = 0.5;
        droppedInPlace = NO;
    }
    NSLog(@"True or false: %i", droppedInPlace);
[self checkJigsawCompleted:droppedInPlace withTag:tag];
}
}

そしてチェック機能:

-(void) checkJigsawCompleted:(BOOL)inPlace withTag:(NSInteger)tag {
NSMutableArray *piecesInPlace;
[piecesInPlace replaceObjectAtIndex:tag-1 withObject:[NSNumber numberWithBool:inPlace]];
//code to loop through array - check if all entries are true/yes/1
//if so, jigsaw is completed - run some other code
//else, do nothing
}
4

3 に答える 3

2

piecesInPlace配列はメソッドcheckJigsawCompletedで初期化されておらず、次の行でクラッシュすることに注意してください。

正しい値で初期化されているとすると、すべての値が真であるかどうかを確認する方法は簡単です。

for (NSNumber *boolNumber in piecesInPlace) {
    if (![boolNumber boolValue])
       return false;
}

return true;

編集:またはもっと良い:

return ![piecesInPlace containsObject:[NSNumber numberWithBool:NO]];
于 2012-04-04T10:57:57.640 に答える
1

配列をループする方法を知りたいですか?for(;;)ループまたはループを使用できます。for(.. in ..)または、この種のものに私のお気に入りは次の とおりです。 -enumerateObjectsUsingBlock:

__block jigsawIsComplete = true;
[piecesInPlace enumerateObjectsUsingBlock: ^(id obj, NSUInteger i, BOOL* stop)
    {
        jigsawIsComplete = jigSawIsComplete && [obj boolValue];
        *stop = !jigsawIsComplete;
    }];
于 2012-04-04T10:59:04.060 に答える
1

だから、いくつかのこと。まず、パズルのピースのタグに基づいて、このpiecesInPlace可変配列内のオブジェクトを置き換えているようです。ただし、これらのビューのタグを設定することはありません。したがって、この行:

int tag = touchedView.tag;

さらに悪いことに、replaceObjectAtIndex:tag-1ビットは、(現時点では、ただしAppleがいくつかの変更を公開すると)合法ではない配列の-1インデックスにアクセスしようとします。

配列をループして真の値をチェックする限り、このメソッドを使用することをお勧めします

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

これを使用すると、配列でNO値が見つかったら、停止ポインターをYESに設定するだけで、列挙が終了します。停止がNOである限り、列挙を続行する必要があります。停止せずに配列を通過すると、すべての値がYESになります。

于 2012-04-04T11:03:50.740 に答える