user1445205
user1445205

Reputation:

Problems with offsets in portrait mode Cocos2d

I am working on the basis of Ray Wenderlich's tutorial on rotating turrets in Cocos 2d (see here: http://www.raywenderlich.com/25791/rotating-turrets-how-to-make-a-simple-iphone-game-with-cocos2d-2-x-part-2). I need my game to be in portrait mode so I have managed to get the position of the turret correctly:enter image description here

The turret manages to shoot right, but not left. Here is my code:

- (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(160, 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;

}

Thanks for the help!

Upvotes: 1

Views: 334

Answers (3)

Nobosi
Nobosi

Reputation: 1085

This issue here is that you've copy-pasted the math instead of editing it properly for your purposes. There are some assumptions made in Ray's code that rely on you shooting always to the right of the turret instead of up, down, or left.

Here's the math code you should be looking at:

// 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;

Note here that you will have an offset.x less than 0 if the tap location is to the left of the turret, so this is an assumption you took from Ray but did not revise. As gheesse said, for your purposes this should be set to offset.y as you don't want them shooting south of the projectile's original location. But this is only part of the problem here.

// Determine where you wish to shoot the projectile to
int realX = winSize.width + (_nextProjectile.contentSize.width/2);

Here's your other big issue. You did not revise Ray's math for determining where the projectile should go. In Ray's code, his projectile will always end up on a location that is off the screen to the right, so he uses the width of the screen and projectile's size to determine the real location he wants the projectile to go. This is causing your issue since you don't have the assumption that your projectile will always head right - yours will always go up (hint, code similar to this should be used for your realY)

float ratio = (float) offset.y / (float) offset.x;
int realY = (realX * ratio) + _nextProjectile.position.y;

Again, Ray makes assumptions in his math for his game and you haven't corrected it in this realY. Your code has the turret turning in ways that will effect the realX coordinate instead of the realY, which is the coordinate that Ray's always shoot right turret needed to effect.

You need to sit down and re-do the math.

Upvotes: 0

davbryn
davbryn

Reputation: 7176

Did you actually set the application to run in portrait mode or have you just rotated the simulator and repositioned the turret?

If you didn't explicitly set the app to run in portrait your x and y coordinates will be swapped (x will run from the ios button to the top of the phone, not accross as you would expect).

If it is converted properly I have answered this question before :)

Upvotes: 0

gheese
gheese

Reputation: 1210

You are checking x axis instead of Y

// Bail out if you are shooting down or backwards
if (offset.x <= 0) return

;

Upvotes: 2

Related Questions