Reputation: 6172
The problem is that the start and end positions of my projectiles are way off. I have NSLog
'd all the CGPoints
and from what I can see the points being fed into the CCSequence
are correct. But from what Im seeing on the screen says different.
A big clue to whats wrong I think is that if create a new CCSprite and use it like I do the projectile the pathing works.
Here is the addProjectile method on the game level layer (GameLevels:Level1Layer)
-(void)addProjectile:(Projectiles*)projectile
{
NSLog(@"projectile position %@",NSStringFromCGPoint(projectile.position));
NSLog(@"wizard position %@",NSStringFromCGPoint(self.wizardHero.position));
NSLog(@"wizard position worldspace %@",NSStringFromCGPoint([self convertToWorldSpace:self.wizardHero.position]));
NSLog(@"destination position %@",NSStringFromCGPoint(projectile.destination.position));
[self addChild:projectile];
// Determine where we wish to shoot the projectile to
int realX;
CGPoint diff = ccpSub(projectile.destination.position,projectile.position);
if (diff.x > 0)
{
realX = (self.tileMap.mapSize.width * self.tileMap.tileSize.width) +
(projectile.contentSize.width/2);
} else {
realX = -(self.tileMap.mapSize.width * self.tileMap.tileSize.width) -
(projectile.contentSize.width/2);
}
float ratio = (float) diff.y / (float) diff.x;
int realY = ((realX - projectile.position.x) * ratio) + projectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far we're shooting
int offRealX = realX - projectile.position.x;
int offRealY = realY - projectile.position.y;
float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY));
float velocity = 280/1; // 280pixels/1sec
float realMoveDuration = length/velocity;
// Move projectile to actual endpoint
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:@selector(projectileMoveFinished:)];
[projectile runAction:
[CCSequence actionOne:
[CCMoveTo actionWithDuration: realMoveDuration
position: realDest]
two: actionMoveDone]];
[self.projectiles addObject:projectile];
}
and output from those NSLog
statements would be (FYI: the projectile is being added from the self.wizardHero
and thus that is its starting position; destination would be self.redEnemy
):
2013-03-27 10:41:57.295 GridWars[13025:c07] projectile position {105, 178}
2013-03-27 10:41:57.296 GridWars[13025:c07] wizard position {105, 178}
2013-03-27 10:41:57.297 GridWars[13025:c07] wizard position worldspace {105, 178}
2013-03-27 10:41:57.298 GridWars[13025:c07] destination position {299, 174}
2013-03-27 11:34:46.608 GridWars[13344:c07] realDest {650, 166}
2013-03-27 11:34:46.608 GridWars[13344:c07] length 545.132080
2013-03-27 11:34:46.610 GridWars[13344:c07] realMoveDuration 1.946900
I realize that with the super classes I have its a little hard to tell whats going on (kinda why I included the source). Basically though I have three main super classes which are subclassed from CCNode
Projectiles : CCNode
sprite : CCSprite
destination : GameCharacters
damage : int
GameLevels : CCNode
hud : HudLayer
tileMap : CCTMXTiledMap
enemies : NSMutablArray
projectiles : NSMutablArray
GameCharacters : CCNode
hp : int
juice : int
sprite : CCSprite
selectedTargets : NSMutablArray
hostLayer : GameLevels
Then the three classes that actually implement these
BasicProjectile : Projectiles
Level1Layer : GameLevels
WizardHero : GameCharacter
RedEnemy : GameCharacter
Though the problem has slightly evolved I have posted this on the cocos2d forums and received some help, which got me to this point (seeing projectiles, but path is wrong vs not seeing them at all). But its been a few days so Hoping for more help.
GameProjectiles:CCNode
#import "CCNode.h"
//forward declaration because we just need to hold a reference
@class GameCharacters;
@interface GameProjectiles : CCNode
@property(nonatomic, strong) CCSprite * sprite;
@property(nonatomic,strong) GameCharacters * destination;
@property(nonatomic) int damage;
-(id)initWithDestination:(GameCharacters*)Destination;
-(CGSize)contentSize;
@end
#import "GameProjectiles.h"
@implementation GameProjectiles
-(id)initWithDestination:(GameCharacters*)Destination
{
if (self = [super init]) {
_damage = 0;
_destination = Destination;
}
return self;
}
-(CGSize)contentSize{
return self.sprite.contentSize;
}
-(void)setPosition:(CGPoint)position
{
[super setPosition:position];
self.sprite.position = position;
}
@end
BasicProjectile
#import "GameProjectiles.h"
@interface BasicProjectile : GameProjectiles
@end
#import "BasicProjectile.h"
@implementation BasicProjectile
-(id)initWithDestination:(GameCharacters*)Destination
{
if (self = [super init]) {
self.damage = 25;
self.sprite = [CCSprite spriteWithFile:@"Projectile.png"];
[self addChild:self.sprite z:1000 ];
self.destination = Destination;
}
return self;
}
@end
Upvotes: 0
Views: 180
Reputation: 21805
since your projectiles and targets are inside a separate CCNode, their bounding box returns their position inside their parent and not in actual screen coordinates (which you want in your case).
To convert the pos you can do like this
CGPoint targetPos = [basicProjectile.destination.sprite.parent convertToWorldSpace:basicProjectile.destination.sprite.position];
NSLog(@"targetPos %@",NSStringFromCGPoint(targetPos));
CGRect targetRect = [self boundingRectForSprite:basicProjectile.destination.sprite andPos:targetPos];
CGPoint projectilePos = [basicProjectile.sprite.parent convertToWorldSpace:basicProjectile.sprite.position];
NSLog(@"projectilePos %@",NSStringFromCGPoint(projectilePos));
CGRect projectileRect = [self boundingRectForSprite:basicProjectile.destination.sprite andPos:projectilePos];
the boundingRectForSprite
method makes the uses the sprite bounding box and position and then calculates the final rect taking anchor point of (0.5,0.5).
now the targetRect
and projectileRect
are of actual screen coordinates.
Upvotes: 1