对于我的程序,我需要使用移动的触摸和SKShapeNode绘制一条线并为其提供碰撞属性。
我看了一下这个帖子:draw a line in sprite kit in touchesmoved画了一条线,但我很难把它变成一个物理体。
我想要完成的是通过用户绘制的道路从上方和下方驾驶汽车。因此,我试图让汽车接触线并沿着它移动......从技术上讲,汽车不会移动,因为只有背景移动。
我将如何做到这一点?
以下是我的代码的重要部分:
我已经制作了3个类(GameHelper,StartGame和GameOver),但它们与我的问题无关。这里是我声明了一个名为pathToDraw的CGMutablePathRef和一个名为lineNode的SKShapeNode。
#import "MyScene.h"
#import "MyScene.h"
#import "StartGameLayer.h"
#import "GameOverLayer.h"
#define TIME 1.5
#define MINIMUM_ROCK_HEIGHT 200.0f
#define GAP_BETWEEN_TOP_AND_BOTTOM_ROCK 50.0f
#define BACKGROUND_Z_POSITION 100
#define START_GAME_LAYER_Z_POSITION 150
#define GAME_OVER_LAYER_Z_POSITION 200
static const uint32_t rockCategory = 0x1 << 0;
static const uint32_t mineCartCategory = 0x1 << 1;
static const uint32_t lineCategory = 0x1 << 1;
static const float BG_VELOCITY = (TIME * 60);
static inline CGPoint CGPointAdd(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);
}
@interface MyScene() <SKPhysicsContactDelegate, StartGameLayerDelegate, GameOverLayerDelegate>
{
NSTimeInterval _dt;
float bottomScrollerHeight;
BOOL _gameStarted;
BOOL _gameOver;
CGMutablePathRef pathToDraw;
SKShapeNode *lineNode;
StartGameLayer* _startGameLayer;
GameOverLayer* _gameOverLayer;
int _score;
}
@property (nonatomic) SKSpriteNode* backgroundImageNode;
@property (nonatomic) SKSpriteNode* mineCart;
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
@property (nonatomic) NSArray* mineCartFrames;
@end
然后这是我的代码画线:
#pragma mark - Touches
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch* touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
lineNode = [SKShapeNode node];
lineNode.path = pathToDraw;
lineNode.strokeColor = [SKColor redColor];
lineNode.zPosition = 125;
lineNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:lineNode.path];
lineNode.physicsBody.categoryBitMask = lineCategory;
lineNode.physicsBody.contactTestBitMask = mineCartCategory;
lineNode.physicsBody.collisionBitMask = 0;
lineNode.physicsBody.affectedByGravity = NO;
[self addChild:lineNode];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch* touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
lineNode.path = pathToDraw;
}
这里我试图让lineNode成为一个物理实体,但是当我运行它时,碰撞并不起作用。 (它运行没有错误)
下面是碰撞代码:
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & rockCategory) != 0 &&
(secondBody.categoryBitMask & mineCartCategory) != 0)
{
[self rock:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
}
else if ((firstBody.categoryBitMask & lineCategory) != 0 &&
(secondBody.categoryBitMask & mineCartCategory) != 0)
{
[self line:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
}
}
答案 0 :(得分:0)
尝试制作具有一定宽度的闭合路径,例如:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
...
pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, 0, 0);
CGPathAddLineToPoint(pathToDraw, NULL, 1, 0);
...
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
...
CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
CGPathAddLineToPoint(pathToDraw, NULL, 0, 0);
lineNode.path = pathToDraw;
}
答案 1 :(得分:0)
你应该在
之后添加物理体- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
你做的是在用户触摸的第一点开始添加一个物理体,这不是你想要的。