0

ソースはこちら

問題は、発射物の開始位置と終了位置がずれていることです。私はNSLogすべてを調べましたが、そこに供給されているポイントが正しいCGPointsことがわかります。CCSequenceしかし、画面に表示されているものとは異なります。

私が考えている問題の大きな手がかりは、新しい CCSprite を作成し、それを発射体のように使用すると、パスが機能することです。

これは、ゲーム レベル レイヤー (GameLevels:Level1Layer) の addProjectile メソッドです。

-(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];
}

これらのステートメントからの出力はNSLog次のようになります (FYI: 発射体は から追加されているself.wizardHeroため、それが開始位置です。目的地は になりますself.redEnemy):

2013-03-27 10:41:57.295 GridWars[13025:c07] 発射体の位置 {105, 178}

2013-03-27 10:41:57.296 GridWars[13025:c07] ウィザードの位置 {105, 178}

2013-03-27 10:41:57.297 GridWars[13025:c07] ウィザード位置ワールドスペース {105, 178}

2013-03-27 10:41:57.298 GridWars[13025:c07] 宛先位置 {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] 長さ 545.132080

2013-03-27 11:34:46.610 GridWars[13344:c07] realMoveDuration 1.946900

スーパークラスでは、何が起こっているのかを伝えるのが少し難しいことに気付きました (なぜソースを含めたのか)。基本的には、サブクラス化された3つの主要なスーパークラスがありますが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

次に、これらを実際に実装する 3 つのクラス

        BasicProjectile : Projectiles
        Level1Layer : GameLevels
        WizardHero : GameCharacter
        RedEnemy : GameCharacter

問題は少し進展しましたが、私はこれをcocos2d フォーラムに投稿し、いくつかの助けを受け取りました。しかし、それから数日が経ちましたので、さらに助けを求めています。

GameProjectile: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

基本発射物

#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
4

1 に答える 1

1

発射体とターゲットは別の CCNode 内にあるため、それらの境界ボックスは、実際の画面座標ではなく、親内の位置を返します (この場合はこれが必要です)。

位置を変換するには、このようにすることができます

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

このboundingRectForSpriteメソッドは、スプライトのバウンディング ボックスと位置を使用し、(0.5,0.5) のアンカー ポイントを取得する最終的な四角形を計算します。

targetRectとはprojectileRect実際の画面座標です。

于 2013-03-28T15:36:37.253 に答える