Sprite Kit — игрок движется по экрану с акселерометром

Я программирую игру, используя набор спрайтов, и я написал код акселерометра, и он работает. Но проблема в том, что он не останавливается при нажатии на край экрана, кто-нибудь может мне помочь с этим?
Вот код для игрока:

    -(void)addShip
{
//initalizing spaceship node
ship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
[ship setScale:0.5];
ship.zRotation = - M_PI / 2;

//Adding SpriteKit physicsBody for collision detection
ship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ship.frame.size];
ship.physicsBody.mass = 0.02;
ship.physicsBody.categoryBitMask = shipCategory;
ship.physicsBody.dynamic = YES;
ship.physicsBody.affectedByGravity = NO;
ship.physicsBody.contactTestBitMask = DonutCategory | PizzaCategory | ChocolateCategory | SoftCategory | AppleCategory | GrapeCategory | OrangeCategory | BananaCategory;
ship.physicsBody.collisionBitMask = 0;
ship.physicsBody.usesPreciseCollisionDetection = YES;
ship.name = @"ship";
ship.position = CGPointMake(260,30);
[self addChild:ship];motionManager = [[CMMotionManager alloc] init];
if ([motionManager isAccelerometerAvailable] == YES) {
[motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
withHandler:^(CMAccelerometerData *data, NSError *error)
{
float destX, destY;
float currentX = ship.position.x;
float currentY = ship.position.y;
BOOL shouldMove = NO;

if(data.acceleration.x < -0.25) {  // tilting the device to the right
destX = currentX + (data.acceleration.x * kPlayerSpeed);
destY = currentY;
shouldMove = YES;
} else if (data.acceleration.x > 0.25) {  // tilting the device to the left
destX = currentX + (data.acceleration.x * kPlayerSpeed);
destY = currentY;
shouldMove = YES;
}
if(shouldMove) {
SKAction *action = [SKAction moveTo:CGPointMake(destX, destY) duration:1];
[ship runAction:action];
}
}];
}

}

1

Решение

Вы можете добавить ребра на ваш экран, чтобы физика остановила корабль, когда он достигнет края (сделайте это в методе init):

self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
//Add this to change some behaviour when ship will collide with the screen
//self.physicsBody.friction = 0.0f;

Другой способ — проверить метод обновления, когда корабль касается края экрана, и изменить его местоположение.

// Расширенный

Я полагаю, что moveTo: duration: метод испортит вашу фазу, чтобы исправить это, просто убедитесь, что ваши destX и destX идут больше, чем размер экрана width (height) — размер корабля width (height) и меньше, чем origin x и origin y.

Вы не должны использовать moveTo: duration: метод, вместо этого вы должны применить силу к своему кораблю.
Попробуйте этот код, он немного отличается от вашего, но это гораздо лучший способ для перемещения вашего корабля (игнорируйте код выше):

//Your ship setting
_ship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_ship.frame.size];
_ship.physicsBody.mass = 0.02;
_ship.physicsBody.categoryBitMask = shipCategory;
_ship.physicsBody.dynamic = YES;
_ship.physicsBody.affectedByGravity = NO;

// Edge around the screen
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

//Apply movement (instead of moveTo:duration:)
//Get the accelerometer value
CMAccelerometerData* accelData = _motionManager.accelerometerData;
if (fabs(accelData.acceleration.x) > 0.2) {
// 35 is the value you can play with to make your ship movement feel more natural
[_ship.physicsBody applyForce:CGVectorMake(0.0, 35.0 * data.acceleration.x)];
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]