川わたりパズルっぽい動きをするiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@interface ViewController ()
@property (nonatomic, weak) UIView *boat;
@property (nonatomic, strong) NSMutableArray *people;
@end
#define MyColor [UIColor colorWithRed:107.0/255.0 green:186.0/255.0 blue:255.0/255.0 alpha:1.0]
@implementation ViewController
– (void)viewDidAppear:(BOOL)animated
{
self.view.backgroundColor = MyColor;
[self createRiver];
[self createBank];
[self createPeople];
[self createBoat];
[self createMoveButton];
}
– (void)createRiver
{
UIBezierPath *wave = [UIBezierPath bezierPath];
float r = 10;
for (int i=0; i<30; i++) {
CGPoint o = CGPointMake(i * r * 2, 270);
[wave appendPath:[UIBezierPath bezierPathWithArcCenter:o radius:r startAngle:0 endAngle:M_PI clockwise:i%2]];
}
CAShapeLayer *waveLayer = [CAShapeLayer layer];
waveLayer.path = wave.CGPath;
waveLayer.fillColor = [UIColor clearColor].CGColor;
waveLayer.strokeColor = [UIColor whiteColor].CGColor;
waveLayer.lineWidth = 2;
[self.view.layer addSublayer:waveLayer];
}
– (void)createBank
{
for (int i=0; i<2; i++) {
UIView *bank = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 80)];
bank.backgroundColor = [UIColor whiteColor];
bank.center = CGPointMake(i == 0 ? 30 : i * CGRectGetMaxX(self.view.bounds) – 30, CGRectGetMaxY(self.view.bounds) – 30);
bank.layer.cornerRadius = 10;
[self.view addSubview:bank];
}
}
– (void)createPeople
{
self.people = [NSMutableArray array];
for (int i=0; i<3; i++) {
float w = (i==0) ? 20 : 10;
UIView *p = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, w * 2.0)];
p.tag = (i==0) ? 2 : 1;
p.backgroundColor = [UIColor whiteColor];
p.center = CGPointMake(i * 30 + CGRectGetMaxX(self.view.bounds) – 80, 220);
[self.view addSubview:p];
UIView *h = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1.7 * w, 1.7 * w)];
h.layer.cornerRadius = 1.7 * w / 2.0;
h.center = CGPointMake(w/2.0, -w * 0.9);
h.backgroundColor = [UIColor whiteColor];
[p addSubview:h];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[p addGestureRecognizer:tap];
[self.people addObject:p];
}
}
– (void)createBoat
{
UIView *boat = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 10)];
boat.center = CGPointMake(350, 250);
boat.backgroundColor = [UIColor whiteColor];
boat.layer.cornerRadius = 5;
[self.view addSubview:boat];
self.boat = boat;
}
– (void)createMoveButton
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@”move” forState:UIControlStateNormal];
[btn sizeToFit];
btn.center = CGPointMake(CGRectGetMidX(self.view.bounds), 290);
[self.view addSubview:btn];
[btn addTarget:self action:@selector(move) forControlEvents:UIControlEventTouchUpInside];
}
– (void)tap:(UITapGestureRecognizer *)gr
{
// check
int onBoat = 0;
NSMutableArray *arr = [NSMutableArray array];
for (UIView *p in self.people) {
if (CGRectContainsPoint(self.boat.frame, CGPointMake(p.center.x, self.boat.center.y))) {
onBoat += p.tag;
[arr addObject:p];
}
}
onBoat += gr.view.tag;
[arr addObject:gr.view];
CGPoint origin = gr.view.center;
[UIView animateWithDuration:0.5 animations:^{
gr.view.center = CGPointMake(self.boat.center.x, 200);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
if (onBoat < 3) {
gr.view.center = CGPointMake(self.boat.center.x + (arr.count – 1) * 20, 230);
} else {
gr.view.center = origin;
}
}];
}];
}
– (void)move
{
NSMutableArray *arr = [NSMutableArray array];
for (UIView *p in self.people) {
if (CGRectContainsPoint(self.boat.frame, CGPointMake(p.center.x, self.boat.center.y))) {
[arr addObject:p];
}
}
if (arr.count == 0) {
return;
}
BOOL right = self.boat.center.x > 250;
[UIView animateWithDuration:2.0 animations:^{
self.boat.center = CGPointMake(right ? 120 : 350, self.boat.center.y);
[arr enumerateObjectsUsingBlock:^(UIView *p, NSUInteger idx, BOOL *stop) {
p.center = CGPointMake(p.center.x + (right ? – 230 : 230), p.center.y);
}];
} completion:^(BOOL finished) {
[arr enumerateObjectsUsingBlock:^(UIView *p, NSUInteger idx, BOOL *stop) {
float d = [self.people indexOfObject:p] * 20 + 50;
p.center = CGPointMake(self.boat.center.x + (right ? – d : d), p.center.y);
}];
}];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end