如何检测碰撞是精灵套件?它需要使用我已经存在的代码,因为我尝试了一种方法,但它失败了。游戏目前有一枚从天空坠落的导弹,太空船必须躲避它们,我想要它,如果它们发生碰撞就会失去生命。这是我的代码
static const uint32_t shipCategory = 0x1 << 1;
static const uint32_t obstacleCategory = 0x1 << 1;
@implementation MyScene{
SKSpriteNode *ship;
SKSpriteNode *missile;
int score;
int HighScore;
SKAction *actionMoveRight;
SKAction *actionMoveLeft;
SKLabelNode *label;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor whiteColor];
[self addShip];
//Making self delegate of physics World
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
//score
score = 5;
label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
label.text = [NSString stringWithFormat:@"%d",score];
label.fontSize = 40;
label.fontColor = [SKColor blackColor];
label.position = CGPointMake(self.size.width/2, self.size.height/2);
[self addChild:label];
//highscore
HighScore = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScore"];
label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
label.text = [NSString stringWithFormat:@"%d",HighScore];
label.fontSize = 40;
label.fontColor = [SKColor blackColor];
label.position = CGPointMake(self.size.width/1, self.size.height/2);
[self addChild:label];
}
return self;
}
-(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.size];
ship.physicsBody.categoryBitMask = shipCategory;
ship.physicsBody.dynamic = YES;
ship.physicsBody.contactTestBitMask = obstacleCategory;
ship.physicsBody.collisionBitMask = 0;
ship.physicsBody.usesPreciseCollisionDetection = YES;
ship.name = @"ship";
ship.position = CGPointMake(260,30);
actionMoveRight = [SKAction moveByX:-30 y:0 duration:.2];
actionMoveLeft = [SKAction moveByX:30 y:0 duration:.2];
[self addChild:ship];
}
- (void)shootMissile
{
// Sprite Kit knows that we are working with images so we don't need to pass the image’s extension
missile = [SKSpriteNode spriteNodeWithImageNamed:@"red-missile"];
[missile setScale:0.15];
// Position the missile outside the top
int r = arc4random() % 200;
missile.position = CGPointMake(20 + r, self.size.height + missile.size.height/2);
// Add the missile to the scene
[self addChild:missile];
// Here is the Magic
// Run a sequence
[missile runAction:[SKAction sequence:@[
// Move the missile and Specify the animation time
[SKAction moveByX:0 y:-(self.size.height + missile.size.height) duration:5],
// When the missile is outside the bottom
// The missile will disappear
[SKAction removeFromParent]
]
]];
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 5) {
self.lastSpawnTimeInterval = 0;
[self shootMissile];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
if(touchLocation.x >ship.position.x){
if(ship.position.x < 270){
[ship runAction:actionMoveLeft];
}
}else{
if(ship.position.x > 50){
[ship runAction:actionMoveRight];
}
}
}
- (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 & shipCategory) != 0 &&
(secondBody.categoryBitMask & obstacleCategory) != 0)
{
score ++;
if (score > HighScore) {
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:score] forKey:@"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size];
[self.view presentScene:gameOverScene transition: reveal];
}
}
}
@end
答案 0 :(得分:2)
为missile
添加新类别:
static const uint32_t missileCategory = 0x1 << 2;
为physicsBody
定义missile
:
missile.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:missile.size];
missile.physicsBody.categoryBitMask = missileCategory;
missile.physicsBody.dynamic = YES;
missile.physicsBody.contactTestBitMask = shipCategory;
missile.physicsBody.collisionBitMask = 0;
missile.physicsBody.usesPreciseCollisionDetection = YES;
将此检查添加到didBeginContact
方法:
if ((firstBody.categoryBitMask & shipCategory) != 0 &&
(secondBody.categoryBitMask & missileCategory) != 0)
{
// Do your stuff here
}
以下是修改后的代码:
static const uint32_t shipCategory = 0x1 << 1;
static const uint32_t obstacleCategory = 0x1 << 1;
static const uint32_t missileCategory = 0x1 << 2;
@implementation MyScene{
SKSpriteNode *ship;
SKSpriteNode *missile;
int score;
int HighScore;
SKAction *actionMoveRight;
SKAction *actionMoveLeft;
SKLabelNode *label;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor whiteColor];
[self addShip];
//Making self delegate of physics World
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
//score
score = 5;
label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
label.text = [NSString stringWithFormat:@"%d",score];
label.fontSize = 40;
label.fontColor = [SKColor blackColor];
label.position = CGPointMake(self.size.width/2, self.size.height/2);
[self addChild:label];
//highscore
HighScore = [[NSUserDefaults standardUserDefaults] integerForKey:@"HighScore"];
label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
label.text = [NSString stringWithFormat:@"%d",HighScore];
label.fontSize = 40;
label.fontColor = [SKColor blackColor];
label.position = CGPointMake(self.size.width/1, self.size.height/2);
[self addChild:label];
}
return self;
}
-(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.size];
ship.physicsBody.categoryBitMask = shipCategory;
ship.physicsBody.dynamic = YES;
ship.physicsBody.contactTestBitMask = obstacleCategory | missileCategory;
ship.physicsBody.collisionBitMask = 0;
ship.physicsBody.usesPreciseCollisionDetection = YES;
ship.name = @"ship";
ship.position = CGPointMake(260,30);
actionMoveRight = [SKAction moveByX:-30 y:0 duration:.2];
actionMoveLeft = [SKAction moveByX:30 y:0 duration:.2];
[self addChild:ship];
}
- (void)shootMissile
{
// Sprite Kit knows that we are working with images so we don't need to pass the image’s extension
missile = [SKSpriteNode spriteNodeWithImageNamed:@"red-missile"];
[missile setScale:0.15];
// Position the missile outside the top
int r = arc4random() % 200;
missile.position = CGPointMake(20 + r, self.size.height + missile.size.height/2);
missile.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:missile.size];
missile.physicsBody.categoryBitMask = missileCategory;
missile.physicsBody.dynamic = YES;
missile.physicsBody.contactTestBitMask = shipCategory;
missile.physicsBody.collisionBitMask = 0;
missile.physicsBody.usesPreciseCollisionDetection = YES;
// Add the missile to the scene
[self addChild:missile];
// Here is the Magic
// Run a sequence
[missile runAction:[SKAction sequence:@[
// Move the missile and Specify the animation time
[SKAction moveByX:0 y:-(self.size.height + missile.size.height) duration:5],
// When the missile is outside the bottom
// The missile will disappear
[SKAction removeFromParent]
]
]];
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 5) {
self.lastSpawnTimeInterval = 0;
[self shootMissile];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
if(touchLocation.x >ship.position.x){
if(ship.position.x < 270){
[ship runAction:actionMoveLeft];
}
}else{
if(ship.position.x > 50){
[ship runAction:actionMoveRight];
}
}
}
- (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 & shipCategory) != 0 &&
(secondBody.categoryBitMask & obstacleCategory) != 0)
{
score ++;
if (score > HighScore) {
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:score] forKey:@"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size];
[self.view presentScene:gameOverScene transition: reveal];
}
}
if ((firstBody.categoryBitMask & shipCategory) != 0 &&
(secondBody.categoryBitMask & missileCategory) != 0)
{
// Do your stuff here
}
}
@end