无法将子弹图像生成在正确的位置

时间:2014-04-14 00:53:33

标签: sprite-kit

大家好我有这个Sprite Kit加农炮游戏,它完美地工作但有一个问题。如果我将大炮指向一个非常顶部或非常底部,正如你在图像中看到的那样,子弹因为它是从大炮精灵的中心产生的,它清楚地表明子弹是从而不是从大炮的隧道,但从图像的中心,我怎样才能修复这个子弹位置,以便它总是从隧道口产卵。

这是我的代码到目前为止。

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
      CGPoint location = [_Player position];
      UITouch *touch = [touches anyObject];
      CGPoint touchLocation = [touch locationInNode:self.scene];
      bullet = [SKSpriteNode spriteNodeWithImageNamed:@"cannonbullet"];
      bullet.xScale = 0.06;
      bullet.yScale = 0.06;
      bullet.position =  
      CGPointMake(location.x+_Player.zRotation,location.y+_Player.zRotation);
      bullet.zPosition = 0;
      CGPoint offset = rwSub(touchLocation, bullet.position);
      if (offset.x <= 0) return;
      [self addChild:bullet];
      CGPoint direction = rwNormalize(offset);
      CGPoint shootAmount = rwMult(direction, 400);
      CGPoint realDest = rwAdd(shootAmount, bullet.position);
      float velocity = 480.0/1.0;
      float realMoveDuration = self.size.width / velocity;
      SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration];
      SKAction * actionMoveDone = [SKAction removeFromParent];
      [bullet runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
      [self animStarter];
}

正如你在图像中看到的那样,如果大炮没有直射,那么子弹就会从一个非常偏离的位置产生。

enter image description here

1 个答案:

答案 0 :(得分:1)

确保您的大炮桶形精灵图像与图像的中心X轴对齐(参见图片)。如果要复制项目,可以拖出或复制图像。

下面是将大炮旋转到触摸位置并在炮弹达到所需旋转角度后发射炮弹的代码。我认为你仍在使用zombie conga代码,所以为了方便我使用了它的功能。

enter image description here

#import "MyScene.h"

 static inline CGPoint CGPointSubtract(const CGPoint a,
                                  const CGPoint b)
{
     return CGPointMake(a.x - b.x, a.y - b.y);
}

 static inline CGPoint CGPointMultiplyScalar(const CGPoint a,const CGFloat b)
{
    return CGPointMake(a.x * b, a.y * b);
}

 static inline CGFloat CGPointLength(const CGPoint a)
{
    return sqrtf(a.x * a.x + a.y * a.y);
}

 static inline CGPoint CGPointNormalize(const CGPoint a)
{
    CGFloat length = CGPointLength(a);
    return CGPointMake(a.x / length, a.y / length);
}

 static inline CGFloat CGPointToAngle(const CGPoint a)
{
    return atan2f(a.y, a.x);
}

 static inline CGFloat ScalarSign(CGFloat a)
{
    return a >= 0 ? 1 : -1;
}

 static inline CGFloat ScalarShortestAngleBetween(const CGFloat a, const CGFloat b)
{
    CGFloat difference = b - a;
    CGFloat angle = fmodf(difference, M_PI * 2);
    if (angle >= M_PI) {
        angle -= M_PI * 2;
    }
    return angle;
}

 static const float ROTATE_RADIANS_PER_SEC = 4 * M_PI;
 static const float MOVE_POINTS_PER_SEC = 120.0;

@implementation MyScene
{
    SKSpriteNode *cannon;
    NSTimeInterval _lastUpdateTime;
    NSTimeInterval _dt;
    CGPoint _velocity;
    CGPoint _lastTouchLocation;
    BOOL fireCannon;
    CGPoint destination;
}

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        [self createCannon];
        fireCannon = false;
    }
    return self;
}


-(void)createCannon
{
    cannon = [SKSpriteNode spriteNodeWithImageNamed:@"cannon"];
    cannon.position = CGPointMake(self.size.height/2, self.size.width/2);
    [self addChild:cannon];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInNode:self.scene];

    fireCannon = true;
    destination = touchLocation;

    _lastTouchLocation = touchLocation;
    CGPoint offset = CGPointSubtract(touchLocation, cannon.position);

    CGPoint direction = CGPointNormalize(offset);
    _velocity = CGPointMultiplyScalar(direction, MOVE_POINTS_PER_SEC);
}

-(void)update:(CFTimeInterval)currentTime
{
    if (_lastUpdateTime) {
        _dt = currentTime - _lastUpdateTime;
    } else {
        _dt = 0;
    }
    _lastUpdateTime = currentTime;

    [self rotateSprite:cannon toFace:_velocity rotateRadiansPerSec:ROTATE_RADIANS_PER_SEC];
}


- (void)rotateSprite:(SKSpriteNode *)sprite
              toFace:(CGPoint)velocity
  rotateRadiansPerSec:(CGFloat)rotateRadiansPerSec
{
    float targetAngle = CGPointToAngle(velocity);
    float shortest = ScalarShortestAngleBetween(cannon.zRotation, targetAngle);
    float amtToRotate = rotateRadiansPerSec * _dt;
    if (ABS(shortest) < amtToRotate)
    {
        amtToRotate = ABS(shortest);
    }
    sprite.zRotation += ScalarSign(shortest) * amtToRotate;

    if ((ABS(shortest) == amtToRotate) && (fireCannon == true))
    {
        fireCannon = false;
        [self fire:targetAngle];
    }
}

-(void)fire:(float)targetAngle
{

    SKSpriteNode *cannonBall = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(5, 5)];
    cannonBall.position = cannon.position;
    [self addChild:cannonBall];

    int x = cannon.position.x + 1000 * cos(targetAngle);
    int y = cannon.position.y + 1000 * sin(targetAngle);

    [cannonBall runAction:[SKAction moveTo:CGPointMake(x, y) duration:2]];
}

@end