5x28のマスを空間に見立てて、H型の何かを落とすようなロジックとか作ってみようと思い、リボン落としiPhoneアプリを描いてみました。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
#define MaxRow 5
#define MaxCol 28
@interface ViewController ()
@property (strong, nonatomic) NSMutableArray *box;
@property (strong, nonatomic) UIColor *color;
@property (strong, nonatomic) NSTimer *timer;
@property (nonatomic) int counter;
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.color = [UIColor greenColor];
[self createNewBlock];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self startTimer];
}
– (void)startTimer
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}
– (void)tick:(NSTimer*)sender
{
[self updateBox];
[self updateRibbon];
}
– (void)updateBox
{
BOOL stop = NO;
NSMutableArray *current = [[NSMutableArray alloc] init];
for (int col=0; col<MaxCol; col++) {
for (int row=0; row<MaxRow; row++) {
if ([self.box[col][row] intValue] == 1) {
//get current
[current addObject:@[@(col),@(row)]];
// check next
if ([self.box[col + 1][row] intValue] == 3 || col == MaxCol – 2) {
stop = YES;
}
}
// change 3
if ([self.box[col][row] intValue] == 2) {
self.box[col][row] = @(3);
}
}
}
// update box
for (NSArray *d in current) {
int col = [d[0] intValue];
int row = [d[1] intValue];
if (stop) {
self.box[col][row] = @(2);
} else {
self.box[col][row] = @(0);
}
}
// down
if (!stop) {
for (NSArray *d in current) {
int col = [d[0] intValue] + 1;
int row = [d[1] intValue];
self.box[col][row] = @(1);
}
}
}
– (void)updateRibbon
{
// clean
for (UIView *v in self.view.subviews) {
if (v.tag != 2) {
[v removeFromSuperview];
}
}
CGPoint p[7];
int i = 0; // counter for ribbon block
BOOL stop = NO;
for (int col=0; col<MaxCol; col++) {
for (int row=0; row<MaxRow; row++) {
NSNumber *val = self.box[col][row];
int x = row * 50 + 10;
int y = col * 20;
if ([val intValue] == 1 || [val intValue] == 2) { // 1 or 2
p[i] = CGPointMake(x, y);
i++; // counter for ribbon block
}
if ([val intValue] == 2) {
stop = YES;
}
}
}
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(p[0].x, p[0].y – 10)];
[path addLineToPoint:CGPointMake(p[5].x, p[5].y + 10)];
[path addLineToPoint:p[3]];
[path closePath];
[path addLineToPoint:p[3]];
[path addLineToPoint:CGPointMake(p[1].x, p[1].y – 10)];
[path addLineToPoint:CGPointMake(p[6].x, p[6].y + 10)];
[path closePath];
CAShapeLayer *sl = [CAShapeLayer layer];
sl.fillColor = self.color.CGColor;
sl.path = path.CGPath;
// create new
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 500)];
if (stop) {
view.tag = 2;
[self createNewBlock];
self.color = [UIColor colorWithHue:(arc4random() % 10) / 10.0 saturation:1 brightness:1 alpha:1];
self.counter++;
if (self.counter > 10) {
[self.timer invalidate];
}
}
[view.layer addSublayer:sl];
[self.view addSubview:view];
}
– (NSMutableArray *)box
{
if (!_box) {
_box = [[NSMutableArray alloc] init];
for (int col=0; col<MaxCol; col++) {
[_box addObject:[[NSMutableArray alloc] init]];
for (int row=0; row<MaxRow; row++) {
_box[col][row] = @(0);
}
}
}
return _box;
}
– (void)createNewBlock
{
int move = arc4random() % 3;
self.box[0][2 + move] = @(1);
self.box[1][2 + move] = @(1);
self.box[2][2 + move] = @(1);
self.box[0][0 + move] = @(1);
self.box[1][0 + move] = @(1);
self.box[2][0 + move] = @(1);
self.box[1][1 + move] = @(1);
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end