我正在制作一个游戏,我在屏幕底部有一条线,用于向空中发射。它应该像橡皮筋或弹弓。我已经将一些有效的东西一起攻击,但这是一个糟糕的解决方案,我希望有人可以提出另一种方法。我的方法基本上涉及通过在touchesMoved方法期间重复调用draw方法来重绘可变路径。再一次,我知道这是一个糟糕的做法,对于可怕的代码感到抱歉。
-(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;
}
我希望有更好的方法可以做到这一点,除了不断重新绘制它,当人们向下拉线以将物体射向空中时。我看着弹簧关节,但无法说服他们工作。我对弹簧接头的另一个问题是如何使图像拉伸以匹配线应该在哪里。这种方法通过简单地消除图像来解决尝试拉伸图像的问题。使用弹簧会很好,这样我就可以避免手工编写物理代码。
有人想过如何做到这一点吗?
答案 0 :(得分:1)
我不确定你是否关心如何在屏幕上画出令人信服的弹性乐队,或者如何模仿一个人的物理特性。如果它是前者我无法帮助你,但如果它是后者你可以尝试这样的东西!您应该可以将其复制并粘贴到现有的精灵工具包应用中,然后对其进行初始化,然后使用它来调用SKView
presentScene:
。
(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.0
和dy = -100.0
,则可以使用applyImpulse:CGVectorMake(-dx, -dy)
向上和向右启动它。但是,使用弹簧接头会为您提供一些加速度。