縦横の長さを変えられる箱を表示するiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface ViewController () <SKSceneDelegate>
@property (nonatomic, weak) SKScene *scene;
@property (nonatomic, weak) SKNode *selected;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createFlexBox];
[self createBall];
}
– (void)setupScene {
SKView *sv = [[SKView alloc] initWithFrame:self.view.bounds];
SKScene *s = [SKScene sceneWithSize:sv.bounds.size];
s.delegate = self;
s.physicsWorld.gravity = CGVectorMake(0, 0);
s.backgroundColor = [UIColor blackColor];
[sv presentScene:s];
[self.view addSubview:sv];
self.scene = s;
}
#define dw CGRectGetMaxX(self.view.bounds) * 0.3
#define dh CGRectGetMaxY(self.view.bounds) * 0.3
#define top [self.scene childNodeWithName:@“t”]
#define bottom [self.scene childNodeWithName:@“b”]
#define right [self.scene childNodeWithName:@“r”]
#define left [self.scene childNodeWithName:@“l”]
#define dottop [self.scene childNodeWithName:@“dot t”]
#define dotbottom [self.scene childNodeWithName:@“dot b”]
#define dotright [self.scene childNodeWithName:@“dot r”]
#define dotleft [self.scene childNodeWithName:@“dot l”]
– (void)createFlexBox {
CGPoint o = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
for (int i=0; i<4; i++) {
SKShapeNode *dot = [SKShapeNode shapeNodeWithCircleOfRadius:8];
dot.name = [NSString stringWithFormat:@”dot %@”, @[@”t”, @”b”, @”r”, @”l”][i]];
dot.fillColor = [UIColor whiteColor];
dot.position = (CGPoint[]){
CGPointMake(o.x, o.y + dh),
CGPointMake(o.x, o.y – dh),
CGPointMake(o.x + dw, o.y),
CGPointMake(o.x – dw, o.y)
}[i];
dot.zPosition = 2;
[self.scene addChild:dot];
}
for (int i=0; i<4; i++) {
SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:
(CGSize[]){CGSizeMake(2.0 * dw, 10), CGSizeMake(10, 2.0 * dh)}[i / 2]];
bar.position = (CGPoint[]){
CGPointMake(o.x, o.y + dh),
CGPointMake(o.x, o.y – dh),
CGPointMake(o.x + dw, o.y),
CGPointMake(o.x – dw, o.y),
}[i];
bar.zPosition = 1;
bar.name = @[@”t”, @”b”, @”r”, @”l”][i];
bar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bar.size];
bar.physicsBody.dynamic = YES;
bar.physicsBody.restitution = 1.0;
bar.physicsBody.friction = 0;
bar.physicsBody.categoryBitMask = 0x1 << 1;
bar.physicsBody.collisionBitMask = 0x1;
bar.physicsBody.allowsRotation = NO;
[self.scene addChild:bar];
}
}
– (void)createBall {
SKShapeNode *ball = [SKShapeNode shapeNodeWithCircleOfRadius:10];
ball.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
ball.physicsBody.dynamic = YES;
ball.physicsBody.friction = 0;
ball.physicsBody.restitution = 0;
[self.scene addChild:ball];
[ball.physicsBody applyImpulse:CGVectorMake(1, 1)];
}
– (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene
{
float dtop = top.position.y – dottop.position.y;
if(abs(dtop) > 0.1) {
top.physicsBody.velocity = CGVectorMake(0, -(dtop / abs(dtop)) * sqrt(abs(dtop)) * 100.0);
} else {
top.physicsBody.velocity = CGVectorMake(0, 0);
}
float dbottom = bottom.position.y – dotbottom.position.y;
if(abs(dbottom) > 0.1) {
bottom.physicsBody.velocity = CGVectorMake(0, -(dbottom / abs(dbottom)) * sqrt(abs(dbottom)) * 100.0);
} else {
bottom.physicsBody.velocity = CGVectorMake(0, 0);
}
float dright = right.position.x – dotright.position.x;
if(abs(dright) > 0.1) {
right.physicsBody.velocity = CGVectorMake(-(dright / abs(dright)) * sqrt(abs(dright)) * 100.0, 0);
} else {
right.physicsBody.velocity = CGVectorMake(0, 0);
}
float dleft = left.position.x – dotleft.position.x;
if(abs(dleft) > 0.1) {
left.physicsBody.velocity = CGVectorMake(-(dleft / abs(dleft)) * sqrt(abs(dleft)) * 100.0, 0);
} else {
left.physicsBody.velocity = CGVectorMake(0, 0);
}
top.xScale = (right.position.x – left.position.x) / (2.0 * dw);
bottom.xScale = top.xScale;
right.yScale = (top.position.y – bottom.position.y) / (2.0 * dh);
left.yScale = right.yScale;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self.scene];
SKNode *hit = [self.scene nodeAtPoint:p];
if ([hit.name hasPrefix:@”dot”]) {
self.selected = hit;
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.selected) {
CGPoint p = [[touches anyObject] locationInNode:self.scene];
CGPoint o = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
SKNode *pair = self.selected == dottop ? dotbottom
: self.selected == dotbottom ? dottop
: self.selected == dotright ? dotleft
: dotright;
if (self.selected == dottop || self.selected == dotbottom) {
self.selected.position = CGPointMake(self.selected.position.x, p.y);
pair.position = CGPointMake(self.selected.position.x, o.y + (o.y – p.y));
} else {
self.selected.position = CGPointMake(p.x, self.selected.position.y);
pair.position = CGPointMake(o.x + (o.x – p.x), self.selected.position.y);
}
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
self.selected = nil;
}
@end