2014-05-03 10 views
1

我正在製作一款遊戲,我在屏幕底部劃出一條線,用於將其展開到空中。它應該像橡皮筋或彈弓。我一起黑了一些有用的東西,但這是一個不好的解決方案,我希望有人可以建議另一種方式。我的方式基本上涉及在touchesMoved方法中通過重複調用draw方法重繪可變路徑。再次,我知道這是一種糟糕的做法,所以對於可怕的代碼很抱歉。在spritekit中製作鬆緊帶式彈弓

-(void)drawLine:(CGPoint)location 
{ 
[_powerLine removeFromParent]; 

CGPoint pointTL = CGPointMake(19, 131); 
CGPoint pointTR = CGPointMake(308, 131); 
CGPoint pointBL = CGPointMake(location.x-10, location.y); 
CGPoint pointBR = CGPointMake(location.x+10, location.y); 

UIBezierPath *lineShape = [UIBezierPath bezierPath]; 
[lineShape moveToPoint:pointTL]; 
[lineShape addLineToPoint:pointBL]; 
[lineShape addLineToPoint:pointBR]; 
[lineShape addLineToPoint:pointTR]; 

_powerLine = [SKShapeNode node]; 
_powerLine.path = lineShape.CGPath; 
_powerLine.lineWidth = 2.0; 
_powerLine.strokeColor = [SKColor colorWithRed:0.0 green:0 blue:0 alpha:1]; 

[self addChild:_powerLine]; 

CGMutablePathRef powerLinePath = CGPathCreateMutable(); 
CGPathMoveToPoint(powerLinePath, nil, pointTL.x, pointTL.y); 
CGPathAddLineToPoint(powerLinePath, nil, pointBL.x, pointBL.y); 
CGPathAddLineToPoint(powerLinePath, nil, pointBR.x, pointBR.y); 
CGPathAddLineToPoint(powerLinePath, nil, pointTR.x, pointTR.y); 
_powerLine.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:powerLinePath]; 
_powerLine.physicsBody.categoryBitMask = WFPhysicsCategoryPowerline; 
_lastBR = pointBR; 
_lastBL = pointBL; 
} 

我希望有一個更好的方式比當人拉線下拉到空氣中的拍攝對象了不斷重繪做到這一點其他的。我看着春天的關節,但無法說服他們工作。我與彈簧接頭有關的另一個問題是如何讓圖像伸展以匹配線條應該在的位置。這種方法解決了試圖通過簡單地消除圖像來拉伸圖像。這將是很好的使用彈簧,以便我可以避免必須手動編碼這個物理。

任何人都有想法如何做到這一點?

回答

1

我不確定您是否在擔心如何在屏幕上繪製出令人信服的彈性帶,或者如何模擬其中的物理。如果是前者,我無法幫到你,但如果是後者,你可以嘗試這樣的事情!您應該可以將其複製並粘貼到現有的精靈套件應用中,以便隨身攜帶,只需將其初始化並使用SKViewpresentScene:即可。

(header file) 
#import <SpriteKit/SpriteKit.h> 

@interface SlingScene : SKScene 

@end 

(implementation file) 
#import "SlingScene.h" 

@interface SlingScene() 

@property (nonatomic, strong) SKAction *slingAction; 

@end 

@implementation SlingScene 

- (instancetype)initWithSize:(CGSize)size { 
    self = [super initWithSize:size]; 
    if (self) { 
     CGPoint center = CGPointMake(self.size.width/2.0, self.size.height/2.0); 

     self.slingAction = [SKAction sequence: 
          @[[SKAction waitForDuration:0.1], 
           [SKAction runBlock: 
           ^{ 
            [self.physicsWorld removeAllJoints]; 
           } 
           ]]]; 

     // Create a square, which will be slung by the spring 
     SKSpriteNode *square = 
      [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] 
             size:CGSizeMake(60.0, 60.0)]; 
     square.position = CGPointMake(center.x, center.y - 2*square.size.height); 
     square.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:square.size]; 
     square.physicsBody.collisionBitMask = 0; 
     square.name = @"square"; 

     // Create a post to anchor the square to 
     SKShapeNode *post = [SKShapeNode node]; 
     post.path = CGPathCreateWithEllipseInRect(
       CGRectMake(0.0, 0.0, 60.0, 60.0), NULL); 
     post.fillColor = [SKColor brownColor]; 
     post.strokeColor = [SKColor brownColor]; 
     post.position = CGPointMake(center.x-30.0, center.y-30.0); 
     post.physicsBody = 
      [SKPhysicsBody bodyWithCircleOfRadius:60.0 center:center]; 

     // Give the post a near-infinite mass so the square won't tug at it 
     // and move it around 
     post.physicsBody.mass = 1000000; 
     post.physicsBody.affectedByGravity = NO; 

     // Set their collision bit masks to the same value to allow them to pass 
     // through each other 
     post.physicsBody.collisionBitMask = 0; 
     square.physicsBody.collisionBitMask = 0; 

     // Add them to the scene 
     [self addChild:post]; 
     [self addChild:square]; 

     // Connect them via a spring 
     SKPhysicsJointSpring *spring = 
      [SKPhysicsJointSpring jointWithBodyA:post.physicsBody 
              bodyB:square.physicsBody 
             anchorA:center 
             anchorB:square.position]; 
     spring.damping = 0.4; 
     spring.frequency = 1.0; 
     [self.physicsWorld addJoint:spring]; 

     // Lower gravity from the default {0.0, -9.8} to allow the 
     // square to be slung farther 
     self.physicsWorld.gravity = CGVectorMake(0.0, -4.0); 
    } 
    return self; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    // Move the square to the touch position 
    SKSpriteNode *square = (SKSpriteNode *)[self childNodeWithName:@"square"]; 
    CGPoint location = [[touches anyObject] locationInNode:self]; 
    [square runAction:[SKAction moveTo:location duration:0.1]]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    // Sling the square by 
    // 1. allowing the spring to accelerate it, and 
    // 2. removing the spring altogether 
    [self runAction:self.slingAction]; 
} 

@end 

的另一種方法可能是計算相對於特定點的x和y位置,並在相反的方向上施加的脈衝。例如,如果您發現dx = -100.0dy = -100.0,則可以使用applyImpulse:CGVectorMake(-dx, -dy)將其啓動並正確啓動。但是,使用彈簧接頭可以提高加速度。

+0

啊,這真的很好,可能會讓我朝着正確的方向前進。我沒有具體說明該物體需要着陸在導線上,並且可以再次啓動。想想你穿過場景底部的一根電線,用來在空中發射東西。當他們回來時,他們落在電線上,你可以再次啓動它們。但我認爲如果我使用兩個錨點並設置碰撞位掩碼,這種方法可能會起作用。感謝您爲我寫出了一整塊代碼! – user3453934