How to blink SpritekitNode? - ios

i want to blink SpritekitNode when two player and monster collapse . im using code in didBeginContact:
-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ([firstBody.node.name isEqual: OBSTACLE_KEY] && ( [secondBody.node.name isEqual: PLAYER_KEY] ))
{
if ([kPref integerForKey:BUY_LIFES] > 0)
{
SKAction *blink = [SKAction sequence:#[[SKAction fadeOutWithDuration:0.25],
[SKAction fadeInWithDuration:0.25]]];
SKAction *blinkForever = [SKAction repeatAction:blink count:3];
[secondBody.node runAction: blinkForever];
int life = [kPref integerForKey:BUY_LIFES] - 1;
[kPref setInteger:life forKey:BUY_LIFES];
}
else
{
[kPref setInteger:sec forKey:HIGH_SCORE];
self.paused =YES;
}
}
}
it working but it continuously call didBeginContact when monster touches player node till it connected to it, i want to set in way that if monster node touch player than it blinks 3 times and that period of time none monster can touch player node.
Please help me out.!

Related

sprite kit can't receive contact message nodes

so i made the code below to receive contact:
- (void) didBeginContact:(SKPhysicsContact *)contact{
SKPhysicsBody *firstBody,*secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
//player<enemy<abilities
firstBody =contact.bodyA; // player
secondBody = contact.bodyB; // enemy or abilities
} else {
firstBody = contact.bodyB;//player
secondBody = contact.bodyA;//enemy or projectile
}
if (firstBody.categoryBitMask == collisionCatergoryPlayer &&
secondBody.categoryBitMask == collisionCatergoryEnemy) {
NSLog(#"test");
playerBall *ball = (playerBall *)firstBody.node;
[ball removeFromParent];
enemyBall *enemyBall1 = (enemyBall *)secondBody.node;
[enemyBall1 removeFromParent];
} else if (firstBody.categoryBitMask == collisionCatergoryPlayer &&
secondBody.categoryBitMask == collisionCatergoryAbilities){
NSLog(#"upgrade");
abilities *abilities1 = (abilities *)secondBody.node;
//if theres abilities2 and 3,make a catergory bit mask for it and remove it from parent
[abilities1 removeFromParent];
}
}
but i can't receive the nslog messages from the code above,please help!!!!
also the remove nodes are not doing anything,my bit mask is player

Cannot add SKSpriteNode dynamically?

I'm adding SKSpriteNode dynamically on didBeginContact delegate method :
Here is my code
-(void)adBall
{
SKSpriteNode *obj = [[SKSpriteNode alloc]initWithImageNamed:#"ball.png"];
obj.physicsBody = [SKPhysicsBody bodyWithTexture:obj.texture size:obj.texture.size];
obj.position = CGPointMake(100, 100);
obj.name = OBSTACLE_KEY;
obj.physicsBody.categoryBitMask = BallCategory1;
obj.physicsBody.contactTestBitMask = GreenLineCategory | RedLineCategory ;;
obj.physicsBody.collisionBitMask = GreenLineCategory | RedLineCategory ;;
obj.physicsBody.affectedByGravity = YES;
obj.physicsBody.dynamic = YES;
obj.physicsBody.friction = 0.0f;
obj.physicsBody.linearDamping = 0.0f;
obj.physicsBody.restitution = 1.0f;
obj.physicsBody.allowsRotation = NO;
[obj.physicsBody applyForce:CGVectorMake(200, 300)];
}
-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ([firstBody.node.name isEqual: OBSTACLE_KEY] && ( [secondBody.node.name isEqual: BLACKLINE_KEY]))
{
[self adBall];
}
}
But cant appear in screen it just show ball at bottom and disappear.
and if add [self adBall]; in didMoveToView method than working fine.
So Plz tell me where I'm wrong here ?
You never run
[self addChild:obj];
inside your adBall method. Therefore the newly created sprite won't be added to the scene graph and naturally won't be drawn (it gets discarded at the end of the method).
Ok Done it.
as LearnCocos2D said that i didn't add [self addChild:obj]; i add that line but than it not working in didMoveToView than what i did is called method after some time.
Like :
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self adBall];
});

Adding a start and end screen in ios game

I am having trouble having my game begin paused so that the player has to press a button to start the game. I also have collision detection working, so when the two objects collide they just fall off of the screen. Here is my current code:
- (instancetype)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.physicsWorld.contactDelegate = self;
[self buildBackground];
[self startScrolling];
_firstPosition = CGPointMake(self.frame.size.width * 0.817f, self.frame.size.height * .40f);
_squirrelSprite = [SKSpriteNode spriteNodeWithImageNamed:#"squirrel"];
_squirrelSprite.position = _firstPosition;
_atFirstPosition = YES;
_squirrelSprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
_squirrelSprite.physicsBody.categoryBitMask = squirrelHitCategory;
_squirrelSprite.physicsBody.contactTestBitMask = nutHitCategory;
_squirrelSprite.physicsBody.collisionBitMask = nutHitCategory;
_squirrelSprite.physicsBody.affectedByGravity = NO;
self.physicsWorld.contactDelegate = self;
[self addChild:_squirrelSprite];
// Declare SKAction that waits 2 seconds
SKAction *wait = [SKAction waitForDuration:3.0];
// Declare SKAction block to generate the sprites
SKAction *createSpriteBlock = [SKAction runBlock:^{
const BOOL isHeads = arc4random_uniform(100) < 50;
NSString* spriteName = isHeads ? #"lightnut.png" : #"darknut.png";
SKSpriteNode *nut = [SKSpriteNode spriteNodeWithImageNamed:spriteName];
BOOL heads = arc4random_uniform(100) < 50;
nut.position = (heads)? CGPointMake(257,600) : CGPointMake(50,600);
nut.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(200,160)];
nut.physicsBody.categoryBitMask = nutHitCategory;
nut.physicsBody.contactTestBitMask = squirrelHitCategory;
nut.physicsBody.collisionBitMask = squirrelHitCategory;
nut.physicsBody.affectedByGravity = NO;
self.physicsWorld.contactDelegate = self;
[self addChild: nut];
SKAction *moveNodeUp = [SKAction moveByX:0.0 y:-700.0 duration:1.3];
[nut runAction: moveNodeUp];
}];
// Combine the actions
SKAction *waitThenRunBlock = [SKAction sequence:#[wait,createSpriteBlock]];
// Lather, rinse, repeat
[self runAction:[SKAction repeatActionForever:waitThenRunBlock]];
}
return self;
}
My touchesBegan:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (_atFirstPosition)
{
SKAction *moveNodeLeft = [SKAction moveByX:-207.8 y:0.0 duration:0.85];
[_squirrelSprite runAction: moveNodeLeft withKey:#"moveleft"];
} else {
SKAction *moveNodeRight = [SKAction moveByX:207.8 y:0.0 duration:0.85];
[_squirrelSprite runAction: moveNodeRight withKey:#"moveright"];
}
_atFirstPosition = !_atFirstPosition;
_squirrelSprite.xScale *= -1.0;
}
Finally, my didBeginContact:
-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
firstBody = contact.bodyA;
secondBody = contact.bodyB;
if(firstBody.categoryBitMask == squirrelHitCategory || secondBody.categoryBitMask == nutHitCategory)
{
}
}
I've been trying to figure this out for the last 2 weeks and I have read many tutorials and code to start the game with a simple start button and end screen, but nothing has worked. Any help is greatly appreciated!
I would use a navigation controller and have your start button on the root view and have that button push a viewcontroller that presents your game.

Sprite Kit, Remove Sprite for collision

Im making a game in sprite kit and I'm fairly new to iOS programming and i have been working on getting it so when 2 images collide that one is deleted or made invisible. I have been very unsuccessful with this and was wondering if anyone knew how to do it?
Below is the ship (which always stays) and one of the objects to be deleted.
-(void)addShip
{
//initalizing spaceship node
ship = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship"];
[ship setScale:0.5];
ship.zRotation = - M_PI / 2;
//Adding SpriteKit physicsBody for collision detection
ship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ship.size];
ship.physicsBody.categoryBitMask = shipCategory;
ship.physicsBody.dynamic = YES;
ship.physicsBody.contactTestBitMask = DonutCategory | PizzaCategory | ChocolateCategory | SoftCategory | AppleCategory | GrapeCategory | OrangeCategory | BananaCategory;
ship.physicsBody.collisionBitMask = 0;
ship.physicsBody.usesPreciseCollisionDetection = YES;
ship.name = #"ship";
ship.position = CGPointMake(260,30);
actionMoveRight = [SKAction moveByX:-30 y:0 duration:.2];
actionMoveLeft = [SKAction moveByX:30 y:0 duration:.2];
[self addChild:ship];
}
- (void)shoot1 //donut
{
// Sprite Kit knows that we are working with images so we don't need to pass the image’s extension
Donut = [SKSpriteNode spriteNodeWithImageNamed:#"1"];
[Donut setScale:0.15];
// Position the Donut outside the top
int r = arc4random() % 300;
Donut.position = CGPointMake(20 + r, self.size.height + Donut.size.height/2);
Donut.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:Donut.size];
Donut.physicsBody.categoryBitMask = DonutCategory;
Donut.physicsBody.dynamic = YES;
Donut.physicsBody.contactTestBitMask = shipCategory;
Donut.physicsBody.collisionBitMask = 0;
Donut.physicsBody.usesPreciseCollisionDetection = YES;
// Add the Dount to the scene
[self addChild:Donut];
// Here is the Magic
// Run a sequence
[Donut runAction:[SKAction sequence:#[
// Move the Dount and Specify the animation time
[SKAction moveByX:0 y:-(self.size.height + Donut.size.height) duration:5],
// When the Dount is outside the bottom
// The Dount will disappear
[SKAction removeFromParent]]]];
}
You have to set the delegate of your physics world:
self.physicsWorld.contactDelegate = self;
Then, you have a delegate that is called when two objects contact :
- (void)didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
(secondBody.categoryBitMask & monsterCategory) != 0)
{
//remove the donut and the target
SKSpriteNode *firstNode = (SKSpriteNode *) firstBody.node;
SKSpriteNode *secondNode = (SKSpriteNode *) secondBody.node;
[firstNode removeFromParent];
[secondNode removeFromParent];
}
}
For more information you can jump to the collision part in this tutorial.

Sprite Kit collisions for multiple collisions

I have looked, and have found answers for single collisions, but I am looking for a way to detect more than one type of collision. I am making a game where there are 3 collisions I would like. The user plane colliding with enemy bullets, the user's bullet colliding with the enemy plane (which i have working already), and the enemy bullet and user bullet colliding. I have all the categoryBitMask and contactTestBitMask set up and correct. Here is my delegate method.
- (void) didBeginContact:(SKPhysicsContact *)contact {
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// if user plane hits enemy bullet
if ((firstBody.categoryBitMask == playerShipCategory) &&
(secondBody.categoryBitMask == enemyBulletCategory)) {
[self takeDamageByAmount:POINT_INCREMENTER];
[_enemyBullet removeFromParent];
SKAction *bounce = [SKAction sequence:#[
[SKAction fadeAlphaTo:.5 duration:.2],
[SKAction fadeAlphaTo:1.0 duration:.2],
[SKAction fadeAlphaTo:.5 duration:.2],
[SKAction fadeAlphaTo:1.0 duration:.2]
]];
[_playerPlane runAction:bounce];
}
// if the user bullet hits the enemy bullet
else if ((firstBody.categoryBitMask == bulletCategory) &&
(secondBody.categoryBitMask == enemyBulletCategory)) {
[_enemyBullet removeFromParent];
[_bullet removeFromParent];
}
// if bullet hits enemy ship - THIS ONE WORKS, but none of the others work for some reason
else if ((firstBody.categoryBitMask == bulletCategory) &&
(secondBody.categoryBitMask == enemyShipCategory)) {
[self gainPointsByAmoint:POINT_INCREMENTER];
[self projectile:(SKSpriteNode *)firstBody.node didCollideWithMonster:(SKSpriteNode *)secondBody.node];
}
}
This should work it's already tested and working
//Define the collider Category
typedef NS_ENUM(uint32_t, CollisionType) {
enemyShipCategory = 0x1 << 0,
enemyBulletCategory = 0x1 << 1,
playerShipCategory = 0x1 << 2,
bulletCategory = 0x1 << 3,
};
// Set the category that this physics body belongs to
// and specify which categories of bodies cause intersection
// notifications with this physics body
ship.physicsBody.categoryBitMask = playerShipCategory;
ship.physicsBody.contactTestBitMask = enemyBulletCategory;
shipBullet.physicsBody.categoryBitMask = bulletCategory;
shipBullet.physicsBody.contactTestBitMask = enemyShipCategory | enemyBulletCategory;
enemy.physicsBody.categoryBitMask = enemyShipCategory;
enemy.physicsBody.contactTestBitMask = bulletCategory;
enemyBullet.PhysicsBody.categoryBitMask = enemyBulletCategory;
enemyBullet.physicsBody.contactTestBitMask = bulletCategory;
// And handle Collisions
- (void)didBeginContact:(SKPhysicsContact *)contact {
uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);
if (collision == (playerShipCategory | enemyBulletCategory)) {
SKNode *Ship, *bullet;
if (contact.bodyA.categoryBitMask == playerShipCategory) {
Ship = contact.bodyA.node;
bullet = contact.bodyB.node;
} else {
Ship = contact.bodyB.node;
bullet = contact.bodyA.node;
}
[self takeDamageByAmount:POINT_INCREMENTER];
[bullet removeFromParent];
SKAction *bounce = [SKAction sequence:#[
[SKAction fadeAlphaTo:.5 duration:.2],
[SKAction fadeAlphaTo:1.0 duration:.2],
[SKAction fadeAlphaTo:.5 duration:.2],
[SKAction fadeAlphaTo:1.0 duration:.2]
]];
[Ship runAction:bounce];
}
else if (collision == (bulletCategory | enemyBulletCategory)) {
[contact.bodyA.node removeFromParent];
[contact.bodyB.node removeFromParent];
}
else if (collision == (bulletCategory | enemyShipCategory)) {
SKNode *shipBullet, *enemyShip;
if (contact.bodyA.categoryBitMask == shipBullet) {
shipBullet = contact.bodyA.node;
enemyShip = contact.bodyB.node;
} else {
shipBullet = contact.bodyB.node;
enemyShip = contact.bodyA.node;
}
[self gainPointsByAmoint:POINT_INCREMENTER];
[self projectile:shipBullet didCollideWithMonster:enemyShip];
}
}
Good Luck!!

Resources