Created
August 2, 2009 23:05
-
-
Save akisute/160246 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "SimpleAudioEngine.h" | |
#import "TicTacToeScene.h" | |
#import "MenuScene.h" | |
@implementation TicTacToeScene | |
-(id) init | |
{ | |
if(self = [super init]) | |
{ | |
// add background layer | |
CGSize size = [[Director sharedDirector] winSize]; | |
Layer* bg = [ColorLayer layerWithColor:0xffffffff width:size.width height:size.height]; | |
[bg setPosition:ccp(0, 0)]; | |
[self addChild:bg z:0]; | |
// create the game board sprite and add it | |
// CGSize size = [[Director sharedDirector] winSize]; | |
Sprite *board = [Sprite spriteWithFile:@"board.png"]; | |
board.position = ccp(size.width/2, size.height/2); | |
[self addChild:board z:1]; | |
// add menu item (back button) | |
Label *label = [Label labelWithString:@"Back" fontName:@"Helvetica" fontSize:32.0]; | |
[label setRGB:0x00 :0x10 :0x99]; | |
MenuItem *back = [MenuItemLabel itemWithLabel:label target:self selector:@selector(back:)]; | |
Menu *menu = [Menu menuWithItems:back, nil]; | |
[menu alignItemsVertically]; | |
menu.position = ccp(40, 20); | |
[self addChild:menu z:2]; | |
// add game board layer (pieces are placed on here) | |
[self addChild:[TicTacToeLayer node] z:3]; | |
} | |
return self; | |
} | |
- (void)back:(id)sender | |
{ | |
MenuScene* scene = [MenuScene node]; | |
FadeTRTransition *transition = [FadeTRTransition transitionWithDuration:1.0 scene:scene]; | |
[[Director sharedDirector] replaceScene:transition]; | |
} | |
@end | |
@implementation TicTacToeLayer | |
- (id)init | |
{ | |
if(self = [super init]) | |
{ | |
// enable touches and accelerometer | |
isTouchEnabled = YES; | |
isAccelerometerEnabled = YES; | |
// set current turn to maru | |
currentTurn = kCurrentTurnMaru; | |
// set initial accelerometer value | |
lastAccerelometerVector = CGPointZero; | |
} | |
return self; | |
} | |
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
if (touch) | |
{ | |
CGPoint location = [touch locationInView: [touch view]]; | |
CGPoint convertedPoint = [[Director sharedDirector] convertCoordinate:location]; | |
// Create piece sprite and add it with tag "Moving"(According to current turn) | |
Sprite *piece = nil; | |
switch (currentTurn) { | |
case kCurrentTurnMaru: | |
piece = [Sprite spriteWithFile:@"maru.png"]; | |
CCLOG(@"Piece=%p", piece); | |
piece.position = convertedPoint; | |
[self addChild:piece z:0 tag:kPieceMoving]; | |
break; | |
case kCurrentTurnBatu: | |
piece = [Sprite spriteWithFile:@"batu.png"]; | |
CCLOG(@"Piece=%p", piece); | |
piece.position = convertedPoint; | |
[self addChild:piece z:0 tag:kPieceMoving]; | |
break; | |
default: | |
break; | |
} | |
// add particle effect | |
ParticleSystem *particle = [[[ParticleExplosion alloc] init] autorelease]; | |
particle.position = convertedPoint; | |
[self addChild:particle z:100]; | |
// play sound | |
[[SimpleAudioEngine sharedEngine] playEffect:@"bell.aif"]; | |
return kEventHandled; | |
} | |
return kEventIgnored; | |
} | |
- (BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
if (touch) | |
{ | |
CGPoint location = [touch locationInView: [touch view]]; | |
CGPoint convertedPoint = [[Director sharedDirector] convertCoordinate:location]; | |
// move the piece "moving" | |
Sprite *piece = (Sprite *)[self getChildByTag:kPieceMoving]; | |
piece.position = convertedPoint; | |
return kEventHandled; | |
} | |
return kEventIgnored; | |
} | |
- (BOOL)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
if (touch) | |
{ | |
CGPoint location = [touch locationInView: [touch view]]; | |
CGPoint convertedPoint = [[Director sharedDirector] convertCoordinate:location]; | |
// settle the piece "moving" | |
Sprite *piece = (Sprite *)[self getChildByTag:kPieceMoving]; | |
piece.position = convertedPoint; | |
piece.tag = kPieceSettled; | |
// ends current turn, pass to the next player | |
switch (currentTurn) { | |
case kCurrentTurnMaru: | |
currentTurn = kCurrentTurnBatu; | |
break; | |
case kCurrentTurnBatu: | |
currentTurn = kCurrentTurnMaru; | |
break; | |
default: | |
break; | |
} | |
return kEventHandled; | |
} | |
return kEventIgnored; | |
} | |
- (BOOL)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
if (touch) | |
{ | |
// remove the piece "moving". (do not end the current turn) | |
[self removeChildByTag:kPieceMoving cleanup:YES]; | |
return kEventHandled; | |
} | |
return kEventIgnored; | |
} | |
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration | |
{ | |
// create raw vector and converted vector of current accelerometer value | |
CGPoint rawVector = ccp(acceleration.x, acceleration.y); | |
ccDeviceOrientation orientation = [Director sharedDirector].deviceOrientation; | |
CGPoint convertedVector = CGPointZero; | |
switch (orientation) { | |
case CCDeviceOrientationLandscapeRight: | |
convertedVector = ccp((float)rawVector.y, (float)-rawVector.x); | |
break; | |
case CCDeviceOrientationLandscapeLeft: | |
convertedVector = ccp(-(float)rawVector.y, (float)rawVector.x); | |
break; | |
case CCDeviceOrientationPortrait: | |
convertedVector = rawVector; | |
break; | |
case CCDeviceOrientationPortraitUpsideDown: | |
convertedVector = ccp(-(float)rawVector.x, (float)-rawVector.y); | |
break; | |
default: | |
break; | |
} | |
// determine shake gesture | |
float dot = ccpDot(lastAccerelometerVector, convertedVector); | |
float a = ccpLength(lastAccerelometerVector); | |
float b = ccpLength(convertedVector); | |
float cosTheta; | |
// avoiding 0 divide. compairing float value with == is not wise though. | |
if (a * b != 0.0) | |
{ | |
cosTheta = dot / (a*b); | |
} | |
else | |
{ | |
cosTheta = FLT_MAX; | |
} | |
float threshold = cos(CC_DEGREES_TO_RADIANS(120.0)); | |
// detect shake when: | |
// 1. vector angles are greater than 120.0 degrees | |
// 2. and both vectors have lenth of 0.6 | |
if ((cosTheta < threshold) && a > 0.6 && b > 0.6) | |
{ | |
CCLOG(@"cosTheta=%f threshold=%f [shaken!]", cosTheta, threshold); | |
CCLOG(@"vector length: (%f, %f)", a, b); | |
// remove all pieces from the board | |
[self removeAllChildrenWithCleanup:YES]; | |
} | |
// keep current vector for next calculation | |
lastAccerelometerVector = convertedVector; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment