0

私は簡単なパズルゲームを作成し、これに次に使用します:

私はPieceという名前のクラスを持っています。ピースクラスは次のフィールドを継承しUIImageView、次のフィールドを含みます。

@property(nonatomic, strong) NSString *pieceName;
@property(nonatomic) CGFloat pos_x;
@property(nonatomic) CGFloat pos_y;
@property(nonatomic) BOOL snapped;

私のゲームでは、各ピースに色(赤、緑、青など)があります。各ピースの形状は不規則です。アルファカラーの画像です。アルファカラーをタップすると、このピースを選択する必要はありません。

このために私は次の方法を使用します:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{   

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    NSArray *views = [self.view subviews];

    for (UIView *v in views) {
        if([v isKindOfClass:[Piece class]]){
            if (CGRectContainsPoint(v.frame, touchLocation) && ((Piece *)v).snapped == FALSE) { 

                UITouch* touchInPiece = [touches anyObject]; 
                CGPoint point = [touchInPiece locationInView:(Piece *)v];
                BOOL solidColor = [self verifyAlphaPixelImage:(Piece *)v atX:point.x * resolution atY:point.y * resolution];

                if (solidColor) {                

                    NSArray *tempViews = [self.view subviews];
                    [tempViews reverseObjectEnumerator];

                    for (UIView *tv in tempViews) {
                        if (tv == v) {
                            [tv setExclusiveTouch:YES];
                            dragging = YES;
                            oldX = touchLocation.x;
                            oldY = touchLocation.y;
                            piece = (Piece *)v;
                            [self.view bringSubviewToFront:piece];
                            break;
                        }
                    }

               }

            }
        }
    }
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    if (dragging) {        
        CGRect frame = piece.frame;
        frame.origin.x = piece.frame.origin.x + touchLocation.x - oldX;
        frame.origin.y =  piece.frame.origin.y + touchLocation.y - oldY;
        if ([self verifyOutOfScopeCoordX:touchLocation.x CoordY:touchLocation.y]) {
            piece.frame = frame;
        }               
        [self snapPiece];
    }

    oldX = touchLocation.x;
    oldY = touchLocation.y;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{    
    dragging = NO;
}

- (BOOL)verifyAlphaPixelImage:(Piece *)image atX:(int)x atY:(int)y{

    CGImageRef imageRef = [image.image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    int byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

    CGFloat red   = (rawData[byteIndex]     * 1.0) / 255.0;
    CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
    CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0;
    CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
    /*
    NSLog(@"red:   %f", red);
    NSLog(@"green: %f", green);
    NSLog(@"blue:  %f", blue);
    NSLog(@"alpha:   %f", alpha);
    */    
    free(rawData);    
    if(alpha==0 && red == 0 && green == 0 && blue == 0) return NO;
    else return YES;

}

私は問題なく作品を動かします。verifyAlphaPixelImageしかし、この行のメソッドで奇妙なエラーが発生することがありCGFloat red = (rawData[byteIndex] * 1.0) / 255.0;ますEXC_BAD_ACCESS

verifyAlphaPixelImage-アルファピクセルを分析するためにこのメソッドが必要です。アルファピクセルをタップすると、このピースを選択する必要はありません。

ここでの主な問題は、EXC_BAD_ACCESSrawDataを使用するオンラインです。

今私はこれを使用します:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.view];

    NSArray *views = [self.view subviews];

    for (UIView *v in views) {
        if([v isKindOfClass:[Piece class]]){

            CGFloat pos_x = touchLocation.x - v.frame.origin.x;
            CGFloat pos_y = touchLocation.y - v.frame.origin.y;         

            if (CGRectContainsPoint(v.frame, touchLocation) && ((Piece *)v).snapped == FALSE) { 


                BOOL solidColor = [self verifyAlphaPixelImage:(Piece *)v atX:pos_x * resolution atY:pos_y * resolution];

                if (solidColor) {                

                    NSArray *tempViews = [self.view subviews];
                    [tempViews reverseObjectEnumerator];

                    for (UIView *tv in tempViews) {
                        if (tv == v) {
                            [tv setExclusiveTouch:YES];
                            dragging = YES;
                            oldX = touchLocation.x;
                            oldY = touchLocation.y;
                            piece = (Piece *)v;
                            [self.view bringSubviewToFront:piece];
                            break;
                        }
                    }

                }

            }
        }
    }
}

そしてこの作品...

4

1 に答える 1

1

最初のアプローチでは、同じ目的で2つの異なるタッチを使用していることに注意してください。

最初に行う:

UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];

タッチがピースビュー内にあるかどうかを確認します。

しかし、あなたは次のように別のタッチを取ります:

UITouch* touchInPiece = [touches anyObject]; 
CGPoint point = [touchInPiece locationInView:(Piece *)v];

複数のタッチイベントがある場合、2番目のタッチは最初のタッチではなく、最初のタッチが検出されたビューの内側にさえない可能性があります。2番目のタッチは、最初のタッチによって検出されたピースビューの範囲外である可能性があります。

于 2012-05-28T13:29:40.223 に答える