画面に6面あるキューブの1面だけを表示したパズルのサンプルです。
他の面は、見えません、
想像力を駆使し、ゆびでパネルをうごかして、
同じ色になるように頑張ってみようというサンプルゲーム
をつくってみました。

ポイント
キューブの展開図を画面上に配置して、一面と下ちょっとだけが
端末の画面に表示されるようにしています。
パネルの移動は、UIPanGestureRecognizerで制御。
タッチして最初にゆびを動かした方向にパネルの動きをロックすることで、
縦、横の動きを固定してみました。
ゆびを動かす方向は pan gesture の velocityInViewから取得しています。

環境
今回つくったiPhoneゲームのサンプルコードは、
XcodeのiOS6 iPhone Simulatorで動かしています。


サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    [self createPuzzle];

    

    [self cover];

    

    [self shuffle];

}

– (void)createPuzzle

{

    float w = self.view.bounds.size.width / 3.0;

    for (int i=0; i<54; i++) {

        UIView *panel = [[UIView alloc] init];

        panel.tag = i + 1;

        if (i < 9) {

            float x = (i % 3) * w;

            float y = (i / 3) * w – w * 3;

            panel.frame = CGRectMake(x, y, w, w);

        } else if (i < 18) {

            float x = ((i-9) % 3) * w;

            float y = ((i-9) / 3) * w;

            panel.frame = CGRectMake(x, y, w, w);

        } else if (i < 27) {

            float x = ((i-18) % 3) * w;

            float y = ((i-18) / 3) * w + w * 3;

            panel.frame = CGRectMake(x, y, w, w);

        } else if (i < 36) {

            float x = ((i-27) % 3) * w – w * 3;

            float y = ((i-27) / 3) * w;

            panel.frame = CGRectMake(x, y, w, w);

        } else if (i < 45) {

            float x = ((i-36) % 3) * w – w * 6;

            float y = ((i-36) / 3) * w;

            panel.frame = CGRectMake(x, y, w, w);

        } else {

            float x = ((i-45) % 3) * w – w * 9;

            float y = ((i-45) / 3) * w;

            panel.frame = CGRectMake(x, y, w, w);

        }

        float colorNo = i / 9 * 0.1;

        UIColor *color = [UIColor colorWithHue:colorNo saturation:1 brightness:1 alpha:1];

        panel.backgroundColor = color;

        [self.view addSubview:panel];

        panel.layer.borderWidth = 1.0;

        panel.layer.borderColor = [UIColor whiteColor].CGColor;

        

        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

        [panel addGestureRecognizer:pan];

    }

}

– (void)pan:(UIPanGestureRecognizer*)gr

{

    CGPoint p = [gr locationInView:self.view];

    float w = self.view.bounds.size.width/3.0;

    

    // direction check

    static BOOL vertical;

    static CGRect origin;

    if (gr.state == UIGestureRecognizerStateBegan) {

        origin = gr.view.frame;

        vertical = fabs([gr velocityInView:self.view].x) < fabs([gr velocityInView:self.view].y);

    } else if (gr.state == UIGestureRecognizerStateEnded){

        [UIView animateWithDuration:0.1 animations:^{

            for (UIView *v in self.view.subviews) {

                if (v.tag == 100) {

                    continue;

                }

                float x = floor(v.center.x / w) * w + w/2.0;

                float y = floor(v.center.y / w) * w + w/2.0;

                v.center = CGPointMake(x, y);

            }

        }];

    } else {

        if (vertical) {

                [self moveVertical:gr.view length:gr.view.center.y – p.y];

            } else {

                // 横方向に動かす

                [self moveHorizontal:gr.view length:gr.view.center.x – p.x];

            }

    }

}

– (void)moveVertical:(UIView *)view length:(float)diff

{

    float w = self.view.bounds.size.width/3.0;

    // 縦方向に動かす

    for (UIView *v in self.view.subviews) {

        if (v.center.x == view.center.x && v.tag < 100) {

            float y = v.center.y – diff;

            if (y > w * 8.5) {

                y -= w * 9;

            } else if (y < – w) {

                y += w * 9;

            }

            v.center = CGPointMake(v.center.x, y);

        }

    }

}

– (void)moveHorizontal:(UIView *)view length:(float)diff

{

    float w = self.view.bounds.size.width/3.0;

    // 横方向に動かす

    for (UIView *v in self.view.subviews) {

        if (v.center.y == view.center.y && v.tag < 100) {

            float x = v.center.x – diff;

            if (x > w * 11.5) {

                x -= w * 12;

            } else if (x < – w) {

                x += w * 12;

            }

            v.center = CGPointMake(x, v.center.y);

        }

    }

}

– (void)shuffle

{

    float w = self.view.bounds.size.width/3.0;

    // 9 ~ 17

    for (int i=0; i<100; i++) {

        int num = arc4random() % 54 + 1;

        UIView *target = [self.view viewWithTag:num];

        if (CGRectContainsRect(CGRectMake(0, 0, 320, 320), target.frame)) {

            [self moveVertical:target length:w];

        }

    }

}

– (void)cover

{

    UIView *cover = [[UIView alloc] initWithFrame:CGRectMake(0, 320, 320, 200)];

    cover.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.8];

    cover.tag = 100;

    

    UILabel *label = [[UILabel alloc] init];

    label.text = @”puzzle”;

    label.font = [UIFont fontWithName:@”Chalkduster” size:50];

    label.textColor = [UIColor whiteColor];

    [label sizeToFit];

    label.center = CGPointMake(160, 80);

    label.backgroundColor = [UIColor clearColor];

    [cover addSubview:label];

    

    [self.view addSubview:cover];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end