I want to create a new sprite in a grid if the field is empty. I also want this new sprite to be centred in the empty field. Let's say the field is:
1 1 1
1 1 0
1 1 1
Whenever I click on one of the fields that is filled with a 1, the sprite disappears (this is what I want and this works fine).
Whenever I click on the 0, a new sprite is added with the following code:
UITouch *touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:positionInScene];
if(touchedNode.position.x == 0) { // x is 0 when I click an empty field, aka background
[self addThing:positionInScene];
}
And:
-(void)addThing:(CGPoint)newLocation{
SKSpriteNode *thing = [SKSpriteNode spriteNodeWithImageNamed:#"thing"];
thing.location = newLocation;
[self addChild:thing];
thing.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:thing.size.width/2];
thing.physicsBody.dynamic = NO;
thing.physicsBody.categoryBitMask = somethingCategory;
thing.physicsBody.contactTestBitMask = somethingElseCategory;
thing.physicsBody.collisionBitMask = 0;
}
However, this sprite is centred in the exact coordinates I click, rather than the centre point of the empty field. How can I make this happen?
The following creates an N x M grid with a sprite at each row and column. When the user touches one of the sprites, it rotates the sprite and then removes it from the scene. If a sprite is not found at the touch location, a sprite is added there.
#define kBoardMinX 25
#define kBoardMinY 25
#define kNumCols 3
#define kNumRows 3
#define kSpacing 40
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
[self addPiecesToScene];
}
return self;
}
// Convert row and col to the appropriate point (in scene coordinates) in the grid
- (CGPoint) pointFromRow:(NSInteger)row andCol:(NSInteger)col
{
return CGPointMake(kBoardMinX+col*kSpacing, kBoardMinY+(kNumRows-row-1)*kSpacing);
}
// If a sprite is found at (row, col) rotate it, else add a sprite there
- (void) rotatePieceAtRow:(NSInteger)row andCol:(NSInteger)col
{
SKSpriteNode *node = (SKSpriteNode *)[self nodeAtPoint:[self pointFromRow:row andCol:col]];
if (node && (SKNode *)node != self) {
SKAction *rotate = [SKAction rotateByAngle:M_PI*2 duration:2];
SKAction *remove = [SKAction removeFromParent];
SKAction *rotateThenRemove = [SKAction sequence:#[rotate,remove]];
[node runAction:rotateThenRemove];
}
else {
[self addPieceAtRow:row andCol:col];
}
}
- (void) togglePieceAtTouchLocation:(CGPoint)location
{
// Convert touch location to row and column
NSInteger col = (NSInteger)roundf((location.x - kBoardMinX) / kSpacing);
NSInteger row = kNumRows - (NSInteger)roundf((location.y - kBoardMinY) / kSpacing) - 1;
// Check if the touch was within the grid
if (col >= 0 && col < kNumCols && row >= 0 && row < kNumRows) {
[self rotatePieceAtRow:row andCol:col];
}
}
- (void) addPieceAtRow:(NSInteger)row andCol:(NSInteger)col
{
CGSize size = CGSizeMake(32, 32);
SKColor *color = [SKColor whiteColor];
SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:color size:size];
node.position = [self pointFromRow:row andCol:col];
[self addChild:node];
}
- (void) addPiecesToScene
{
for (int row=0;row<kNumRows;row++) {
for (int col=0;col<kNumCols;col++) {
[self addPieceAtRow:row andCol:col];
}
}
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
[self togglePieceAtTouchLocation:location];
}
}
Related
Working with Xcode, Spritebuilder and Cocos2d, I am trying to let the players sprite only jump 1 single time. So when the player taps the screen, the sprite jumps, and only when it has landed, the player should again be able to jump again. I haven't found any clear explanations so far, so hence my question.
Here's my code
Edit so that the code only lets the sprite jump once:
static const CGFloat scrollSpeed = 0.4;
BOOL isInAir;
#implementation GameScene
{
CCSprite *player1;
CCPhysicsNode *physicsNode1;
CCNode *ground1;
CCNode *ground2;
}
- (void)didLoadFromCCB
{
self.userInteractionEnabled = TRUE;
grounds = #[ground1, ground2]
}
- (void)update:(CCTime)delta
{
// moves the player to the right
player1.position = ccp(player1.position.x + delta * scrollSpeed, player1.position.y);
// move the camera with the player
physicsNode1.position = ccp(physicsNode1.position.x - (scrollSpeed *delta), physicsNode1.position.y);
// loop the ground
for (CCNode *ground in grounds)
{
// get the world position of the ground
CGPoint groundWorldPosition = [physicsNode1 convertToWorldSpace:ground.position];
// get the screen position of the ground
CGPoint groundScreenPosition = [self convertToNodeSpace:groundWorldPosition];
// if the left corner is one complete width off the screen, move it to the right
if (groundScreenPosition.x <= (-1 * ground.contentSize.width))
{
// puts the ground piece that is about to leave the screen behind the last one
ground.position = ccp(ground.position.x + 600, ground.position.y);
//NSLog(#"player1 pos: %#", NSStringFromCGPoint(ground.position));
}
}
// clamp velocity
float yVelocity = clampf(player1.physicsBody.velocity.y, -1 * MAXFLOAT, 200.f);
player1.physicsBody.velocity = ccp(0, yVelocity);
}
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
if (isInAir == NO)
{
[player1.physicsBody applyImpulse:ccp(0, 150)];
isInAir = YES;
}
}
- (BOOL) ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair player1:(CCNode *)player1 ground: (CCNode *)ground
{
NSLog(#"player is touching the ground");
isInAir = NO;
return YES;
}
#end
You can use a BOOL. Here is my code for a jump on touch:
BOOL isInAir;//Make this global.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
UITouch *touch = [touches anyObject];
SKSpriteNode *node = [self nodesAtPoint:[touch locationInNode:self]];
if (isInAir == NO)
{
CGFloat impulseX = 0.0f;
CGFloat impulseY = 600.0f;
[node.physicsBody applyImpulse:CGVectorMake(impulseX, impulseY) atPoint:node.position];
isInAir = YES;
//other stuff
}
}
Then when you contact ground, set isInAir to NO.
I've used this same exact code before, and it worked perfect every time. However, I'm trying to use it to move the paddle sprite along a horizontal path at position 100 for y and it updates with the location of my touch but for some reason it's not moving at all. I can't spot what's wrong. Can someone take a look and let me know?
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches){
CGPoint location = [touch locationInNode:self];
CGPoint newPosition = CGPointMake(location.x, 100);
//stop the paddle from going too far
if (newPosition.x < self.paddle.size.width/ 2) {
newPosition.x = self.paddle.size.width/ 2;
}
if (newPosition.x > self.size.width - (self.paddle.size.width/ 2)) {
newPosition.x = self.size.width - (self.paddle.size.width/ 2);
}
self.paddle.position = newPosition;
}
}
-(void) addPlayer:(CGSize)size {
SKSpriteNode *paddle = [SKSpriteNode spriteNodeWithImageNamed:#"paddle"];
//resize sprite
paddle.size = CGSizeMake(125, 31.25);
//position sprite
paddle.position = CGPointMake(size.width/2, 100);
//add physics body to paddle
paddle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:paddle.frame.size];
//change to static so wont be moved by physics
paddle.physicsBody.dynamic = NO;
//add sprite to scene
[self addChild:paddle];
}
-(instancetype)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]){
self.backgroundColor = [SKColor colorWithRed:(29.0f/255) green:(29.0f/255) blue:(29.0f/255) alpha:1.0];
//change gravity
self.physicsWorld.gravity = CGVectorMake(0, 0);
//add physics body to scene
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
[self addPlayer:size];
[self addBricks:size];
[self addBall:size];
}
return self;
}
I am making a game which purpose it is to catch multiple objects that are falling from the top of the screen. In the bottom there is a basket to catch the objects. i managed to randomly spawn objects from the top dropping to the bottom using raywenderlich's tutorial : http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners
But what i want is that when i tap on that random object, the image of that object changes into another image , so just for imagination if the random objects are cats, after i tap them they have to become dogs, how do i have to program this?
edit this is what i got so far :
#import "MyScene.h"
static NSString* basketCategoryName = #"basket";
static NSString* monsterCategoryName= #"monster";
static const uint32_t projectileCategory = 0x1 << 0;
static const uint32_t monsterCategory = 0x1 << 1;
#interface MyScene() <SKPhysicsContactDelegate>
#property (nonatomic) SKLabelNode * scoreLabelNode;
#property int score;
#property (nonatomic) SKSpriteNode * basket;
#property (nonatomic) SKSpriteNode * monster;
#property (nonatomic) BOOL isFingerOnBasket;
#property (nonatomic) BOOL isFingerOnMonster;
#property (nonatomic) BOOL isTouching;
#property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
#property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
//#property (nonatomic, strong) SKSpriteNode *selectedNode;
#end
#implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
// Initialize label and create a label which holds the score
_score = 0;
_scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:#"MarkerFelt-Wide"];
_scoreLabelNode.position = CGPointMake( CGRectGetMidX( self.frame ), 3 * self.frame.size.height / 4 );
_scoreLabelNode.zPosition = 100;
_scoreLabelNode.text = [NSString stringWithFormat:#"%d", _score];
[self addChild:_scoreLabelNode];
// Set the background
SKTexture* groundTexture = [SKTexture textureWithImageNamed:#"AcornFlipTestBackground1136x640.png"];
groundTexture.filteringMode = SKTextureFilteringNearest;
for( int i = 0; i < 2 + self.frame.size.width / ( groundTexture.size.width * 2 ); ++i ) {
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:groundTexture];
[sprite setScale:1.0];
sprite.size = CGSizeMake(self.frame.size.width,self.frame.size.height);
sprite.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
[self addChild:sprite];
}
// Make grafity for sprite
self.physicsWorld.gravity = CGVectorMake(0.0f, 0.0f);
self.physicsWorld.contactDelegate = self;
// Make catching object sprite
self.basket = [SKSpriteNode spriteNodeWithImageNamed:#"bedTest.png"];
self.basket.position = CGPointMake(CGRectGetMidX(self.frame), _basket.frame.size.height * 0.5f);
self.basket.name = basketCategoryName;
[self addChild:self.basket];
// For default this is set to no until user touches the basket and the game begins.
self.isTouching = NO;
}
return self;
}
-(void)addAcorn{
if(_isTouching == YES) {
self.monster= [SKSpriteNode spriteNodeWithImageNamed:#"AcornFinal.png"];
// Determine where to spawn the monster along the X axis
int minX = self.monster.size.width;
int maxX = self.frame.size.width - self.monster.size.width;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX)+minX;
// Random position along the X axis as calculated above
// This describe from which way the acorns move
// - means moving from top to the right and + means moving from the top to the left
self.monster.position = CGPointMake(actualX ,self.frame.size.height+ self.monster.size.height);
self.monster.name = monsterCategoryName;
[self addChild:self.monster];
CGSize contactSize = CGSizeMake(self.monster.size.width - 5.0, self.monster.size.height - 10.0);
self.monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize]; // 1
self.monster.physicsBody.dynamic = YES; // 2
self.monster.physicsBody.categoryBitMask = monsterCategory; // 3
self.monster.physicsBody.contactTestBitMask = projectileCategory; // 4
self.monster.physicsBody.collisionBitMask = 0; // 5
// Determine speed of the monster
int minDuration = 8.0;
int maxDuration = 10.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX,-self.monster.size.height) duration:actualDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
[self.monster runAction:[SKAction sequence:#[actionMove, actionMoveDone]]];
}
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 0.5) {
self.lastSpawnTimeInterval = 0;
[self addAcorn];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
self.isTouching = YES;
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode* body = [self nodeAtPoint:location];
if ([body.name isEqualToString:basketCategoryName])
{
NSLog(#"Began touch on basket");
self.isFingerOnBasket = YES;
}
else if ([body.name isEqualToString:monsterCategoryName])
{
NSLog(#"Began touch on MONSTER");
self.isFingerOnMonster = YES;
}
}
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (self.isFingerOnMonster) {
// 2 Get touch location
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint previousLocation = [touch previousLocationInNode:self];
// 3 Get node for paddle
SKSpriteNode* monster = (SKSpriteNode*)[self childNodeWithName: monsterCategoryName];
int oldPosition = monster.position.x + (location.x - previousLocation.x);
self.monster = [SKSpriteNode spriteNodeWithImageNamed:#"AcornFinal.png"];
monster.position = CGPointMake(oldPosition, monster.position.y);
NSLog(#"reached the touch though");
}
// 1 Check whether user tapped paddle
if (self.isFingerOnBasket) {
// 2 Get touch location
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint previousLocation = [touch previousLocationInNode:self];
// 3 Get node for paddle
SKSpriteNode* basket = (SKSpriteNode*)[self childNodeWithName: basketCategoryName];
// 4 Calculate new position along x for paddle
int basketX = basket.position.x + (location.x - previousLocation.x);
// 5 Limit x so that the paddle will not leave the screen to left or right
basketX = MAX(basketX, basket.size.width/2);
basketX = MIN(basketX, self.size.width - basket.size.width/2);
// 6 Update position of paddle
basket.position = CGPointMake(basketX, basket.position.y);
CGSize contactSize = CGSizeMake(basket.size.width - 8.0, basket.size.height - 8.0);
basket.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];
basket.physicsBody.dynamic = YES;
basket.physicsBody.categoryBitMask = projectileCategory;
basket.physicsBody.contactTestBitMask = monsterCategory;
basket.physicsBody.collisionBitMask = 0;
basket.physicsBody.usesPreciseCollisionDetection = YES;
}
}
- (void)projectile:(SKSpriteNode *)basket didCollideWithMonster:(SKSpriteNode *)monster {
NSLog(#"Hit");
[monster removeFromParent];
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
// 1
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// 2
if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
(secondBody.categoryBitMask & monsterCategory) != 0)
{
[self projectile:(SKSpriteNode *) firstBody.node didCollideWithMonster:(SKSpriteNode *) secondBody.node];
NSLog(#"test");
_score++;
_scoreLabelNode.text = [NSString stringWithFormat:#"%d", _score];
}
}
// Removing this void will result in being able to drag the basket accross the screen without touching the basket itself.
-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
self.isFingerOnBasket = NO;
self.isFingerOnMonster = NO;
}
#end
Once a touch is detected on a sprite (I assume you already got that working out) you can either create the sprite again with spriteNodeWithImageNamed. Make sure you save the previous node's position and set it again on the new sprite so it will match the position of the old sprite.
CGPoint oldPosition = touchedSprite.position;
touchedSprite = [SKSpritNode spriteWithImageNamed:#"imgge.png"];
touchedSprite.position = oldPosition;
// If you have any other sprite properties you will have to save them as well
You can also set the texture with setTexture method which will not require you to change anything else (e.g. position) :
[touchedSprite setTexture:[SKTexture textureWithImageNamed:#"image.png"]];
EDIT :
Answering your question in the comments you implement this in the touchesEnded method of the parent node of the sprites :
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
for (SKSpriteNode *sprite in fallingSprites) { // Assuming fallingSprite is an array containing the cat sprites you want to detect touches for
if (CGRectContainsPoint(sprite.frame, touchLocation)) {
[sprite setTexture:[SKTexture textureWithImageNamed:#"dog.png"]];
}
}
}
Another approach (Haven't tried it yet) is to subclass SKSpriteNode and implement the same method but without the touch detection in rect since if this method is called the sprite has been touched .
Each part of the skeleton model is a spritekit node. Find the node that you wish to change and update its texture property like this:
spriteKitNode.texture = // Updated SKTexture
In your TouchesEnded event:
Add a small skspritenode positioned at the touch location with a small physics body that last for a short duration. ("touch spritenode)
Set up contact between all possible transformed objects and the "touch spritenode"
Create a subclass of SKSpritenode for the falling objects that has a variable to stores their type.
In the method called from contact between the touch spritenode and the falling objects:
Remove the touchspritenode first
Create if statements to check which falling object was touched.
Update the image of the contacted falling object spritenode according to its type.
If you are following Raywenderlich you have access to the actual syntax
I'm New to SpriteKit and build a simple CLickerGame in SpriteKit. Now i have the game finish but the thing which should spawn to click on it, spawns from time to time outside the screen. Where can i select the arc4random area where the thing should spawn?
#implementation MyScene
-(void)CreateTestObject
{
SKSpriteNode *TestObject = [SKSpriteNode spriteNodeWithImageNamed:#"TestObject"];
int maxX = CGRectGetMaxX(self.frame);
float ranX = (arc4random()%maxX) + 1;
int maxY = CGRectGetMaxY(self.frame);
float ranY = (arc4random()%maxY) + 1;
TestObject.position = CGPointMake(ranX, ranY);
TestObject = CGSizeMake(75, 75);
TestObject = #"Object";
[self addChild:TestObject];
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
bg = [SKSpriteNode spriteNodeWithImageNamed:#"bg.png"];
bg.position = CGPointMake(160, 284);
bg.size = CGSizeMake(self.frame.size.width, self.frame.size.height);
[self addChild:bg];
[self CreateTestObject];
}
return self;
}
-(void)selectNodeForTouch:(CGPoint)touchLocation
{
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
if([[touchedNode name] isEqualToString:#"TestObject"])
{
SKSpriteNode *TestObject = (SKSpriteNode *)[self childNodeWithName:#"TestObject"];
TestObject.name = #"DisabledTestObject";
SKAction *grow = [SKAction scaleTo:1.2 duration:0.1];
SKAction*shrink = [SKAction scaleTo:0 duration:0.07];
SKAction *removeNode = [SKAction removeFromParent];
SKAction *seq = [SKAction sequence:#[grow, shrink, removeNode]];
[TestObject runAction:seq];
[self CreateTestObject];
[self runAction:[SKAction playSoundFileNamed:#"Sound.aif" waitForCompletion:NO]];
}
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
{
//CGPoint location = [touch locationInNode:self];
UITouch *touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
[self selectNodeForTouch:positionInScene];
}
}
#end
Modify the max values for your (x,y) coordinates of any object being added to your view.
For example, on an iPhone 5 display in landscape mode and the spawned object being of size width=100, height=100, the max x value should be no more than 518. Width of screen being 568 less half the width of your object (50).
The same logic applies for the y value. The max y value should be 270 given the same object dimensions.
The above assumes that you have not changed your object's anchor point from (0.5,0.5) to another value.
I'm working on a game for iOS and I was wondering why this countdown won't work. I want to have a set amount of moves per level in this game, and I want it to subtract 1 move every time the user taps on one of the puzzle pieces.
This is the bit of code I've set up:
I set up two integers in the header file: int movesRemaining; and int moved;
The SKLabelNode that displays the amount of moves:
moves = [SKLabelNode labelNodeWithFontNamed:#"DIN Condensed"];
moves.position = CGPointMake(110, -15);
moves.text = [NSString stringWithFormat:#"MOVES %d", movesRemaining];
moves.fontSize = 25;
moves.zPosition = 2.0;
moves.fontColor = [SKColor whiteColor];
[menuBar addChild:moves];
The method that calculates the score:
-(void)moves {
movesRemaining = 4;
movesRemaining = (movesRemaining - moved);
}
The code that tells movesRemaining to subtract 1 move each time the puzzle is touched:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:#"sq1"]) {
[_BS1 removeFromParent];
moved = 1;
}
if ([node.name isEqualToString:#"sq2"]) {
[_BS2 removeFromParent];
moved = 1;
}
if ([node.name isEqualToString:#"sq3"]) {
[_BS3 removeFromParent];
moved = 1;
}
if ([node.name isEqualToString:#"sq4"]) {
[_BS4 removeFromParent];
moved = 1;
}
if ([node.name isEqualToString:#"sq5"]) {
[_BS5 removeFromParent];
moved = 1;
}
My question is where did I go wrong that it doesn't subtract 1 each time the puzzle is tapped? How can I properly make movesRemaining subtract 1 each time the user touches the puzzle piece?
If more information is needed please let me know.
Thanks.
Problem is that it isn't being updated. How to fix:
Touches:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:#"sq1"]) {
movesRemaining = movesRemaining - 1;
[_BS1 removeFromParent];
}
Take out the stuff in the initWithSize method and add this to your -(void)update:(CFTimeInterval)currentTime method:
if (!moves) {
moves = [SKLabelNode labelNodeWithFontNamed:#"DIN Condensed"];
moves.position = CGPointMake(110, -15);
moves.fontSize = 25;
moves.zPosition = 2.0;
moves.fontColor = [SKColor whiteColor];
[menuBar addChild:moves];
}
//scoring
moves.text = [NSString stringWithFormat:#"MOVES %d", movesRemaining];
This will fix your code. It will then update every time it is tapped like you want it to.
Move movesRemaining = 4; to the init method.
Then add [self moves]; to the end of -(void)touchesBegan.
In the moved method change it so that it declares moved = moved - 1; then that will add the rolling effect
moves = [SKLabelNode labelNodeWithFontNamed:#"DIN Condensed"];
moves.position = CGPointMake(110, -15);
moves.text = [NSString stringWithFormat:#"MOVES %d", movesRemaining];
moves.fontSize = 25;
moves.zPosition = 2.0;
moves.fontColor = [SKColor whiteColor];
movesRemaining = 4; //Move initial movesRemaining value here.
[menuBar addChild:moves];
-(void)moves { //Subtract number of moves everytime the user moves.
movesRemaining = (movesRemaining - moved);
}