ひらがな「なにぬねの」を使ったシューティングゲームをiPhoneアプリで描いてみます。(SpriteKit使います。)
動作イメージ
XcodeからiOS7 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <SpriteKit/SpriteKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ShootScene : SKScene <SKPhysicsContactDelegate>
@property BOOL contentCreated;
@property NSMutableArray *mySounds;
@end
@implementation ShootScene
– (void)didMoveToView:(SKView *)view
{
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
self.physicsWorld.gravity = CGVectorMake(0, 0); // zero gravity
self.physicsWorld.contactDelegate = self;
}
}
– (void)createSceneContents
{
[self createHiragana];
[self createTank];
[self prepareToSounds];
}
– (void)createHiragana
{
NSArray *words = @[@”な“,@”に“,@”ぬ“,@”ね“,@”の“];
NSArray *speedPattern = @[@100, @(–150), @50, @(–80), @20];
for (int i=0; i<5; i++) {
SKShapeNode *node = [[SKShapeNode alloc] init];
node.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-20, –20, 40, 40)].CGPath;
node.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:20];
node.position = CGPointMake(160, 200 + i * 50);
node.physicsBody.velocity = CGVectorMake([speedPattern[i] intValue], 0);
node.name = @”hiragana”;
node.physicsBody.collisionBitMask = 0x1;
node.physicsBody.contactTestBitMask = 0x1 << 1;
[self addChild:node];
NSString *s = words[i];
SKLabelNode *l = [[SKLabelNode alloc] init];
l.fontSize = 30;
l.position = CGPointMake(0, –10);
l.text = s;
[node addChild:l];
}
}
– (void)createTank
{
SKShapeNode *node = [[SKShapeNode alloc] init];
node.fillColor = [SKColor whiteColor];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(-30, 0, 60, 20)];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(-10, 20, 20, 20)]];
node.path = path.CGPath;
node.position = CGPointMake(160, 40);
node.name = @”tank”;
[self addChild:node];
}
– (void)didSimulatePhysics
{
[self enumerateChildNodesWithName:@”hiragana” usingBlock:^(SKNode *node, BOOL *stop) {
if(node.position.x < 0 || node.position.x > 320) {
node.physicsBody.velocity = CGVectorMake(-node.physicsBody.velocity.dx, 0);
}
}];
[self enumerateChildNodesWithName:@”cannonball” usingBlock:^(SKNode *node, BOOL *stop) {
if (!CGRectContainsPoint(CGRectMake(0, 0, 320, 568), node.position)) {
[node removeFromParent];
}
}];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInNode:self];
SKNode *node = [self childNodeWithName:@”tank”];
if ([node containsPoint:p]) {
[self fire];
} else {
node.position = CGPointMake(p.x, node.position.y);
}
}
– (void)fire
{
SKShapeNode *node = [[SKShapeNode alloc] init];
node.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-5, –5, 10, 10)].CGPath;
node.position = [self childNodeWithName:@”tank”].position;
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(10, 10)];
node.physicsBody.velocity = CGVectorMake(0, 500);
node.name = @”cannonball”;
node.physicsBody.collisionBitMask = 0x1;
node.physicsBody.contactTestBitMask = 0x1 << 1;
[self addChild:node];
}
– (void)didEndContact:(SKPhysicsContact *)contact
{
NSArray *nodes = @[contact.bodyA.node, contact.bodyB.node];
for (SKNode *node in nodes) {
if ([node.name isEqual:@”hiragana”]) {
SKLabelNode *l = [node children][0];
[self performSelector:@selector(sound:) withObject:l.text afterDelay:0.01];
}
}
}
– (void)prepareToSounds
{
NSArray *names = @[@”na”,@”ni”,@”nu”,@”ne”,@”no”];
self.mySounds = [[NSMutableArray alloc] init];
for (NSString *s in names) {
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:s ofType:@”m4a”]];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
[player prepareToPlay];
[self.mySounds addObject:player];
}
}
– (void)sound:(NSString*)s
{
NSArray *kakiku = @[@”な“, @”に“, @”ぬ“, @”ね“, @”の“];
NSUInteger i = [kakiku indexOfObject:s];
[(AVAudioPlayer*)self.mySounds[i] play];
}
@end
@interface ViewController ()
@property (strong, nonatomic) SKView *spriteView;
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.spriteView];
SKScene *scene = [[ShootScene alloc] initWithSize:self.view.bounds.size];
[self.spriteView presentScene:scene];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@”reset” forState:UIControlStateNormal];
btn.titleLabel.textColor = [UIColor whiteColor];
btn.frame = CGRectMake(0, 0, 100, 30);
btn.center = CGPointMake(50, 450);
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(reset) forControlEvents:UIControlEventTouchUpInside];
}
– (void)reset
{
SKScene *newScene = [[ShootScene alloc] initWithSize:self.view.bounds.size];
[self.spriteView presentScene:newScene transition:[SKTransition doorsCloseHorizontalWithDuration:0.5]];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end