Rotating Turrets: How To Make A Simple iPhone Game with Cocos2D 2.X Part 2

Discussion of the official tutorials published on raywenderlich.com. Please only discuss the official tutorials here - for general questions, use the General Discussion forum instead.

Rotating Turrets: How To Make A Simple iPhone Game with Cocos2D 2.X Part 2

Postby rwenderlich » Thu Nov 22, 2012 12:00 pm

This is the official thread to discuss the following blog post: Rotating Turrets: How To Make A Simple iPhone Game with Cocos2D 2.X Part 2
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ray Wenderlich
Blog: http://www.raywenderlich.com
Twitter: http://twitter.com/rwenderlich
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
User avatar
rwenderlich
Team Member
Site Admin
 
Posts: 2159
Joined: Thu Dec 23, 2010 4:14 pm
Has thanked: 28 times
Been thanked: 345 times

Re: Rotating Turrets: How To Make A Simple iPhone Game with

Postby tic » Wed Dec 12, 2012 9:51 pm

Hi

I am confused at how the CCSequence for _nextProjectile will not execute until the CCSequence for _player has finished.
Could you clarify?

Thanks
tic
n00b
 
Posts: 1
Joined: Wed Dec 12, 2012 9:49 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Rotating Turrets: How To Make A Simple iPhone Game with

Postby urth » Fri Feb 01, 2013 2:48 am

Thanks for this tutorial.

There is a couple of bugs that I found.

1. If you shoot a projectile with the offset.x <= 0 the next touches do not produce any projectiles since _nextProjectile is not nil. So the if statement should be:

Code: Select all
    // Bail out if you are shooting down or backwards
    if (offset.x <= 0)
    {
        [_nextProjectile release];
        _nextProjectile = nil;
       
        return;
    }


2. The pew pew sound is produced when the projectile is defined not when it is added to the layer. If you shoot a shot in the vertically up then another vertically down you hear the sound before the projectile is fired from the canon. A better placement would be when adding the projectile to the layer:
Code: Select all
         [self addChild:_nextProjectile];
         [_projectiles addObject:_nextProjectile];
         [[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"];


Best regards,

Hussam Kazah
urth
n00b
 
Posts: 3
Joined: Fri Feb 01, 2013 2:37 am
Has thanked: 0 time
Been thanked: 0 time

Re: Rotating Turrets: How To Make A Simple iPhone Game with

Postby akram » Wed Mar 13, 2013 6:01 am

Hai,

Actually this tutorial going for landscape mode for rotating firing Turrets , Once i have designed for portrait mode for iphone then how can i run the touch handles please clarify me once. Send sample code if u have ...

Thanks
akram
n00b
 
Posts: 2
Joined: Tue Mar 12, 2013 6:38 am
Has thanked: 0 time
Been thanked: 0 time

Re: Rotating Turrets: How To Make A Simple iPhone Game with

Postby Erick Beard » Thu Apr 11, 2013 7:55 pm

I am trying to modify the code so that I can position a rotating turret at the bottom center of the screen. The positioning went fine for the sprite and the starting position of the bullets, but I am having trouble firing to the left side of the screen. I commented out the section of code for bailing out if shooting down or backwards, unfortunately the turret fires down and to the right when I attempt to shoot on the left side of the screen. I understand this involves the positional coordinates, but I don't know how to fix the problem. If I find a solution before I can get any assistance, then I will post it here.

Code: Select all
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
   
    if (_nextProjectile != nil) return;
   
    // Choose one of the touches to work with
    UITouch *touch = [touches anyObject];
    CGPoint location = [self convertTouchToNodeSpace:touch];
   
    // Set up initial location of projectile
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    _nextProjectile = [[CCSprite spriteWithFile:@"projectile2.png"] retain];
    _nextProjectile.position = ccp(winSize.width/2, 20);
   
    // Determine offset of location to projectile
    CGPoint offset = ccpSub(location, _nextProjectile.position);
   
    // Bail out if you are shooting down or backwards
    //if (offset.x <= 0) return;
   
    // Determine where you wish to shoot the projectile to
    int realX = winSize.width + (_nextProjectile.contentSize.width/2);
    float ratio = (float) offset.y / (float) offset.x;
    int realY = (realX * ratio) + _nextProjectile.position.y;
    CGPoint realDest = ccp(realX, realY);
   
    // Determine the length of how far you're shooting
    int offRealX = realX - _nextProjectile.position.x;
    int offRealY = realY - _nextProjectile.position.y;
    float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
    float velocity = 480/1; // 480pixels/1sec
    float realMoveDuration = length/velocity;
   
    // Determine angle to face
    float angleRadians = atanf((float)offRealY / (float)offRealX);
    float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
    float cocosAngle = -1 * angleDegrees;
    float rotateDegreesPerSecond = 180 / 0.5; // Would take 0.5 seconds to rotate 180 degrees, or half a circle
    float degreesDiff = _player.rotation - cocosAngle;
    float rotateDuration = fabs(degreesDiff / rotateDegreesPerSecond);
    [_player runAction:
     [CCSequence actions:
      [CCRotateTo actionWithDuration:rotateDuration angle:cocosAngle],
      [CCCallBlock actionWithBlock:^{
         // OK to add now - rotation is finished!
         [self addChild:_nextProjectile];
         [_projectiles addObject:_nextProjectile];
         
         // Release
         [_nextProjectile release];
         _nextProjectile = nil;
     }],
      nil]];
   
    // Move projectile to actual endpoint
    [_nextProjectile runAction:
     [CCSequence actions:
      [CCMoveTo actionWithDuration:realMoveDuration position:realDest],
      [CCCallBlockN actionWithBlock:^(CCNode *node) {
         [_projectiles removeObject:node];
         [node removeFromParentAndCleanup:YES];
    }],
      nil]];
   
    _nextProjectile.tag = 2;
   
    [[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"];
}
Erick Beard
n00b
 
Posts: 2
Joined: Sat Mar 09, 2013 8:30 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Rotating Turrets: How To Make A Simple iPhone Game with

Postby xenogear » Sun Jun 30, 2013 5:04 am

@Erick, the reason is because of how the arctangent function is defined. To be mathy about it, the range of arctangent is (-pi/2, pi/2).

To be less mathy about it, this means that atanf will give you something to the top-right of the turret (Quadrant I), something to the bottom-right of the turret (Quadrant IV), or something directly to the right of the turret, which is not in any quadrant. These are the only three possibilities. But what you want is something to the top-left of the turret (Quadrant II). The way to achieve this is by putting the following code right after the definition of angleRadians:

Code: Select all
if (angleRadians < 0)
    angleRadians = M_PI + angleRadians;


This adds the value of pi (3.14159...) to angleRadians, thus rotating the turret in the proper direction.

But we still need to take care of the bullets. Replace the 4 lines of code under the comment "Determine where you wish to shoot the projectile to" with the following lines:

Code: Select all
int realX, realY;
if (offset.x == 0) {  // tapped directly above the turret
    realX = location.x;
    realY = winSize.height + _nextProjectile.contentSize.height/2;
}
else if (offset.x >= 0) {  // tapped right of the turret
    float ratio = ((float) offset.y) / ((float) offset.x);
    realX = winSize.width + _nextProjectile.contentSize.width/2;
    realY = realX * ratio + _nextProjectile.position.y;
}
else {  // tapped left of the turret
    float ratio = - ((float) location.y) / ((float) location.x);
    realX = -_nextProjectile.contentSize.width/2;
    realY = location.y + ratio * (realX - location.x);
}
CGPoint realDest = ccp(realX, realY);


Note that the last line remains unchanged. I know that could be a little more slick, but I set it up like that to clearly and completely separate the cases.
xenogear
n00b
 
Posts: 1
Joined: Sun Jun 30, 2013 3:06 am
Has thanked: 0 time
Been thanked: 0 time

Postby jookjah » Mon Dec 23, 2013 9:45 pm

I am just wondering how does the _nextprojectile sprite run its action after it has been released from memory in the whole [_player runAction:... ]method where we release the _nextProjectile with the line [_nextProjectile release] and set it to nil?

Doesn't this mean the projectile no longer exists after we shoot it? So how can it run the [_nextproject runaction...] method? Not sure if I am making sense. If anyone could answer this , much would be appreciated.
jookjah
n00b
 
Posts: 4
Joined: Wed Dec 18, 2013 5:23 pm
Has thanked: 0 time
Been thanked: 0 time

Postby rayjan » Thu Jan 09, 2014 7:16 am

Hi so does this turret going to do a 360 degree rotation then? i havent finished this tutorial yet.
rayjan
Hacker
 
Posts: 32
Joined: Wed Jan 08, 2014 10:37 pm
Has thanked: 4 times
Been thanked: 0 time


Return to Official Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests