From cdc7ed14c8e6d2be41e4b211399361d651ccf847 Mon Sep 17 00:00:00 2001 From: dsc Date: Tue, 24 May 2011 01:30:53 -0700 Subject: [PATCH] Adds Cooldown class. --- src/game/QQActive.h | 3 +- src/game/QQDisplayable.h | 3 + src/game/QQGame.mm | 22 +++++----- src/game/QQPhysical.h | 5 ++ src/game/ability/QQCooldown.h | 47 ++++++++++++++++++++++ src/game/ability/QQCooldown.mm | 84 ++++++++++++++++++++++++++++++++++++++++ src/game/actor/QQActor.h | 3 +- src/game/actor/QQUnit.h | 28 +++---------- src/game/actor/QQUnit.mm | 72 ---------------------------------- src/prefix.pch | 2 + 10 files changed, 162 insertions(+), 107 deletions(-) create mode 100644 src/game/ability/QQCooldown.h create mode 100644 src/game/ability/QQCooldown.mm delete mode 100644 src/game/actor/QQUnit.mm diff --git a/src/game/QQActive.h b/src/game/QQActive.h index 62a0681..ec6fe08 100644 --- a/src/game/QQActive.h +++ b/src/game/QQActive.h @@ -1,8 +1,9 @@ +#import "game/QQThing.h" /** * Anything that takes a turn is QQActive. */ -@protocol QQActive +@protocol QQActive @property (nonatomic, getter=isActive) BOOL active; diff --git a/src/game/QQDisplayable.h b/src/game/QQDisplayable.h index 3d69432..a559892 100644 --- a/src/game/QQDisplayable.h +++ b/src/game/QQDisplayable.h @@ -1,6 +1,9 @@ #import "Sparrow.h" +/** + * Anything that has a Sparrow represenation in the display tree. + */ @protocol QQDisplayable @property (nonatomic, retain, readonly) SPDisplayObject* shape; diff --git a/src/game/QQGame.mm b/src/game/QQGame.mm index aa54899..14ea57f 100644 --- a/src/game/QQGame.mm +++ b/src/game/QQGame.mm @@ -1,9 +1,9 @@ #import "QQGame.h" -#import "game/actor/QQUnit.h" +#import "game/actor/QQTank.h" -static QQGame* _currentGame = NULL; +static QQGame* _CurrentGame = NULL; @@ -13,24 +13,24 @@ static QQGame* _currentGame = NULL; @implementation QQGame -@synthesize ticks = _ticks; -@synthesize world = _world; +@synthesize ticks = _ticks; +@synthesize world = _world; @synthesize actors = _actors; - (id) init { - if (_currentGame) { + if (_CurrentGame) { [self release]; [NSException raise:@"TooManyGames" format:@"cannot instantiate more than one QQGame at a time!"]; } if ( (self = [super init]) ){ - _currentGame = self; + _CurrentGame = self; _ticks = 0l; _actors = [[NSMutableArray alloc] initWithCapacity:10]; _world = [[QQWorld alloc] init]; - [self addActor:[[[QQUnit alloc] init] autorelease]]; + [self addActor:[[[QQTank alloc] init] autorelease]]; [self addEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME]; } @@ -41,7 +41,7 @@ static QQGame* _currentGame = NULL; [_actors removeAllObjects]; [_actors release]; [_world release]; - _currentGame = NULL; + _CurrentGame = NULL; [super dealloc]; } @@ -69,10 +69,10 @@ static QQGame* _currentGame = NULL; + (QQGame*) current { - if (!_currentGame) - [[[QQGame alloc] init] // init assigns to singleton, but singleton is a weakref, + if (!_CurrentGame) + [[[QQGame alloc] init] // init assigns to singleton, but singleton is a weakref, autorelease]; // XXX: so game will still be released if not retained... - return _currentGame; + return _CurrentGame; } diff --git a/src/game/QQPhysical.h b/src/game/QQPhysical.h index bb664cc..0dd0ce3 100644 --- a/src/game/QQPhysical.h +++ b/src/game/QQPhysical.h @@ -5,8 +5,13 @@ */ @protocol QQPhysical +// @property (nonatomic, readwrite, assign) float x; +// @property (nonatomic, readwrite, assign) float y; + + // FIXME: don't expose these, instead aggregate properties from body & fixtures/shapes @property (nonatomic, readonly) b2Body* body; @property (nonatomic, readonly) b2Fixture* fixture; + @end \ No newline at end of file diff --git a/src/game/ability/QQCooldown.h b/src/game/ability/QQCooldown.h new file mode 100644 index 0000000..596b58e --- /dev/null +++ b/src/game/ability/QQCooldown.h @@ -0,0 +1,47 @@ + + +/** + * Cooldown timer. + */ +@interface QQCooldown : NSObject { +@private + float _duration; + float _elapsed; +} + +/** Duration of this cooldown timer (ms). */ +@property (nonatomic, readwrite, assign) float duration; + +/** Elapsed time (ms) since last activated if not ready; otherwise {duration}. */ +@property (nonatomic, readwrite, assign) float elapsed; + +/** Whether Cooldown timer is ready to be activated. */ +@property (nonatomic, readwrite, getter=isReady) BOOL ready; + +/** Percent completed (elapsed / duration), clamped [0, 1.0]. */ +@property (nonatomic, readwrite) float ratio; + +/** + * Implies ready=NO. + */ +- (id) initWithDuration:(float)duration; +- (id) initWithDuration:(float)duration andReady:(BOOL)ready; + +/** + * Attempts to activate this cooldown, clearing the ready flag and setting elapsed to 0. + * If not ready, has no effect. + * @return Ready state. + */ +- (BOOL) activate; + +/** + * Advances the timer by {elapsed} milliseconds, updating ready state if necessary. + * @return Ready state. + */ +- (BOOL) tick:(float)elapsed; + + ++ (QQCooldown) cooldownWithDuration:(float)duration; ++ (QQCooldown) cooldownWithDuration:(float)duration andReady:(BOOL)ready; + +@end diff --git a/src/game/ability/QQCooldown.mm b/src/game/ability/QQCooldown.mm new file mode 100644 index 0000000..873bd54 --- /dev/null +++ b/src/game/ability/QQCooldown.mm @@ -0,0 +1,84 @@ +#import "QQCooldown.h" + + +@implementation QQCooldown + +/// properties + +@synthesize duration = _duration; +@synthesize elapsed = _elapsed; + +- (BOOL) ready { return (self.elapsed >= self.duration); } +- (void) setReady:(BOOL)newReady { + if (newReady == self.ready) + return; + if (newReady) + self.elapsed = self.duration; + else + self.elapsed = 0f; +} + +- (float) ratio { return fminf(1.0f, self.elapsed / self.duration); } +- (void) setRatio:(float)newRatio { + if (newRatio >= 1.0f) + self.elapsed = self.duration; + else if (newRatio <= 0.0f) + self.elapsed = 0f; + else + self.elapsed = newRatio * self.duration; +} + + +/// initializers + +- (id) initWithDuration:(float)duration { + return [self initWithDuration:duration andReady:NO]; +} + +- (id) initWithDuration:(float)duration andReady:(BOOL)ready { + if ((self = [super init])){ + _duration = duration; + _elapsed = (ready ? _duration : 0f); + } + return self; +} + + +/// methods + +/** + * Attempts to activate this cooldown, clearing the ready flag and setting elapsed to 0. Otherwise has no effect. + * @return Whether activation succeeded. + */ +- (BOOL) activate { + if (self.ready) { + self.ready = NO; + return YES; + } + return NO; +} + +/** + * Advances the timer by {elapsed} milliseconds, updating ready state if necessary. + * @return Ready state. + */ +- (BOOL) tick:(float)elapsed { + if (self.ready) + return YES; + self.elapsed += elapsed; + return self.ready; +} + + +/// convenience constructors + ++ (QQCooldown) cooldownWithDuration:(float)duration { + return [[[QQCooldown alloc] initWithDuration:duration] autorelease]; +} + ++ (QQCooldown) cooldownWithDuration:(float)duration andReady:(BOOL)ready { + return [[[QQCooldown alloc] initWithDuration:duration andReady:ready] autorelease]; +} + + +@end diff --git a/src/game/actor/QQActor.h b/src/game/actor/QQActor.h index b7fc953..3aefbe4 100644 --- a/src/game/actor/QQActor.h +++ b/src/game/actor/QQActor.h @@ -1,4 +1,5 @@ #include +#import "game/QQThing.h" #import "game/QQActive.h" #import "game/QQPhysical.h" #import "game/QQDisplayable.h" @@ -7,7 +8,7 @@ @class QQGame; -@interface QQActor : NSObject { +@interface QQActor : NSObject { @protected b2Body* _body; diff --git a/src/game/actor/QQUnit.h b/src/game/actor/QQUnit.h index 77517c9..6f05b9a 100644 --- a/src/game/actor/QQUnit.h +++ b/src/game/actor/QQUnit.h @@ -1,30 +1,14 @@ -#include -#import "Sparrow.h" - -#import "render/QQSparrowExtensions.h" - #import "game/actor/QQActor.h" -#import "game/actor/QQUnitDelegate.h" - -#import "physics/QQWorld.h" - +#import "game/QQThing.h" -//////////////////////////////////////////////////////////////////////////////////// -@interface QQUnit : QQActor { -@private - SPDisplayObject* _shape; - id _delegate; -} +@protocol QQUnit -//////////////////////////////////////////////////////////////////////////////////// -@property (nonatomic, retain, readwrite) SPDisplayObject* shape; -@property (nonatomic, retain, readwrite) id delegate; +@property (nonatomic, readonly) BOOL canAttack; -//////////////////////////////////////////////////////////////////////////////////// -- (id) initWithFile:(NSString*)fileName atX:(float)x y:(float)y; -- (id) initWithShape:(SPDisplayObject*)shape atX:(float)x y:(float)y; +- (void) attackTarget:(QQActor)actor; +- (void) attackToward:(NSPoint)point; +- (void) attackTowardX:(float)x y:(float)y; -- (void) onTouch:(SPTouchEvent*)event; @end diff --git a/src/game/actor/QQUnit.mm b/src/game/actor/QQUnit.mm deleted file mode 100644 index e6c0cac..0000000 --- a/src/game/actor/QQUnit.mm +++ /dev/null @@ -1,72 +0,0 @@ -#include -#import "Sparrow.h" -#import "QQUnit.h" - - -//////////////////////////////////////////////////////////////////////////////////// -@implementation QQUnit - -//////////////////////////////////////////////////////////////////////////////////// -@synthesize shape = _shape; -@synthesize delegate = _delegate; - -//////////////////////////////////////////////////////////////////////////////////// -- (id) init { - return [self initWithShape:[SPQuad quadWithWidth:50 height:50 color:0xff0000] atX:15 y:15]; -} - -//////////////////////////////////////////////////////////////////////////////////// -- (id) initWithFile:(NSString*)fileName atX:(float)x y:(float)y { - return [self initWithShape: - [[[SPImage alloc] autorelease] initWithContentsOfFile:fileName] - atX:x y:y]; -} - -//////////////////////////////////////////////////////////////////////////////////// -- (id) initWithShape:(SPDisplayObject*)shape atX:(float)x y:(float)y { - if ((self = [super initAtX:x y:y])) { - float px = self.world.scale; - self.shape = [shape setPositionX:x*px y:y*px]; - - b2PolygonShape box; - box.SetAsBox(shape.width/px, shape.height/px); - self.body->CreateFixture(&box, 5.0f); - - [self.game addEventListener:@selector(onTouch:) atObject:self forType:SP_EVENT_TYPE_TOUCH]; - } - return self; -} - -//////////////////////////////////////////////////////////////////////////////////// -- (void) dealloc { - [self.game removeEventListener:@selector(onTouch:) atObject:self forType:SP_EVENT_TYPE_TOUCH]; - [self.game removeChild:_shape]; - [_shape release]; - [super dealloc]; -} - -//////////////////////////////////////////////////////////////////////////////////// -- (void) setShape:(SPDisplayObject*)newShape { - if (_shape != newShape) { - [self.game removeChild:_shape]; - [_shape release]; - _shape = [newShape retain]; - [self.game addChild:_shape]; - } -} - -//////////////////////////////////////////////////////////////////////////////////// -- (void) onTouch:(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.body->SetTransform(b2Vec2(x/px, y/px), self.body->GetAngle()); - } -} - - -@end diff --git a/src/prefix.pch b/src/prefix.pch index 45a03fd..f3e2b5c 100644 --- a/src/prefix.pch +++ b/src/prefix.pch @@ -12,3 +12,5 @@ #import #import #endif + +#import "TanksMacros.h" -- 1.7.0.4