dennis-tra
dennis-tra

Reputation: 1319

iOS 7 - SpriteKit Buttons/MenuItem

I am trying to build a simple iOS game. When my main menu loads and appears on screen, I wanna have the buttons move in from the sides. My only idea is to apply some SKActions to SKSpriteNodes. But so I have to create my own button-class. Is there a simpler method to accomplish this? Are there already classes like CCMenuItem/CCMenu from cocos2d? Or is there a way with UIButtons?

Thanks

Upvotes: 2

Views: 4498

Answers (2)

user2796283
user2796283

Reputation: 313

I created a button class that has a SKSpriteNode property, a CGRect property and a Radius property (for round buttons). When you initialise the button with an image it set's it's CGRect and Radius property based on the image size. You can then just check if a player's hitting the button by calling to it's -collisionRect method which return's a CGRect and check if the "touch" location is within that rect. This way the button's can move around and still receive input. Here's the code...

////////////////////// HEADER FILE //////////////////////

//
//  ZSButton.h
//  PEGO
//
//  Created by Zion Siton on 07/09/2013.
//  Copyright (c) 2013 zillustrator. All rights reserved.
//

#import <SpriteKit/SpriteKit.h>

@interface ZSButton : SKNode {

    SKSpriteNode *mySprite;
    CGRect myRect;
    CGFloat myRadius;

}

@property (nonatomic, strong)SKSpriteNode *mySprite;
@property (nonatomic, assign)CGRect myRect;
@property (nonatomic, assign)CGFloat myRadius;

- (id)initWithTexture:(SKTexture *)texture;
- (BOOL)didRadialCollideWith:(CGPoint)aPoint;

@end

/////////////////// IMPLEMENTATION FILE //////////////////////

//
//  ZSButtonA.m
//  PEGO
//
//  Created by Zion Siton on 07/09/2013.
//  Copyright (c) 2013 zillustrator. All rights reserved.
//

#import "ZSButton.h"

@implementation ZSButton

@synthesize mySprite, myRect, myRadius;

- (id)init {

    // Use a default button image
    return [self initWithTexture:[SKTexture textureWithImageNamed:@"ButtonDefault.png"]];

}

- (id)initWithTexture:(SKTexture *)texture {

    self = [super init];
    if (self) {

        // Assumes there is a texture
        mySprite = [SKSpriteNode spriteNodeWithTexture:texture];
        [self addChild:mySprite];

        // Assumes the collision area is the size of the texture frame
        myRect = [mySprite frame];

        // Assumes the texture is square
        myRadius = myRect.size.width * 0.5;

    }

    return self;

}

- (CGRect)myRect {

    CGPoint pos = [self position];
    CGFloat originX = pos.x - (mySprite.frame.width * 0.5);
    CGFloat originY = pos.y - (mySprite.frame.height * 0.5);
    CGFloat width = mySprite.frame.width;
    CGFloat height = mySprite.frame.height;

    myRect = CGRectMake(originX, originY, width, height);

    return myRect;

}

- (BOOL)didRadialCollideWith:(CGPoint)aPoint {

    // Get the distance between the button centre and the touch
    // ZSMath is a class I wrote that mainly performs trigonometric functions
    CGFloat distance = [ZSMath distanceFromA:[self position] toB:aPoint];

    // Perform a radial collision check
    if (distance < [self myRadius]) {

        // HIT!!!
        return YES;
    }

    // MISS!!!
    return NO;

}

@end

////////////////// TO INITIALISE A BUTTON...

// Initialize BACK BUTTON
        backButton = [[ZSButton alloc] initWithTexture:
                      [[ZSGraphicLoader sharedGraphicLoader] frameByName:kBACK_BUTTON]];
        [self addChild:backButton];

////////////////// TO TEST FOR A COLLISION/USER PRESS

for (UITouch *touch in touches) {

    // Get the user's touch location
    CGPoint location = [touch locationInNode:self];

    // If the user taps on BACK Button Rectangle
    if (CGRectContainsPoint(backButton.myRect, location))
    {
        // DO A RADIAL CHECK
        if ([backButton didRadialCollideWith:location])
        {
            // DO BACK BUTTON STUFF
        }

    }

}

Upvotes: 1

ajeetdl
ajeetdl

Reputation: 1284

Creating your own button class inheriting from SKSpriteNode and adding actions takes mere minutes and works really well. UIButton and SKScene don't seem to play well together with respect to touches and really there's no need considering the approach described works really well. You can add your own textures and colors to the button using the inherited SKSpriteNode members.

Upvotes: 0

Related Questions