我试图使车辆(在这种情况下,火车)移动基于球员的输入。如果我通过SKAction来移动火车,车轮就不会转动。我可以在它的物理体上使用applyForce方法,但我需要更多的控制。我需要让它在一定的时间内移动一定的距离。如何才能做到这一点?
-(void)didMoveToView:(SKView *)view {
SKTexture *trainBodyTexture = [SKTexture textureWithImageNamed:@"levelselect_trainbody"];
SKSpriteNode *trainBody = [[SKSpriteNode alloc] initWithTexture:trainBodyTexture];
trainBody.zPosition = 0;
trainBody.position = CGPointMake(300, 500);
trainBody.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:trainBody.size];
[self addChild:trainBody];
SKTexture *trainWheelTexture = [SKTexture textureWithImageNamed:@"levelselect_trainwheel"];
SKSpriteNode *trainWheel1 = [[SKSpriteNode alloc] initWithTexture:trainWheelTexture];
trainWheel1.zPosition = 1;
trainWheel1.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:trainWheel1.size.width/2];
trainWheel1.physicsBody.allowsRotation = YES;
trainWheel1.position = CGPointMake(220, 400);
[self addChild:trainWheel1];
SKSpriteNode *trainWheel2 = [[SKSpriteNode alloc] initWithTexture:trainWheelTexture];
trainWheel2.zPosition = 1;
trainWheel2.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:trainWheel2.size.width/2];
trainWheel2.physicsBody.allowsRotation = YES;
trainWheel2.position = CGPointMake(380, 400);
[self addChild:trainWheel2];
SKShapeNode *dot = [SKShapeNode shapeNodeWithCircleOfRadius:10];
dot.zPosition = 2;
dot.fillColor = [NSColor redColor];
dot.position = CGPointMake(0, -20);
[trainWheel1 addChild:dot];
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:trainBody.physicsBody bodyB:trainWheel1.physicsBody anchor:trainWheel1.position];
SKPhysicsJointPin *pin2 = [SKPhysicsJointPin jointWithBodyA:trainBody.physicsBody bodyB:trainWheel2.physicsBody anchor:trainWheel2.position];
[self.scene.physicsWorld addJoint:pin];
[self.scene.physicsWorld addJoint:pin2];
//[trainWheel1 runAction:[SKAction moveByX:300 y:0 duration:3]];
[trainBody.physicsBody applyForce:CGVectorMake(3000, 0)];
}更新:用列车级( Jaffer建议)实现
Train.h
#import <SpriteKit/SpriteKit.h>
@interface Train : SKSpriteNode
-(void) createPhysics;
-(void) moveLeft;
-(void) moveRight;
@endTrain.m
#import "Train.h"
@interface Train()
@property SKSpriteNode *trainBody, *trainWheelFront, *trainWheelRear;
@property SKPhysicsWorld *physicsWorld;
@end
@implementation Train
-(instancetype) init {
if (self = [super init]) {
[self initTrainBody];
[self initWheels];
}
return self;
}
-(void) initTrainBody {
SKTexture *trainBodyTexture = [SKTexture textureWithImageNamed:@"levelselect_trainbody"];
_trainBody = [[SKSpriteNode alloc] initWithTexture:trainBodyTexture];
_trainBody.zPosition = 0;
_trainBody.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_trainBody.size];
[self addChild:_trainBody];
}
-(void) initWheels {
SKTexture *_trainWheelTexture = [SKTexture textureWithImageNamed:@"levelselect_trainwheel"];
_trainWheelFront = [[SKSpriteNode alloc] initWithTexture:_trainWheelTexture];
_trainWheelFront.zPosition = 1;
_trainWheelFront.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_trainWheelFront.size.width/2];
_trainWheelFront.physicsBody.allowsRotation = YES;
_trainWheelFront.position = CGPointMake(-80, -82);
[self addChild:_trainWheelFront];
_trainWheelRear = [[SKSpriteNode alloc] initWithTexture:_trainWheelTexture];
_trainWheelRear.zPosition = 1;
_trainWheelRear.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_trainWheelRear.size.width/2];
_trainWheelRear.physicsBody.allowsRotation = YES;
_trainWheelRear.position = CGPointMake(80, -82);
[self addChild:_trainWheelRear];
//dot used to see if wheels are rotating, no other point
SKShapeNode *dot = [SKShapeNode shapeNodeWithCircleOfRadius:10];
dot.zPosition = 2;
dot.fillColor = [NSColor redColor];
dot.position = CGPointMake(0, -20);
[_trainWheelFront addChild:dot];
}
//this method is called after the train node is added to the scene in GameScene otherwise will get error adding joints before node is in scene
-(void) createPhysics {
SKPhysicsJointPin *pin = [SKPhysicsJointPin jointWithBodyA:_trainBody.physicsBody bodyB:_trainWheelFront.physicsBody anchor:_trainWheelFront.position];
SKPhysicsJointPin *pin2 = [SKPhysicsJointPin jointWithBodyA:_trainBody.physicsBody bodyB:_trainWheelRear.physicsBody anchor:_trainWheelRear.position];
[self.scene.physicsWorld addJoint:pin];
[self.scene.physicsWorld addJoint:pin2];
}
-(void) moveLeft {
SKAction *rotateLeft = [SKAction rotateByAngle:6*M_PI duration:0.2];
[_trainWheelFront runAction:rotateLeft];
[_trainWheelRear runAction:rotateLeft];
}
-(void) moveRight {
SKAction *rotateRight = [SKAction rotateByAngle:-6*M_PI duration:0.2];
[_trainWheelFront runAction:rotateRight];
[_trainWheelRear runAction:rotateRight];
}
@endGameScene.m
#import "GameScene.h"
#import "Train.h"
@interface GameScene()
@property Train *train;
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view {
[self initTrain];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name:@"KeyPressedNotificationKey" object:nil]; //using notifications and custom view class to handle key presses
}
-(void) initTrain {
_train = [[Train alloc] init];
_train.position = CGPointMake(500, 300);
[self addChild:_train];
[_train createPhysics];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
-(void) keyPressed:(NSNotification*)notification {
NSNumber *keyCodeObject = notification.userInfo[@"keyCode"];
NSInteger keyCode = keyCodeObject.integerValue;
NSLog(@"keycode = %lu", keyCode);
switch (keyCode) {
case 123:
[self leftArrowPressed];
break;
case 124:
[self rightArrowPressed];
break;
}
}
-(void) leftArrowPressed {
SKAction *moveLeft = [SKAction moveByX:-200 y:0 duration:0.2];
[_train runAction:moveLeft];
[_train moveLeft];
}
-(void) rightArrowPressed {
SKAction *moveRight = [SKAction moveByX:200 y:0 duration:0.2];
[_train runAction:moveRight];
[_train moveRight];
}
@end注意:当左右键被按下时,这个解决方案会导致整个列车翻转和抓狂。我的针关节似乎不正确,但在我看来是正确的。
发布于 2015-08-13 07:46:40
SkSpriteNode的默认初始化程序是- (instancetype)initWithTexture:(SKTexture *)texture color:(SKColor *)color size:(CGSize)size;请尝试
@interface Train : SKSpriteNode
- (instancetype)initTrainWithColor:(UIColor *) color andSize:(CGSize) size;
-(void) animateWheelsWithTime:(float) time;
@end
@interface Train ()
{
SKSpriteNode *wheel1;
SKSpriteNode *wheel2;
NSMutableArray *wheelsArray;
}
@end
@implementation Train
- (instancetype)initTrainWithColor:(UIColor *) color andSize:(CGSize) size
{
self = [super initWithTexture:nil color:color size:size];
if (self)
{
[self addWheels];
}
return self;
}
-(void)addWheels
{
wheelsArray = [[NSMutableArray alloc]init];
wheel1 = [SKSpriteNode spriteNodeWithImageNamed:@"wheel"];
[wheel1 setPosition:CGPointMake(-(self.frame.size.width/2.0f-wheel1.frame.size.width/2.0f), - (self.frame.size.height/2.0f - wheel1.frame.size.height/2.0f))];
[self addChild:wheel1];
wheel2 = [SKSpriteNode spriteNodeWithImageNamed:@"wheel"];
[wheel2 setPosition:CGPointMake((self.frame.size.width/2.0f-wheel2.frame.size.width/2.0f), - (self.frame.size.height/2.0f - wheel2.frame.size.height/2.0f))];
[self addChild:wheel2];
[wheelsArray addObject:wheel1];
[wheelsArray addObject:wheel2];
}
-(void) animateWheelsWithTime:(float) time
{
for (SKSpriteNode *wheel in wheelsArray)
{
SKAction *act = [SKAction rotateByAngle:3*M_PI duration:time];
[wheel runAction:act];
}
}
@end在GameScene.m添加这样的火车,
-(void) addTrain
{
Train *train1 = [[Train alloc]initTrainWithColor:[UIColor yellowColor] andSize:CGSizeMake(150, 100)];
[train1 setPosition:CGPointMake(self.size.width/2.0f, self.size.height/2.0f)];
[self addChild:train1];
SKAction *act = [SKAction moveTo:CGPointMake(self.size.width/2.0f, self.size.height - 50) duration:2];
[train1 runAction:act];
[train1 animateWheelsWithTime:2];
}我试过了而且成功了。
https://stackoverflow.com/questions/31955346
复制相似问题