objective c - intersectsNode fails when object goes counterclockwise but not clockwise -


i creating simple wheel game. there no physics involved. dial spins around coloured quadrated wheel , must stop dial on correct colour. if stop on correct colour dial spins opposite direction new colour them match. using "intersectsnode" on boundary line detect when dial enters quadrant of wheel , check if right colour etc. when dial spinning counterclockwise dial correctly intersects boundary lines when touches them. when dial spinning clockwise intersectsnode fired third of way before connects.

the same code used detect both counterclockwise , clockwise , creating boundary lines, confused why fail 1 way vs. other. have ideas? bug perhaps not aware of? glaring issue setup?

enter image description here

@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 find unique color other 1 assigned     color randomcolor = (int)arc4random_uniform(colorcount);      if (randomcolor == color)         //same color try again         return [self getrandomcolorbutnotthiscolor:color];      return randomcolor; }  - (void)switchdirection {      [pin removeallactions];      //if stopping pin either going correct or game on     if (enteringcolor != currentcolor) {          rlog(@"game over");         return;     }      self.score += 1;      //find new color them match     startingcolor = currentcolor;     currentcolor = [self getrandomcolorbutnotthiscolor:currentcolor];     [self changepintocolor:currentcolor];      //change direction of 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 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 pin color based on color need 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;                 }             }         }];     } } 

gif showing problem

from intersectsnode documentation,

two nodes considered intersect if frames intersect.

a node's frame (i.e., bounding box)

a rectangle in parent’s coordinate system contains content of node...

by observing resulting bounding box pin rotates (see video clip), becomes clear why using intersectsnode not reliable way determine pin's position within wheel.

enter image description here

alternatively, can determine pin's position directly zrotation property by

// make sure angle in [-2pi, 2pi]. can large number cgfloat angle = fmod(sprite.zrotation+m_pi_2, 2*m_pi); // make sure angle positive , in [0, 2pi] angle = angle < 0 ? angle + m_pi*2 : angle; // determine quadrant pin in. integer in [0, 3] int quadrant =  (int)floor(angle/m_pi_2); 

at point, 'quadrant` indicates color position of pin, 0 = yellow, 1 = blue, 2 = orange, 3 = green.


Comments

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -