我正在创造一个非常简单的轮盘游戏。没有物理参与。表盘绕着彩色的方向盘旋转,必须使表盘停在正确的颜色上。如果它们停在正确的颜色上,则表盘会以相反的方向旋转一个新颜色,以便它们匹配。我正在使用" intersectsNode"在边界线上检测表盘何时进入车轮的象限并检查其颜色是否正确等。当表盘逆时针旋转时,表盘在接触时正确地与边界线相交。然而,当表盘顺时针旋转时,intersectsNode在它连接之前会被触发三分之一。
相同的代码用于检测逆时针和顺时针以及创建边界线,所以我很困惑为什么它会以一种方式与另一种方式失败。有没有人有任何想法?也许是我不知道的一个错误?我的设置一个明显的问题?
@implementation GameScene {
Sound *sound;
GameModel *gameModel;
SKSpriteNode *wheel, *pin;
float duration;
Direction currentDirection;
int colorCount;
Color currentColor, startingColor, enteringColor;
SKLabelNode *scoreLabel;
}
- (void)didMoveToView:(SKView *)view {
gameModel = [GameModel sharedManager];
self.anchorPoint = CGPointMake(0.5, 0.5);
self.backgroundColor = [SKColor colorWithWhite:0.9 alpha:1.0];
wheel = [SKSpriteNode spriteNodeWithImageNamed:@"wheel"];
[self addChild:wheel];
//wheel.zRotation = SK_DEGREES_TO_RADIANS(-45);
SKSpriteNode *hub = [SKSpriteNode spriteNodeWithImageNamed:@"hub"];
[wheel addChild:hub];
pin = [SKSpriteNode spriteNodeWithImageNamed:@"blue_pin"];
pin.anchorPoint = CGPointMake(0.5, 0);
pin.size = pin.texture.size;
//pin.zRotation = SK_DEGREES_TO_RADIANS(45);
[self addChild:pin];
[self createBoundaryLines];
PushButton *hubButton = [[PushButton alloc] initWithUpImage:@"blank_button" andDownImage:@"blank_button"];
[hubButton setTouchUpInsideTarget:self action:@selector(switchDirection) parent:self];
hubButton.zPosition = 50;
[wheel addChild:hubButton];
[self createScoreLabel];
[self createResetButton];
[self resetGame];
}
- (void)setScore:(int)score {
_score = score;
scoreLabel.text = [NSString stringWithFormat:@"%d", _score];
}
- (void)createBoundaryLines {
//counterclockwise lines
[wheel addChild:[self createLine:@"counterLine" color:[SKColor blueColor] position:CGPointMake(0, wheel.size.height / 2) size:CGSizeMake(1, 150) value:0]];
[wheel addChild:[self createLine:@"counterLine" color:[SKColor yellowColor] position:CGPointMake(wheel.size.width / 2, 0) size:CGSizeMake(150, 1) value:1]];
[wheel addChild:[self createLine:@"counterLine" color:[SKColor greenColor] position:CGPointMake(0, -wheel.size.height / 2) size:CGSizeMake(1, 150) value:2]];
[wheel addChild:[self createLine:@"counterLine" color:[SKColor redColor] position:CGPointMake(-wheel.size.width / 2, 0) size:CGSizeMake(150, 1) value:3]];
//clockwise lines
[wheel addChild:[self createLine:@"clockwiseLine" color:[SKColor yellowColor] position:CGPointMake(1, wheel.size.height / 2) size:CGSizeMake(1, 150) value:1]];
[wheel addChild:[self createLine:@"clockwiseLine" color:[SKColor greenColor] position:CGPointMake(wheel.size.width / 2, 1) size:CGSizeMake(150, 1) value:2]];
[wheel addChild:[self createLine:@"clockwiseLine" color:[SKColor orangeColor] position:CGPointMake(1, -wheel.size.height / 2) size:CGSizeMake(1, 150) value:3]];
[wheel addChild:[self createLine:@"clockwiseLine" color:[SKColor blueColor] position:CGPointMake(-wheel.size.width / 2, 1) size:CGSizeMake(150, 1) value:0]];
}
- (SKSpriteNode *)createLine:(NSString *)name color:(SKColor *)color position:(CGPoint)position size:(CGSize)size value:(int)value {
SKSpriteNode *line = [SKSpriteNode spriteNodeWithColor:color size:size];
line.position = position;
line.name = name;
line.userData = [[NSMutableDictionary alloc] init];
[line.userData setValue:[NSNumber numberWithInt:value] forKey:@"color"];
line.zPosition = 500;
return line;
}
#pragma mark - game methods
- (Color)getRandomColorButNotThisColor:(Color)color {
//recursive method to find unique color other than one currently assigned
Color randomColor = (int)arc4random_uniform(colorCount);
if (randomColor == color)
//same color so try again
return [self getRandomColorButNotThisColor:color];
return randomColor;
}
- (void)switchDirection {
[pin removeAllActions];
//if they are stopping the pin then it is either going to be correct or game over
if (enteringColor != currentColor) {
RLog(@"game over");
return;
}
self.score += 1;
//find a new color for them to match
startingColor = currentColor;
currentColor = [self getRandomColorButNotThisColor:currentColor];
[self changePinToColor:currentColor];
//change direction of the spinning pin
currentDirection = (currentDirection == COUNTERCLOCKWISE) ? CLOCKWISE : COUNTERCLOCKWISE;
[pin runAction:[SKAction rotateByAngle:2 * M_PI * currentDirection duration:duration]];
}
- (void)resetGame {
[pin removeAllActions];
pin.zRotation = 0;
//reset all variables
currentColor = startingColor = BLUE;
[self changePinToColor:currentColor];
self.score = 0;
colorCount = 4;
duration = 5.0;
currentDirection = COUNTERCLOCKWISE;
//pin.zRotation = SK_DEGREES_TO_RADIANS(45);
}
- (void)changePinToColor:(Color)color {
//change the pin color based on the color that they need to match
SKTexture *pinTexture;
switch (color) {
case BLUE:
pinTexture = [SKTexture textureWithImageNamed:@"blue_pin"];
break;
case YELLOW:
pinTexture = [SKTexture textureWithImageNamed:@"yellow_pin"];
break;
case GREEN:
pinTexture = [SKTexture textureWithImageNamed:@"green_pin"];
break;
case RED:
pinTexture = [SKTexture textureWithImageNamed:@"orange_pin"];
break;
default:
break;
}
pin.texture = pinTexture;
}
#pragma mark - game loop methods
- (void)update:(CFTimeInterval)currentTime {
[self checkForCollisions];
}
- (void)checkForCollisions{
if (currentDirection == COUNTERCLOCKWISE) {
[wheel enumerateChildNodesWithName:@"counterLine" usingBlock:^(SKNode *line, BOOL *stop) {
if ([pin intersectsNode:line]) {
int amount = [line.userData[@"color"] intValue];
[line runAction:[gameModel flashRedAction]];
if (amount != enteringColor) {
enteringColor = amount;
RLog(@"entered %@", amount == 0 ? @"blue" : amount == 1 ? @"yellow" : amount == 2 ? @"green" : @"red" );
if (amount == currentColor - 1 || ((currentColor == 0) && amount == colorCount - 1))
RLog(@"game over!");
*stop = YES;
}
}
}];
}
else {
[wheel enumerateChildNodesWithName:@"clockwiseLine" usingBlock:^(SKNode *line, BOOL *stop) {
if ([pin intersectsNode:line]) {
int amount = [line.userData[@"color"] intValue];
[line runAction:[gameModel flashRedAction]];
if (amount != enteringColor) {
enteringColor = amount;
RLog(@"entered %@", amount == 0 ? @"blue" : amount == 1 ? @"yellow" : amount == 2 ? @"green" : @"red" );
if (amount == currentColor + 1 || ((currentColor == colorCount - 1) && amount == 0))
RLog(@"game over!");
*stop = YES;
}
}
}];
}
}
答案 0 :(得分:1)
来自intersectsNode
文档,
如果两个节点的帧相交,则认为它们相交。
节点的帧(即边界框)是
父级坐标系中包含节点内容的矩形...
通过观察引脚旋转时产生的边界框(见视频剪辑),很明显为什么使用intersectsNode
不是确定引脚在方向盘内位置的可靠方法。
或者,您可以通过
直接从zRotation
属性确定引脚的位置
// Make sure angle in [-2pi, 2pi]. It can be a very large number
CGFloat angle = fmod(sprite.zRotation+M_PI_2, 2*M_PI);
// Make sure angle is positive and in [0, 2pi]
angle = angle < 0 ? angle + M_PI*2 : angle;
// Determine which quadrant the pin is in. An integer in [0, 3]
int quadrant = (int)floor(angle/M_PI_2);
此时,“象限”表示引脚的颜色位置,其中0 =黄色,1 =蓝色,2 =橙色,3 =绿色。