From 2b79059b6c5db9c53caa607c68b6e30ef52dfa40 Mon Sep 17 00:00:00 2001 From: dsc Date: Mon, 6 Jun 2011 06:23:56 -0700 Subject: [PATCH] Minor reorg of unit crap. --- src/Tanks.h | 8 ++- src/TanksMacros.h | 3 + src/game/QQActive.h | 12 +++- src/game/QQDisplayable.h | 2 +- src/game/QQGame.h | 9 ++- src/game/QQGame.mm | 31 ++++++---- src/game/QQPhysical.h | 15 +++-- src/game/QQThing.h | 2 +- src/game/ability/QQCooldown.h | 15 +++-- src/game/ability/QQCooldown.mm | 34 +++++++--- src/game/unit/QQActor.h | 20 ++++-- src/game/unit/QQActor.mm | 112 +++++++++++++++++++++------------- src/game/unit/QQBullet.h | 1 + src/game/unit/QQBullet.mm | 4 +- src/game/unit/QQTank.h | 4 +- src/game/unit/QQTank.mm | 19 +------ src/game/unit/QQUnit.h | 9 ++- src/game/unit/QQUnit.mm | 22 ++++++- src/qq/NSArray+QQExtensions.h | 6 ++ src/qq/NSArray+QQExtensions.mm | 12 ++++ src/qq/NSDictionary+QQExtensions.h | 8 +++ src/qq/NSDictionary+QQExtensions.mm | 27 ++++++++ src/qq/NSSet+QQExtensions.h | 1 + src/qq/NSSet+QQExtensions.mm | 7 ++ src/qq/event/QQNotificationCenter.h | 6 +- src/qq/event/QQNotificationCenter.mm | 15 ++++- src/qq/event/QQNotificationProxy.h | 6 ++- src/qq/event/QQNotificationProxy.mm | 26 ++++++--- src/qq/event/QQNotifier.h | 11 +++- src/qq/event/QQNotifiers.h | 40 ------------ src/qq/event/QQObservable.h | 2 - tanks.xcodeproj/project.pbxproj | 20 ++++++- 32 files changed, 331 insertions(+), 178 deletions(-) create mode 100644 src/qq/Collections+FP.h create mode 100644 src/qq/Collections+FP.mm create mode 100644 src/qq/NSArray+QQExtensions.h create mode 100644 src/qq/NSArray+QQExtensions.mm create mode 100644 src/qq/NSDictionary+QQExtensions.h create mode 100644 src/qq/NSDictionary+QQExtensions.mm diff --git a/src/Tanks.h b/src/Tanks.h index a2a448b..6246017 100644 --- a/src/Tanks.h +++ b/src/Tanks.h @@ -1,14 +1,20 @@ #ifndef TANKS_H #define TANKS_H + #ifdef DEBUG #define TANKS_DEBUG_LOG 1 -#else + +#else // DEBUG #define TANKS_DEBUG_LOG 0 + #endif // DEBUG + #endif // TANKS_H #import "TanksMacros.h" +#import "qq/NSArray+QQExtensions.h" +#import "qq/NSDictionary+QQExtensions.h" #import "qq/NSSet+QQExtensions.h" #import "render/QQSparrowExtensions.h" diff --git a/src/TanksMacros.h b/src/TanksMacros.h index b36a57c..b2c9fd0 100644 --- a/src/TanksMacros.h +++ b/src/TanksMacros.h @@ -4,4 +4,7 @@ #define b2s(__val) ((__val)?("YES"):("NO")) +#define ATTACK_COOLDOWN_NAME @"attack" + + #endif \ No newline at end of file diff --git a/src/game/QQActive.h b/src/game/QQActive.h index 4bc669b..eba0aed 100644 --- a/src/game/QQActive.h +++ b/src/game/QQActive.h @@ -1,16 +1,22 @@ #import "game/QQGameTime.h" #import "game/QQThing.h" +#import "game/ability/QQCooldown.h" + /** * Anything that takes a turn is QQActive. */ @protocol QQActive -@property (nonatomic, readwrite, getter=isActive) BOOL active; -// @property (nonatomic, readwrite, getter=isSleeping) BOOL sleeping; -@property (nonatomic, readwrite, retain) NSArray* cooldowns; +@property (nonatomic, readwrite, getter=isActive) BOOL active; +@property (nonatomic, readwrite, getter=isSleeping) BOOL sleeping; + +@property (nonatomic, readonly, retain) NSMutableDictionary* cooldowns; +- (void) addCooldown:(QQCooldown*)cool; +- (void) tickCooldowns; - (void) tick; - (void) act; + @end \ No newline at end of file diff --git a/src/game/QQDisplayable.h b/src/game/QQDisplayable.h index ab60dbf..b7031cf 100644 --- a/src/game/QQDisplayable.h +++ b/src/game/QQDisplayable.h @@ -12,7 +12,7 @@ /** * Called to setup the Sparrow shape. */ -- (SPDisplayObject*) setupShape; +- (void) setupShape; /** * Called to update appearance after game actions have occurred diff --git a/src/game/QQGame.h b/src/game/QQGame.h index f69644d..aaef0b2 100644 --- a/src/game/QQGame.h +++ b/src/game/QQGame.h @@ -1,5 +1,6 @@ #import "Sparrow.h" +#import "Tanks.h" #import "qq/event/QQNotificationCenter.h" #import "physics/QQWorld.h" @@ -38,7 +39,7 @@ @property (nonatomic, readonly) float elapsed; @property (nonatomic, readonly) long ticks; -@property (nonatomic, readonly, getter=isPaused) BOOL paused; +@property (nonatomic, readonly, getter=isRunning) BOOL running; @property (nonatomic, readwrite, assign) BOOL debugDrawingEnabled; @property (nonatomic, readonly) SPStage* stage; @@ -46,12 +47,9 @@ @property (nonatomic, readonly) QQLevel* level; @property (nonatomic, readonly) QQWorld* world; - @property (nonatomic, readonly, retain) NSSet* actors; -- (void) tick:(float)elapsed; - /** Alerts the game to a new actor. */ - (QQGame*) addActor:(QQActor*)actor; - (QQGame*) removeActor:(QQActor*)actor; @@ -62,6 +60,9 @@ /** Pauses the game. */ - (void) stop; +/** Advances the game clock one step and elapsed ms. */ +- (void) tick:(float)elapsed; + + (QQGame*) current; diff --git a/src/game/QQGame.mm b/src/game/QQGame.mm index ad60683..6ec2b28 100644 --- a/src/game/QQGame.mm +++ b/src/game/QQGame.mm @@ -1,6 +1,5 @@ #import -#import "Tanks.h" #import "game/QQGame.h" #import "game/unit/QQActors.h" #import "physics/event/QQContactNotification.h" @@ -11,6 +10,7 @@ - (void) onEnterFrame:(SPEnterFrameEvent*)event; - (void) onCollide:(QQContactNotification*)msg; +- (void) logEvent:(SPEvent*)evt; @end @@ -25,6 +25,7 @@ static QQGame* _CurrentGame = NULL; return _CurrentGame; } + - (id) init { if (_CurrentGame) { [self release]; @@ -70,9 +71,10 @@ static QQGame* _CurrentGame = NULL; [[[QQTank alloc] initAtX:wMax/6 y:hMax/6 width:50 height:50 color:0xFF0071] autorelease]; [[[QQUnit alloc] initAtX:wMax/3 y:hMax/2 width:50 height:50 color:0x4596FF] autorelease]; -#if TANKS_DEBUG_LOG - [_stage addEventListener:@selector(logEvent:) atObject:self forType:SP_EVENT_TYPE_ANY]; -#endif + #if TANKS_DEBUG_LOG + [_stage addEventListener:@selector(logEvent:) atObject:self forType:SP_EVENT_TYPE_ANY]; + #endif + } return self; } @@ -106,7 +108,7 @@ static QQGame* _CurrentGame = NULL; - (id) time { return self; } -@synthesize paused = _running; +@synthesize running = _running; @synthesize stage = _stage; @synthesize root = _root; @@ -126,10 +128,11 @@ static QQGame* _CurrentGame = NULL; /// methods - (void) tick:(float)elapsed { - if (!self.isPaused) return; + if (!self.isRunning) return; + _ticks++; - _elapsed = elapsed; - _now += elapsed; + _elapsed = elapsed; + _now += elapsed; for (QQActor* actor in self.actors) [actor tick]; @@ -185,20 +188,22 @@ static QQGame* _CurrentGame = NULL; } - (void) onCollide:(QQContactNotification*)msg { - NSLog(@"%@", msg); +// NSLog(@"\v\t%@", msg); } - (void) logEvent:(SPEvent*)evt { // ignore enter-frame events, as they happen constantly if ([evt.type isEqualToString:SP_EVENT_TYPE_ENTER_FRAME]) return; - NSLog(@"%@", evt); + NSLog(@"\v\t%@", evt); } - (NSString*) description { - return [NSString stringWithFormat:@"<%@: %p> {running=%s, #actors=%i, time={now=%f, elapsed=%f, ticks=%l}}", - [self class], (long)self, b2s(self.isPaused), [self.actors count], - self.now, self.elapsed, self.ticks]; + return [NSString stringWithFormat:@"<%@: %p> {running=%s, #actors=%i, time={now=%f, ticks=%l, elapsed=%f}}", + [self class], (long)self, + b2s(self.isRunning), [self.actors count], + self.now, self.ticks, self.elapsed + ]; } diff --git a/src/game/QQPhysical.h b/src/game/QQPhysical.h index 951567e..5714c23 100644 --- a/src/game/QQPhysical.h +++ b/src/game/QQPhysical.h @@ -14,6 +14,7 @@ /// The y coordinate in the simulation. @property (nonatomic, readwrite, assign) float y; +/// Simulation coordinates @property (nonatomic, readwrite) CGPoint position; - (void) setPositionX:(float)x y:(float)y; @@ -25,19 +26,21 @@ /// The height of the object in simulation units. //@property (nonatomic, assign) float height; - - - // FIXME: don't expose these, instead aggregate properties from body & fixtures/shapes @property (nonatomic, readonly) b2Body* body; @property (nonatomic, readonly) b2Fixture* fixture; + +/// methods + /** - * Called after initialization to create the various bodies, fixtures, and shapes - * that represent the Unit in Box2D. + * Called to create the various bodies, fixtures, and shapes that represent + * the Unit in Box2D. Normally called after initialization completes, but may + * be deferred if in a callback. */ -- (void) setupPhysics; +- (void) setupPhysics:(b2BodyDef*)bd; +- (void) applyLinearImpulse:(CGPoint)vec; - (void) applyLinearImpulseX:(float)xNs y:(float)yNs; diff --git a/src/game/QQThing.h b/src/game/QQThing.h index 8ee089f..231988a 100644 --- a/src/game/QQThing.h +++ b/src/game/QQThing.h @@ -1,4 +1,4 @@ -#import "qq/event/QQObservable.h" +#import "qq/event/QQNotifier.h" @class QQGame; @class QQWorld; diff --git a/src/game/ability/QQCooldown.h b/src/game/ability/QQCooldown.h index 63fd4cd..b706bf9 100644 --- a/src/game/ability/QQCooldown.h +++ b/src/game/ability/QQCooldown.h @@ -1,3 +1,4 @@ +#import "Tanks.h" #import "game/QQGameTime.h" @@ -6,10 +7,14 @@ */ @interface QQCooldown : NSObject { @private + NSString* _name; float _duration; float _elapsed; } +/** Name of this cooldown timer. */ +@property (nonatomic, readwrite, retain) NSString* name; + /** Duration of this cooldown timer (ms). */ @property (nonatomic, readwrite, assign) float duration; @@ -17,7 +22,7 @@ @property (nonatomic, readwrite, assign) float elapsed; /** Whether Cooldown timer is ready to be activated. */ -@property (nonatomic, readwrite) BOOL ready; +@property (nonatomic, readwrite, getter=isReady) BOOL ready; /** Percent completed (elapsed / duration), clamped [0, 1.0]. */ @property (nonatomic, readwrite) float ratio; @@ -25,8 +30,8 @@ /** * Implies ready=YES. */ -- (id) initWithDuration:(float)duration; -- (id) initWithDuration:(float)duration andReady:(BOOL)ready; +- (id) init:(NSString*)name duration:(float)duration; +- (id) init:(NSString*)name duration:(float)duration ready:(BOOL)ready; /** * Attempts to activate this cooldown, clearing the ready flag and setting elapsed to 0. @@ -42,7 +47,7 @@ - (BOOL) tick:(id)time; -+ (QQCooldown*) cooldownWithDuration:(float)duration; -+ (QQCooldown*) cooldownWithDuration:(float)duration andReady:(BOOL)ready; ++ (QQCooldown*) cooldown:(NSString*)name duration:(float)duration; ++ (QQCooldown*) cooldown:(NSString*)name duration:(float)duration ready:(BOOL)ready; @end diff --git a/src/game/ability/QQCooldown.mm b/src/game/ability/QQCooldown.mm index 0949e5d..432d1d9 100644 --- a/src/game/ability/QQCooldown.mm +++ b/src/game/ability/QQCooldown.mm @@ -5,10 +5,11 @@ /// properties +@synthesize name = _name; @synthesize duration = _duration; @synthesize elapsed = _elapsed; -- (BOOL) ready { return (self.elapsed >= self.duration); } +- (BOOL) isReady { return (self.elapsed >= self.duration); } - (void) setReady:(BOOL)newReady { if (newReady == self.ready) return; @@ -18,7 +19,7 @@ self.elapsed = 0; } -- (float) ratio { return fminf(1.0f, self.elapsed / self.duration); } +- (float) ratio { return MIN(1.0f, self.elapsed / self.duration); } - (void) setRatio:(float)newRatio { if (newRatio >= 1.0f) self.elapsed = self.duration; @@ -31,12 +32,17 @@ /// initializers -- (id) initWithDuration:(float)duration { - return [self initWithDuration:duration andReady:YES]; +- (id) init:(NSString*)name duration:(float)duration { + return [self init:name duration:duration ready:YES]; } -- (id) initWithDuration:(float)duration andReady:(BOOL)ready { - if ((self = [super init])){ +- (id) init:(NSString*)name duration:(float)duration ready:(BOOL)ready { + if ((self = [super init])) { + if (duration <= 0.0f) { + [self autorelease]; + [NSException raise:@"InvalidArgumentException" format:@"duration must be positive!"]; + } + self.name = name; _duration = duration; _elapsed = (ready ? _duration : 0); } @@ -69,15 +75,23 @@ return self.ready; } +- (NSString*) description { + return [NSString stringWithFormat:@"<%@: %p> {name=%@, ready=%s (%.3f%% %.3f/%.3f)}", + [self class], self, _name, b2s(self.isReady), + self.ratio, _elapsed, _duration + ]; +} + + /// convenience constructors -+ (QQCooldown*) cooldownWithDuration:(float)duration { - return [[[QQCooldown alloc] initWithDuration:duration] autorelease]; ++ (QQCooldown*) cooldown:(NSString*)name duration:(float)duration { + return [[[QQCooldown alloc] init:name duration:duration] autorelease]; } -+ (QQCooldown*) cooldownWithDuration:(float)duration andReady:(BOOL)ready { - return [[[QQCooldown alloc] initWithDuration:duration andReady:ready] autorelease]; ++ (QQCooldown*) cooldown:(NSString*)name duration:(float)duration ready:(BOOL)ready { + return [[[QQCooldown alloc] init:name duration:duration ready:ready] autorelease]; } diff --git a/src/game/unit/QQActor.h b/src/game/unit/QQActor.h index b5dc695..abc384e 100644 --- a/src/game/unit/QQActor.h +++ b/src/game/unit/QQActor.h @@ -1,10 +1,12 @@ #include -#import "qq/event/QQNotificationProxy.h" +#import "Tanks.h" +#import "qq/event/QQNotifiers.h" #import "game/QQThing.h" #import "game/QQActive.h" #import "game/QQPhysical.h" #import "game/QQDisplayable.h" +#import "game/ability/QQCooldown.h" #import "game/unit/QQActorDelegate.h" #import "physics/QQWorld.h" @@ -17,20 +19,26 @@ b2Body* _body; @private + id _delegate; + BOOL _active; BOOL _dirty; BOOL _dead; - id _delegate; - NSArray* _cooldowns; + NSMutableDictionary* _cooldowns; } +@property (nonatomic, readwrite, retain) id delegate; + @property (nonatomic, readonly) QQGame* game; @property (nonatomic, readonly) QQWorld* world; -@property (nonatomic, readwrite, retain) id delegate; -@property (nonatomic, readonly) BOOL dead; + +@property (nonatomic, readonly, getter=isDead) BOOL dead; +@property (nonatomic, readonly, retain) NSMutableDictionary* cooldowns; + - (id) initAtX:(float)x y:(float)y; -- (id) initType:(b2BodyType)type atX:(float)x y:(float)y; +- (id) initWithType:(b2BodyType)type atX:(float)x y:(float)y; +- (id) initWithBodyDef:(b2BodyDef*)bd; - (void) destroy; diff --git a/src/game/unit/QQActor.mm b/src/game/unit/QQActor.mm index 8421992..0237ef0 100644 --- a/src/game/unit/QQActor.mm +++ b/src/game/unit/QQActor.mm @@ -1,5 +1,4 @@ #import "QQActor.h" -#import "render/QQSparrowExtensions.h" #import "game/QQGame.h" @@ -7,34 +6,27 @@ /// properties -@dynamic shape; - -@synthesize active = _active; -@synthesize dirty = _dirty; -@synthesize dead = _dead; -@synthesize delegate = _delegate; -@synthesize cooldowns = _cooldowns; - - - (QQGame*) game { return QQGame.current; } - (QQWorld*) world { return self.game.world; } - (b2Body*) body { return _body; } - (b2Fixture*) fixture { return nil; } -- (id) implicitNotificationSender { return self; } -- (void) setImplicitNotificationSender:(id)sender {} -- (id) proxiedNotifier { return self.game; } -- (void) setProxiedNotifier:(id)notifier {} +@synthesize delegate = _delegate; +@synthesize cooldowns = _cooldowns; +@synthesize dead = _dead; +@synthesize dirty = _dirty; +@synthesize active = _active; + +- (BOOL) isSleeping { return _active; } +- (void) setSleeping:(BOOL)v { _active = v; } - (float) x { return self.body->GetPosition().x; } - (void) setX:(float)x { [self setPositionX:x y:self.y]; } - - (float) y { return self.body->GetPosition().y; } - (void) setY:(float)y { [self setPositionX:self.x y:y]; } - - (CGPoint) position { b2Vec2 pos = self.body->GetPosition(); return CGPointMake(pos.x, pos.y); @@ -45,21 +37,22 @@ - (void) setPositionX:(float)x y:(float)y { self.body->SetTransform(b2Vec2(x,y), self.body->GetAngle()); } - - (float) rotation { return self.body->GetAngle(); } - (void) setRotation:(float)r { self.body->SetTransform(self.body->GetPosition(), r); } +@dynamic shape; + +// sync sparrow with box2d + - (void) updateShapeX:(float)x y:(float)y { float px = self.world.scale; [self.shape setCenterX:x*px y:y*px]; } - - (void) updateShapeX:(float)x y:(float)y rotation:(float)r { [self updateShapeX:x y:y]; self.shape.rotation = r; } - - (void) updateShape { b2Transform trans = self.body->GetTransform(); [self updateShapeX:trans.position.x y:trans.position.y rotation:trans.GetAngle()]; @@ -69,26 +62,38 @@ /// initializers +- (id) init { + return [self initAtX:0 y:0]; +} + - (id) initAtX:(float)x y:(float)y { - return [self initType:b2_dynamicBody atX:x y:y]; + return [self initWithType:b2_dynamicBody atX:x y:y]; } -- (id) initType:(b2BodyType)type atX:(float)x y:(float)y { +- (id) initWithType:(b2BodyType)type atX:(float)x y:(float)y { + b2BodyDef bd; + bd.type = type; + bd.position = b2Vec2(x,y); + bd.userData = self; + return [self initWithBodyDef:&bd]; +} + +- (id) initWithBodyDef:(b2BodyDef*)bd { if ((self = [super init])) { _active = YES; _dead = NO; + + self.implicitSender = self; self.proxiedNotifier = self.game; - self.cooldowns = [NSArray array]; - [self.game addActor:self]; - b2BodyDef bd; - bd.type = type; - bd.position = b2Vec2(x, y); - bd.userData = self; - _body = self.world.world->CreateBody(&bd); + _cooldowns = [[NSMutableDictionary alloc] initWithCapacity:2]; + [self setupPhysics:bd]; + [self.game addActor:self]; if ([self respondsToSelector:@selector(onCollideBegin:)]) [self addObserver:self selector:@selector(onCollideBegin:) name:QQ_EVENT_CONTACT_BEGIN]; + if ([self respondsToSelector:@selector(onCollideEnd:)]) + [self addObserver:self selector:@selector(onCollideEnd:) name:QQ_EVENT_CONTACT_END]; } return self; } @@ -101,10 +106,34 @@ +/// subclassing + +- (void) setupShape { + // override in subclass +} + +// TODO: you can't create bodies during callbacks +/// override but call super! +- (void) setupPhysics:(b2BodyDef*)bd { + if (!_body) { + _body = self.world.world->CreateBody(bd); + } +} + +- (void) act { + // override in subclass +} + + + /// methods +- (void) addCooldown:(QQCooldown*)cool { + [self.cooldowns setObject:cool forKey:cool.name]; +} + - (void) destroy { - if (self.dead) return; + if (self.isDead) return; _dead = YES; self.shape = nil; @@ -112,28 +141,26 @@ } - (void) tick { - if (self.dead) return; + if (self.isDead) return; - [self.cooldowns makeObjectsPerformSelector:@selector(tick:) withObject:self.game.time]; + [self tickCooldowns]; if (self.isActive) [self act]; } -- (void) act {} - -- (SPDisplayObject*) setupShape { - return self.shape; +- (void) tickCooldowns { + [self.cooldowns makeObjectsPerformSelector:@selector(tick:) withObject:self.game.time]; } - (void) draw { - if (self.dead) return; - + if (self.isDead) return; + if (!self.shape) [self setupShape]; [self updateShape]; } -- (void) setupPhysics {} - - +- (void) applyLinearImpulse:(CGPoint)pt { + [self applyLinearImpulseX:pt.x y:pt.y]; +} - (void) applyLinearImpulseX:(float)xNs y:(float)yNs { self.body->ApplyLinearImpulse(b2Vec2(xNs, yNs), self.body->GetPosition()); } @@ -143,9 +170,8 @@ b2Transform trans = self.body->GetTransform(); b2Vec2 pos = trans.position; //b2Vec2 v = actor.body->GetLinearVelocity(); - SPDisplayObject* s = self.shape; - return [NSString stringWithFormat:@"[%@ box2d=[ (%f,%f) rotation=%f], shape=%@]", - [super description], pos.x,pos.y, trans.GetAngle(), s]; + return [NSString stringWithFormat:@"\v\t<%@ %p> {\v\t\tbox2d=[ (%f,%f) rotation=%f], \v\t\tshape=%@, \v\t\tcooldowns=%@}", + [self class], self, pos.x,pos.y, trans.GetAngle(), self.shape, self.cooldowns]; } diff --git a/src/game/unit/QQBullet.h b/src/game/unit/QQBullet.h index b4a6241..2d11478 100644 --- a/src/game/unit/QQBullet.h +++ b/src/game/unit/QQBullet.h @@ -1,3 +1,4 @@ +#import "Tanks.h" #import "game/unit/QQUnit.h" diff --git a/src/game/unit/QQBullet.mm b/src/game/unit/QQBullet.mm index 99b3f42..ea998f7 100644 --- a/src/game/unit/QQBullet.mm +++ b/src/game/unit/QQBullet.mm @@ -31,8 +31,8 @@ } - (void) onCollideBegin:(QQContactNotification*)msg { - QQActor* other = (msg.actorA && (msg.actorA != self) ? msg.actorA : - (msg.actorB && (msg.actorB != self) ? msg.actorB : nil)); + QQActor* other = ((msg.actorA && (msg.actorA != self)) ? msg.actorA : + ((msg.actorB && (msg.actorB != self)) ? msg.actorB : nil)); if (other) { NSLog(@"BOOM! %@", msg); [other destroy]; diff --git a/src/game/unit/QQTank.h b/src/game/unit/QQTank.h index c4c5971..5850a26 100644 --- a/src/game/unit/QQTank.h +++ b/src/game/unit/QQTank.h @@ -1,10 +1,8 @@ #import "game/unit/QQUnit.h" -#import "game/ability/QQCooldown.h" @interface QQTank : QQUnit { - QQCooldown* _coolAtk; + } -@property (nonatomic, readonly, retain) QQCooldown* coolAtk; @end diff --git a/src/game/unit/QQTank.mm b/src/game/unit/QQTank.mm index edd130a..edacf1a 100644 --- a/src/game/unit/QQTank.mm +++ b/src/game/unit/QQTank.mm @@ -6,7 +6,6 @@ // private interface @interface QQTank () -@property (nonatomic, readwrite, retain) QQCooldown* coolAtk; - (void) onTouch:(SPTouchEvent*)event; @end @@ -14,12 +13,9 @@ @implementation QQTank -@synthesize coolAtk = _coolAtk; - (id) initAtX:(float)x y:(float)y withShape:(SPDisplayObject*)shape { if ((self = [super initAtX:x y:y withShape:shape])){ - self.coolAtk = [QQCooldown cooldownWithDuration:0.5f]; - self.cooldowns = [self.cooldowns arrayByAddingObject:self.coolAtk]; [self.game.stage addEventListener:@selector(onTouch:) atObject:self forType:SP_EVENT_TYPE_TOUCH]; } return self; @@ -27,14 +23,13 @@ - (void) dealloc { [self.game.stage removeEventListener:@selector(onTouch:) atObject:self forType:SP_EVENT_TYPE_TOUCH]; - [_coolAtk release]; [super dealloc]; } - (void) onTouch:(SPTouchEvent*)event { SPTouch* touch = [[event touchesWithTarget:(SPDisplayObject*)self.game.stage] anyObject]; - if (touch && [self.coolAtk activate]) { + if (touch && [[self.cooldowns objectForKey:ATTACK_COOLDOWN_NAME] activate]) { // Touch's normal vector in local coords (rel unit origin) SPPoint* normVec = [[[touch locationInSpace:self.shape.parent] subtractPoint:self.shape.position] normalize]; @@ -50,17 +45,5 @@ } } -- (void) _moveOnTouch:(SPTouchEvent*)event { - SPTouch* touch = [[event touchesWithTarget:self.shape.parent] anyObject]; - if (touch) { - SPPoint* touchPosition = [touch locationInSpace:self.shape.parent]; - float x = self.shape.x = touchPosition.x - self.shape.width / 2.0f; - float y = self.shape.y = touchPosition.y - self.shape.height / 2.0f; - - float px = self.world.scale; - [self setPositionX:x/px y:y/px]; - // self.body->SetTransform(b2Vec2(x/px, y/px), self.body->GetAngle()); - } -} @end \ No newline at end of file diff --git a/src/game/unit/QQUnit.h b/src/game/unit/QQUnit.h index 6fdee22..ce5bf9e 100644 --- a/src/game/unit/QQUnit.h +++ b/src/game/unit/QQUnit.h @@ -1,10 +1,11 @@ #include #import "Sparrow.h" +#import "render/QQSparrowExtensions.h" -#import "physics/QQWorld.h" +#import "game/ability/QQCooldown.h" #import "game/unit/QQActor.h" #import "game/unit/QQActorDelegate.h" -#import "render/QQSparrowExtensions.h" + @interface QQUnit : QQActor { @@ -14,9 +15,13 @@ } /// properties + @property (nonatomic, readonly) BOOL canAttack; +@property (nonatomic, readwrite, assign) QQCooldown* attackCooldown; + - (void) setShapeFromFile:(NSString*)filename; + /// initializers - (id) initAtX:(float)x y:(float)y width:(float)w height:(float)h color:(uint)color; - (id) initAtX:(float)x y:(float)y withShape:(SPDisplayObject*)shape; diff --git a/src/game/unit/QQUnit.mm b/src/game/unit/QQUnit.mm index 0959cfb..557125d 100644 --- a/src/game/unit/QQUnit.mm +++ b/src/game/unit/QQUnit.mm @@ -1,9 +1,10 @@ #include #import "Sparrow.h" +#import "render/QQSparrowExtensions.h" #import "game/unit/QQUnit.h" #import "game/QQGame.h" -#import "render/QQSparrowExtensions.h" +#import "game/unit/QQBullet.h" @@ -20,7 +21,9 @@ - (float) shapeCenterY { return self.shape.registrationY; } - (void) setShapeCenterY:(float)y { self.shape.registrationY = y; } -- (BOOL) canAttack { return NO; } +- (QQCooldown*) attackCooldown { return [self.cooldowns objectForKey:ATTACK_COOLDOWN_NAME]; } +- (void) setAttackCooldown:(QQCooldown*)newAttackCooldown { [self.cooldowns setObject:newAttackCooldown forKey:ATTACK_COOLDOWN_NAME]; } +- (BOOL) canAttack { return self.attackCooldown.isReady; } /// initializers @@ -36,6 +39,7 @@ - (id) initAtX:(float)x y:(float)y withShape:(SPDisplayObject*)shape { if ((self = [super initAtX:x y:y])) { + [self addCooldown:[QQCooldown cooldown:ATTACK_COOLDOWN_NAME duration:0.5f]]; self.shape = shape; float dblpx = 2*self.world.scale; @@ -93,7 +97,21 @@ [self attackTowardX:pt.x y:pt.y]; } - (void) attackTowardX:(float)x y:(float)y { + SPPoint* pos = [SPPoint pointFromCGPoint:self.position]; + SPPoint* target = [SPPoint pointWithX:x y:y]; + + // Touch's normal vector in local coords (rel unit origin) + SPPoint* normVec = [[target subtractPoint:pos] normalize]; + + // Bullet starting position + float offset = 1.5f + MAX(self.shape.width, self.shape.height) * 1.41421356237f; // bullet_radius + tank_diagonal_length + SPPoint* start = [pos addPoint:[normVec scaleBy:offset]]; + QQBullet* bullet = [[[QQBullet alloc] init:self x:start.x y:start.y] autorelease]; + // Bullet impulse vector + SPPoint* imp = [normVec scaleBy:50]; + [bullet applyLinearImpulseX:imp.x y:imp.y]; + NSLog(@"[%@ pos:(%f,%f) impulse:(%f,%f)]", bullet, bullet.x,bullet.y, imp.x,imp.y); } diff --git a/src/qq/Collections+FP.h b/src/qq/Collections+FP.h new file mode 100644 index 0000000..e69de29 diff --git a/src/qq/Collections+FP.mm b/src/qq/Collections+FP.mm new file mode 100644 index 0000000..e69de29 diff --git a/src/qq/NSArray+QQExtensions.h b/src/qq/NSArray+QQExtensions.h new file mode 100644 index 0000000..9a23277 --- /dev/null +++ b/src/qq/NSArray+QQExtensions.h @@ -0,0 +1,6 @@ + +@interface NSArray (QQExtensions) + +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2; + +@end diff --git a/src/qq/NSArray+QQExtensions.mm b/src/qq/NSArray+QQExtensions.mm new file mode 100644 index 0000000..963735a --- /dev/null +++ b/src/qq/NSArray+QQExtensions.mm @@ -0,0 +1,12 @@ +#import "NSArray+QQExtensions.h" + + +@implementation NSArray (QQExtensions) + +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2 { + for (id value in self) + [value performSelector:aSelector withObject:arg1 withObject:arg2]; +} + + +@end diff --git a/src/qq/NSDictionary+QQExtensions.h b/src/qq/NSDictionary+QQExtensions.h new file mode 100644 index 0000000..3a47227 --- /dev/null +++ b/src/qq/NSDictionary+QQExtensions.h @@ -0,0 +1,8 @@ + +@interface NSDictionary (QQExtensions) + +- (void) makeObjectsPerformSelector:(SEL)aSelector; +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1; +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2; + +@end diff --git a/src/qq/NSDictionary+QQExtensions.mm b/src/qq/NSDictionary+QQExtensions.mm new file mode 100644 index 0000000..91dd463 --- /dev/null +++ b/src/qq/NSDictionary+QQExtensions.mm @@ -0,0 +1,27 @@ +#import "NSDictionary+QQExtensions.h" + + +@implementation NSDictionary (QQExtensions) + +- (void) makeObjectsPerformSelector:(SEL)aSelector { + for (NSString* key in self) { + id value = [self objectForKey:key]; + [value performSelector:aSelector]; + } +} + +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 { + for (NSString* key in self) { + id value = [self objectForKey:key]; + [value performSelector:aSelector withObject:arg1]; + } +} + +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2 { + for (NSString* key in self) { + id value = [self objectForKey:key]; + [value performSelector:aSelector withObject:arg1 withObject:arg2]; + } +} + +@end diff --git a/src/qq/NSSet+QQExtensions.h b/src/qq/NSSet+QQExtensions.h index 80780dd..51dbc01 100644 --- a/src/qq/NSSet+QQExtensions.h +++ b/src/qq/NSSet+QQExtensions.h @@ -4,5 +4,6 @@ - (NSSet*) setByRemovingObject:(id)object; - (NSSet*) setByRemovingArray:(NSArray*)objects; +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2; @end diff --git a/src/qq/NSSet+QQExtensions.mm b/src/qq/NSSet+QQExtensions.mm index 6b4d74c..e04a818 100644 --- a/src/qq/NSSet+QQExtensions.mm +++ b/src/qq/NSSet+QQExtensions.mm @@ -1,3 +1,5 @@ +#import "NSSet+QQExtensions.h" + @implementation NSSet (QQExtensions) - (NSSet*) setByRemovingObject:(id)object { @@ -12,4 +14,9 @@ }]; } +- (void) makeObjectsPerformSelector:(SEL)aSelector withObject:(id)arg1 withObject:(id)arg2 { + for (id value in self) + [value performSelector:aSelector withObject:arg1 withObject:arg2]; +} + @end diff --git a/src/qq/event/QQNotificationCenter.h b/src/qq/event/QQNotificationCenter.h index 661d909..520bb35 100644 --- a/src/qq/event/QQNotificationCenter.h +++ b/src/qq/event/QQNotificationCenter.h @@ -1,16 +1,18 @@ #import "qq/event/QQNotifier.h" -@interface QQNotificationCenter : NSNotificationCenter { +@interface QQNotificationCenter : NSNotificationCenter { @private id _implicitNotificationSender; + id _parentNotifier; } /** Object used for implicit sender when adding or removing observers. */ -@property (nonatomic, readwrite, retain) id implicitNotificationSender; +@property (nonatomic, readwrite, assign) id implicitNotificationSender; /** Initialize with self as implicit sender. */ - (id) init; /** Returns a center with given implicit target. A nil target will subscript observers to all objects. */ + (QQNotificationCenter*) notifierWithTarget:(id)target; ++ (QQNotificationCenter*) notifierWithTarget:(id)target andParent:(id)parent; @end diff --git a/src/qq/event/QQNotificationCenter.mm b/src/qq/event/QQNotificationCenter.mm index 64e5703..da2ce8a 100644 --- a/src/qq/event/QQNotificationCenter.mm +++ b/src/qq/event/QQNotificationCenter.mm @@ -6,16 +6,19 @@ - (id) init { if ((self = [super init])){ _implicitNotificationSender = self; + _parentNotifier = nil; } return self; } - (void) dealloc { - [_implicitNotificationSender release]; + self.implicitNotificationSender = nil; + self.parentNotifier = nil; [super dealloc]; } @synthesize implicitNotificationSender = _implicitNotificationSender; +@synthesize parentNotifier = _parentNotifier; /// observable @@ -33,6 +36,7 @@ } // Send a notification from this object + - (void) postNotificationName:(NSString*)name { [self postNotificationName:name object:self.implicitNotificationSender]; } @@ -47,6 +51,11 @@ [super removeObserver:observer]; } +- (void) postNotification:(NSNotification*)msg { + [super postNotification:msg]; + [self.parentNotifier postNotification:msg]; +} + /// NSNotificationCenter (superclass) provides: @@ -61,8 +70,12 @@ + (QQNotificationCenter*) notifierWithTarget:(id)target { + return [QQNotificationCenter notifierWithTarget:target andParent:nil]; +} ++ (QQNotificationCenter*) notifierWithTarget:(id)target andParent:(id)parent { QQNotificationCenter* notifier = [[[QQNotificationCenter alloc] init] autorelease]; notifier.implicitNotificationSender = target; + notifier.parentNotifier = parent; return notifier; } diff --git a/src/qq/event/QQNotificationProxy.h b/src/qq/event/QQNotificationProxy.h index 0030b68..31ad268 100644 --- a/src/qq/event/QQNotificationProxy.h +++ b/src/qq/event/QQNotificationProxy.h @@ -6,11 +6,15 @@ @interface QQNotificationProxy : NSObject { @private id _proxiedNotifier; - id _implicitNotificationSender; + id _parentNotifier; + id _implicitSender; } +@property (nonatomic, readwrite, assign) id implicitSender; +@property (nonatomic, readwrite, retain) id parentNotifier; @property (nonatomic, readwrite, retain) id proxiedNotifier; - (id) initWithNotifier:(id)notifier; +- (id) initWithNotifier:(id)notifier andParent:(id)parent; @end diff --git a/src/qq/event/QQNotificationProxy.mm b/src/qq/event/QQNotificationProxy.mm index 3d2c3ee..5a2efd0 100644 --- a/src/qq/event/QQNotificationProxy.mm +++ b/src/qq/event/QQNotificationProxy.mm @@ -1,44 +1,52 @@ #import "qq/event/QQNotificationProxy.h" +#import "qq/event/QQNotification.h" @implementation QQNotificationProxy @synthesize proxiedNotifier = _proxiedNotifier; -@synthesize implicitNotificationSender = _implicitNotificationSender; +@synthesize parentNotifier = _parentNotifier; +@synthesize implicitSender = _implicitSender; - (id) initWithNotifier:(id)notifier { + return [self initWithNotifier:notifier andParent:nil]; +} + +- (id) initWithNotifier:(id)notifier andParent:(id)parent { if ((self = [super init])){ self.proxiedNotifier = notifier; + self.parentNotifier = parent; } return self; } - (void) dealloc { self.proxiedNotifier = nil; + self.parentNotifier = nil; [super dealloc]; } /// observable - (void) addObserver:(id)observer selector:(SEL)selector name:(NSString*)event { - [self addObserver:observer selector:selector name:event object:self.implicitNotificationSender]; + [self addObserver:observer selector:selector name:event object:self.implicitSender]; } // Remove a listener from this object - (void) removeObserver:(id)observer { - [self removeObserver:observer name:nil object:self.implicitNotificationSender]; + [self removeObserver:observer name:nil object:self.implicitSender]; } - (void) removeObserver:(id)observer name:(NSString*)event { - [self removeObserver:observer name:event object:self.implicitNotificationSender]; + [self removeObserver:observer name:event object:self.implicitSender]; } // Send a notification from this object - (void) postNotificationName:(NSString*)name { - [self postNotificationName:name object:self.implicitNotificationSender]; + [self postNotificationName:name object:self.implicitSender userInfo:nil]; } - (void) postNotificationName:(NSString*)name userInfo:(NSDictionary*)info { - [self postNotificationName:name object:self.implicitNotificationSender userInfo:info]; + [self postNotificationName:name object:self.implicitSender userInfo:info]; } @@ -57,12 +65,14 @@ - (void) postNotification:(NSNotification*)msg { [self.proxiedNotifier postNotification:msg]; + [self.parentNotifier postNotification:msg]; } - (void) postNotificationName:(NSString*)name object:(id)sender { - [self.proxiedNotifier postNotificationName:name object:sender]; + [self postNotificationName:name object:sender userInfo:nil]; } - (void) postNotificationName:(NSString*)name object:(id)sender userInfo:(NSDictionary*)info { - [self.proxiedNotifier postNotificationName:name object:sender userInfo:info]; + QQNotification* msg = [QQNotification notification:name object:sender userInfo:info]; + [self postNotification:msg]; } diff --git a/src/qq/event/QQNotifier.h b/src/qq/event/QQNotifier.h index 445d501..0651091 100644 --- a/src/qq/event/QQNotifier.h +++ b/src/qq/event/QQNotifier.h @@ -21,9 +21,16 @@ - (void) postNotificationName:(NSString*)name object:(id)sender; - (void) postNotificationName:(NSString*)name object:(id)sender userInfo:(NSDictionary*)info; - @end + @protocol QQObservableNotifier +@end + + +@protocol QQBubblingNotifier + +@property (nonatomic, readwrite, retain) id parentNotifier; + +@end -@end \ No newline at end of file diff --git a/src/qq/event/QQNotifiers.h b/src/qq/event/QQNotifiers.h index 8eeab9a..55b852c 100644 --- a/src/qq/event/QQNotifiers.h +++ b/src/qq/event/QQNotifiers.h @@ -4,43 +4,3 @@ #import "qq/event/QQNotificationCenter.h" #import "qq/event/QQNotificationProxy.h" - - -/** - * As a QQNotificationProxy, but via encapsulation. - */ -#define qqNotifierProxy(__target, __notifier) \ -- (void) addObserver:(id)observer selector:(SEL)selector name:(NSString*)event { \ - [self addObserver:observer selector:selector name:event object:__target]; \ -} \ -- (void) removeObserver:(id)observer { \ - [self removeObserver:observer name:nil object:__target]; \ -} \ -- (void) removeObserver:(id)observer name:(NSString*)event { \ - [self removeObserver:observer name:event object:__target]; \ -} \ -- (void) postNotificationName:(NSString*)name { \ - [self postNotificationName:name object:__target]; \ -} \ -- (void) postNotificationName:(NSString*)name userInfo:(NSDictionary*)info { \ - [self postNotificationName:name object:__target userInfo:info]; \ -} \ -- (void) addObserver:(id)observer selector:(SEL)selector name:(NSString*)event object:(id)sender { \ - [__notifier addObserver:observer selector:selector name:event object:sender]; \ -} \ -- (void) removeObserver:(id)observer name:(NSString*)event object:(id)sender { \ - [__notifier removeObserver:observer name:event object:sender]; \ -} \ -- (void) removeObservers:(id)observer { \ - [__notifier removeObserver:observer]; \ -} \ -- (void) postNotification:(NSNotification*)msg { \ - [__notifier postNotification:msg]; \ -} \ -- (void) postNotificationName:(NSString*)name object:(id)sender { \ - [__notifier postNotificationName:name object:sender]; \ -} \ -- (void) postNotificationName:(NSString*)name object:(id)sender userInfo:(NSDictionary*)info { \ - [__notifier postNotificationName:name object:sender userInfo:info]; \ -} - diff --git a/src/qq/event/QQObservable.h b/src/qq/event/QQObservable.h index 8814775..5f56475 100644 --- a/src/qq/event/QQObservable.h +++ b/src/qq/event/QQObservable.h @@ -5,8 +5,6 @@ */ @protocol QQObservable -@property (nonatomic, readwrite, retain) id implicitNotificationSender; - //- (void) observe:(NSString*)event notify:(id)observer selector:(SEL)selector; /** Adds an observer of this object. */ diff --git a/tanks.xcodeproj/project.pbxproj b/tanks.xcodeproj/project.pbxproj index 8bd63cc..78525df 100644 --- a/tanks.xcodeproj/project.pbxproj +++ b/tanks.xcodeproj/project.pbxproj @@ -62,6 +62,10 @@ 499F65E9139CBCBA00309DE4 /* QQUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 499F65DF139CBCBA00309DE4 /* QQUnit.h */; }; 499F65EA139CBCBA00309DE4 /* QQUnit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 499F65E0139CBCBA00309DE4 /* QQUnit.mm */; }; 499F65EC139CBCC000309DE4 /* QQGameTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 499F65EB139CBCC000309DE4 /* QQGameTime.h */; }; + 499F65FD139CFD3800309DE4 /* NSArray+QQExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 499F65F9139CFD3700309DE4 /* NSArray+QQExtensions.h */; }; + 499F65FE139CFD3800309DE4 /* NSArray+QQExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 499F65FA139CFD3700309DE4 /* NSArray+QQExtensions.mm */; }; + 499F65FF139CFD3800309DE4 /* NSDictionary+QQExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 499F65FB139CFD3700309DE4 /* NSDictionary+QQExtensions.h */; }; + 499F6600139CFD3800309DE4 /* NSDictionary+QQExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 499F65FC139CFD3800309DE4 /* NSDictionary+QQExtensions.mm */; }; 49D8645D1392DB2800BC341C /* QQShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D8645B1392DB2800BC341C /* QQShape.h */; }; 49D8645E1392DB2800BC341C /* QQShape.mm in Sources */ = {isa = PBXBuildFile; fileRef = 49D8645C1392DB2800BC341C /* QQShape.mm */; }; 49DA67D4137847A7004841E9 /* QQWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 49DA67D2137847A7004841E9 /* QQWorld.h */; }; @@ -283,6 +287,10 @@ 499F65DF139CBCBA00309DE4 /* QQUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQUnit.h; sourceTree = ""; }; 499F65E0139CBCBA00309DE4 /* QQUnit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQUnit.mm; sourceTree = ""; }; 499F65EB139CBCC000309DE4 /* QQGameTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQGameTime.h; sourceTree = ""; }; + 499F65F9139CFD3700309DE4 /* NSArray+QQExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+QQExtensions.h"; sourceTree = ""; }; + 499F65FA139CFD3700309DE4 /* NSArray+QQExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+QQExtensions.mm"; sourceTree = ""; }; + 499F65FB139CFD3700309DE4 /* NSDictionary+QQExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+QQExtensions.h"; sourceTree = ""; }; + 499F65FC139CFD3800309DE4 /* NSDictionary+QQExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+QQExtensions.mm"; sourceTree = ""; }; 49D8645B1392DB2800BC341C /* QQShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQShape.h; sourceTree = ""; }; 49D8645C1392DB2800BC341C /* QQShape.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQShape.mm; sourceTree = ""; }; 49DA67D2137847A7004841E9 /* QQWorld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQWorld.h; sourceTree = ""; }; @@ -484,6 +492,10 @@ isa = PBXGroup; children = ( 499F65BF139CBC0C00309DE4 /* event */, + 499F65F9139CFD3700309DE4 /* NSArray+QQExtensions.h */, + 499F65FA139CFD3700309DE4 /* NSArray+QQExtensions.mm */, + 499F65FB139CFD3700309DE4 /* NSDictionary+QQExtensions.h */, + 499F65FC139CFD3800309DE4 /* NSDictionary+QQExtensions.mm */, 49E3C5D0139A73E700A3958A /* NSSet+QQExtensions.h */, 49E3C5D1139A73E700A3958A /* NSSet+QQExtensions.mm */, ); @@ -619,10 +631,10 @@ 499F65D6139CBCBA00309DE4 /* unit */ = { isa = PBXGroup; children = ( + 499F65DA139CBCBA00309DE4 /* QQActors.h */, + 499F65D9139CBCBA00309DE4 /* QQActorDelegate.h */, 499F65D7139CBCBA00309DE4 /* QQActor.h */, 499F65D8139CBCBA00309DE4 /* QQActor.mm */, - 499F65D9139CBCBA00309DE4 /* QQActorDelegate.h */, - 499F65DA139CBCBA00309DE4 /* QQActors.h */, 499F65DB139CBCBA00309DE4 /* QQBullet.h */, 499F65DC139CBCBA00309DE4 /* QQBullet.mm */, 499F65DD139CBCBA00309DE4 /* QQTank.h */, @@ -1080,6 +1092,8 @@ 499F65E7139CBCBA00309DE4 /* QQTank.h in Headers */, 499F65E9139CBCBA00309DE4 /* QQUnit.h in Headers */, 499F65EC139CBCC000309DE4 /* QQGameTime.h in Headers */, + 499F65FD139CFD3800309DE4 /* NSArray+QQExtensions.h in Headers */, + 499F65FF139CFD3800309DE4 /* NSDictionary+QQExtensions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1240,6 +1254,8 @@ 499F65E6139CBCBA00309DE4 /* QQBullet.mm in Sources */, 499F65E8139CBCBA00309DE4 /* QQTank.mm in Sources */, 499F65EA139CBCBA00309DE4 /* QQUnit.mm in Sources */, + 499F65FE139CFD3800309DE4 /* NSArray+QQExtensions.mm in Sources */, + 499F6600139CFD3800309DE4 /* NSDictionary+QQExtensions.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- 1.7.0.4