-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCCParentalControl.m
More file actions
322 lines (261 loc) · 10.8 KB
/
Copy pathCCParentalControl.m
File metadata and controls
322 lines (261 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
//
// CCParentalControl.m
// Myro
//
// Created by Peter Mumford on 25/11/2013.
// Copyright 2013 __MyCompanyName__. All rights reserved.
//
#import "CCParentalControl.h"
#import "NSMutableArray+shuffling.h"
#define kDialogTag 1234
#define kDialogMenuTag 4321
#define kWaitingTime 3
#define kNumberOfItems 4
#define menuPadding 25
#define titleTextY 140
#define menuItemsY 10
#define descriptionTextY 100
// class that implements a black colored layer that will cover the whole screen
// and eats all touches except within the dialog box child
@interface ParentalCoverLayer : CCLayerColor {
}
@end
@implementation ParentalCoverLayer
- (id)init {
self = [super init];
if (self) {
[self initWithColor:ccc4(0,0,0,0)
width:[CCDirector sharedDirector].winSize.width
height:[CCDirector sharedDirector].winSize.height];
self.touchEnabled = YES;
}
return self;
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLocation = [self convertTouchToNodeSpace: touch];
CCNode *dialogBox = [self getChildByTag: kDialogTag];
CCMenu *menu = (CCMenu*)[self getChildByTag:kDialogMenuTag];
CGRect menuRect = CGRectMake(menu.position.x, menu.position.y, menu.contentSize.width, menu.contentSize.height);
if (CGRectContainsPoint(menuRect, touchLocation))
return NO;
return (!CGRectContainsPoint(dialogBox.boundingBox, touchLocation));
}
-(void)registerWithTouchDispatcher
{
CCTouchDispatcher *dispatcher = [[CCDirector sharedDirector] touchDispatcher];
[dispatcher addTargetedDelegate: self
priority: INT_MIN+1
swallowsTouches: YES];
}
-(void)dealloc
{
[super dealloc];
}
@end
@implementation CCParentalControl
@synthesize delegate;
@synthesize coverLayer, dialog;
@synthesize titleText, descriptionText, resultText, menuItems;
@synthesize parentalArr;
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// release objects here before super
[coverLayer release];
[dialog release];
[super dealloc];
}
-(void)loadUIGraphcs
{
// NSString *UIPlist= @"Media/BookResources/UI/ui.plist";
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache addSpriteFramesWithFile:GetFullPath(spriteSheet)];
}
-(void)removeUIGraphcs
{
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache removeSpriteFramesFromFile:GetFullPath(spriteSheet)];
}
-(id)initShowParentalControlOnLayer:(CCLayer *)layer sprite:(NSString*)spriteSheetStr urlLocation:(NSString*)urlStr
{
if((self=[super init]))
{
parentPassedTest=NO;
remainingAttempts=3;
counter=0;
spriteSheet = spriteSheetStr;
returnURL = urlStr;
[self loadUIGraphcs];
NSDictionary *parentalDict = [[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ParentalControl" ofType:@"plist"]] autorelease];
self.parentalArr = [[[NSMutableArray alloc] initWithArray:[parentalDict objectForKey:@"items"]] autorelease];
[self.parentalArr shuffleArray];
self.coverLayer = [[ParentalCoverLayer new] autorelease]; // create the cover layer that "hides" the application in the background
[layer addChild:coverLayer z:INT_MAX-1]; // put to the very top to block application touches
[self.coverLayer runAction:[CCFadeTo actionWithDuration:OBJECTSFADEDURATION opacity:200]]; // smooth fade-in to dim with semi-transparency
CCMenuItemImage *closeBtn = [CCMenuItemImage itemWithNormalSprite:[CCSprite spriteWithSpriteFrameName:@"parental-close.png"] selectedSprite:nil block:^(id sender) {
[self closeParentalControl];
}];
closeBtn.anchorPoint = ccp(0,0);
CCMenu *menu = [CCMenu menuWithItems:closeBtn, nil];
[menu setTag:kDialogMenuTag];
[menu setContentSize:CGSizeMake(closeBtn.contentSize.width, closeBtn.contentSize.height)];
menu.position = ccp(([CCDirector sharedDirector].winSize.width-closeBtn.contentSize.width),[CCDirector sharedDirector].winSize.height-closeBtn.contentSize.height);
[self.coverLayer addChild:menu];
self.dialog = [CCSprite spriteWithSpriteFrameName:@"parental-background.png"];
self.dialog.tag = kDialogTag;
self.dialog.position = ccp(self.coverLayer.contentSize.width/2, self.coverLayer.contentSize.height/2);
self.dialog.scale = 0;
[self setupScreen];
[self.coverLayer addChild:self.dialog];
[dialog runAction:[CCEaseBackOut actionWithAction:[CCScaleTo actionWithDuration:OBJECTSFADEDURATION scale:1.0]]];
}
return self;
}
-(void)setupScreen
{
randomlySelectedItem = arc4random() % 4;
NSString *title = [NSString string];
if (remainingAttempts == 3)
title = @"Are you a grown up?";
else
title = [NSString stringWithFormat:@"You have %@ goes remaining...", [self convertNumberToWords:remainingAttempts], nil];
self.titleText = [CCLabelTTF labelWithString:title fontName:@"Verdana" fontSize:FONTSIZEIPAD];
[self.titleText setColor:ccBLACK];
[self.titleText setPosition:ccp(self.dialog.contentSize.width/2, (self.dialog.contentSize.height-titleTextY) )];
[self.dialog addChild:self.titleText];
NSMutableArray *selectedItemsArr = [[[NSMutableArray alloc] init] autorelease];
for (int i=0; i<4; i++)
{
NSDictionary *dict = [[[NSDictionary alloc] initWithDictionary:[self.parentalArr objectAtIndex:i]] autorelease];
NSString *image = [NSString stringWithFormat:@"%@", [dict objectForKey:@"filename"], nil];
CCMenuItemImageWithTouches *menuItem = [CCMenuItemImageWithTouches itemWithNormalSprite:[CCSprite spriteWithSpriteFrameName:image] selectedSprite:nil target:self selector:@selector(selectedMenuItem:)];
[menuItem setTag:i];
[selectedItemsArr addObject:menuItem];
}
self.menuItems = [CCMenu menuWithArray:selectedItemsArr];
[self.menuItems alignItemsHorizontallyWithPadding:menuPadding];
self.menuItems.position = ccp( self.dialog.contentSize.width/2, ( self.dialog.contentSize.height/2 + menuItemsY ) );
[self.menuItems glowItems];
[self.menuItems setTouchEnabled:YES];
[self.dialog addChild:self.menuItems];
NSDictionary *selectedDict = [[[NSDictionary alloc] initWithDictionary:[self.parentalArr objectAtIndex:randomlySelectedItem]] autorelease];
NSString *selectedName = [NSString stringWithFormat:@"%@", [selectedDict objectForKey:@"name"], nil];
self.descriptionText = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"Touch %@ \nfor 2 seconds...", selectedName, nil] fontName:@"Verdana" fontSize:FONTSIZEIPAD dimensions:CGSizeMake(0, 0) hAlignment:UITextAlignmentCenter];
[self.descriptionText setColor:ccBLACK];
[self.descriptionText setPosition:ccp( self.dialog.contentSize.width/2, (self.dialog.contentSize.height/2-descriptionTextY) )];
[self.dialog addChild:self.descriptionText];
}
-(void)selectedMenuItem:(id)sender
{
CCMenuItemImageWithTouches *selMenuItem = (CCMenuItemImageWithTouches*)sender;
if (selMenuItem.didTimeOut)
{
[self.titleText runAction:[CCFadeOut actionWithDuration:OBJECTSFADEDURATION]];
[self.descriptionText runAction:[CCFadeOut actionWithDuration:OBJECTSFADEDURATION]];
[self.menuItems removeGlowItems];
[self.menuItems setEnabled:NO];
CCMenuItemImageWithTouches *item;
CCARRAY_FOREACH(self.menuItems.children, item)
{
if (item.tag != selMenuItem.tag)
{
[item runAction:[CCSequence actions:
[CCDelayTime actionWithDuration:0.2 * (arc4random()%[self.menuItems.children count])],
[CCEaseBackIn actionWithAction:[CCScaleTo actionWithDuration:OBJECTSFADEDURATION scale:0]],
[CCCallBlock actionWithBlock:^{
[self.menuItems removeChild:item cleanup:YES];
}],
[CCCallFunc actionWithTarget:self selector:@selector(reAlignMenuItems:)],
nil]];
}
}
}
}
-(void)reAlignMenuItems:(id)sender
{
if (counter == 2)
{
[self.menuItems alignItemsHorizontallyWithPadding:menuPadding];
[self showResults];
}
counter++;
}
-(void)showResults
{
CCMenuItemImageWithTouches *selectedItem = [self.menuItems.children objectAtIndex:0];
if (selectedItem.tag == randomlySelectedItem)
{
parentPassedTest = YES;
self.resultText = [CCSprite spriteWithSpriteFrameName:@"parental-well-done.png"];
[self.resultText setPosition:ccp( self.dialog.contentSize.width/2, (self.dialog.contentSize.height-titleTextY) )];
[self.resultText setOpacity:0];
[self.dialog addChild:self.resultText];
[self.resultText runAction:[CCFadeIn actionWithDuration:OBJECTSFADEDURATION]];
[self performSelector:@selector(closeParentalControl) withObject:nil afterDelay:kWaitingTime];
}
else
{
remainingAttempts--;
if (remainingAttempts > 0)
self.resultText = [CCSprite spriteWithSpriteFrameName:@"parental-try-again.png"];
else
self.resultText = [CCSprite spriteWithSpriteFrameName:@"parental-bad-luck.png"];
[self.resultText setPosition:ccp( self.dialog.contentSize.width/2, (self.dialog.contentSize.height-titleTextY) )];
[self.resultText setOpacity:0];
[self.dialog addChild:self.resultText];
[self.resultText runAction:[CCFadeIn actionWithDuration:OBJECTSFADEDURATION]];
[self performSelector:@selector(tryAgain:) withObject:nil afterDelay:kWaitingTime];
}
}
-(void)tryAgain:(id)sender
{
if (remainingAttempts > 0)
{
counter=0;
[self.dialog removeChild:self.titleText cleanup:YES];
[self.dialog removeChild:self.descriptionText cleanup:YES];
[self.dialog removeChild:self.menuItems cleanup:YES];
[self.dialog removeChild:self.resultText cleanup:YES];
[self setupScreen];
}
else
[self closeParentalControl];
}
-(NSString*)convertNumberToWords:(int)number
{
NSString *returnStr = [NSString string];
if (number == 2)
returnStr = @"two";
else if (number == 1)
returnStr = @"one";
return returnStr;
}
-(void)closeParentalControl
{
// A Little Hack - strange but it works!
// This will make sure the device doesn't power down and goes to sleep
[UIApplication sharedApplication].idleTimerDisabled = YES;
[UIApplication sharedApplication].idleTimerDisabled = NO;
// in parallel, fadeout and remove self.coverLayer, self.dialog and then execute block
[self.dialog runAction:[CCSequence actions:
[CCEaseBackIn actionWithAction:[CCScaleTo actionWithDuration:OBJECTSFADEDURATION scale:0.0]],
[CCCallBlock actionWithBlock:^{
[self.dialog removeFromParentAndCleanup:YES];
}],
nil]];
// (note: you can't use CCFadeOut since we don't start at opacity 1!)
[self.coverLayer runAction:[CCSequence actions:
[CCFadeTo actionWithDuration:OBJECTSFADEDURATION opacity:0],
[CCCallBlock actionWithBlock:^{
[self.coverLayer removeFromParentAndCleanup:YES];
[self removeUIGraphcs];
[[CCDirector sharedDirector] purgeCachedData];
[delegate closedParentalControlWithResult:parentPassedTest urlLocation:returnURL];
}],
nil]];
}
+(id)showParentalControl:(CCLayer *)layer sprite:(NSString*)spriteSheetStr urlLocation:(NSString*)urlStr
{
return [[[self alloc]initShowParentalControlOnLayer:(CCLayer *)layer sprite:(NSString*)spriteSheetStr urlLocation:(NSString*)urlStr]autorelease];
}
@end