Fixes registration on Circle. Sparrow vs Box2D debug rendering should now be the...
authordsc <david.schoonover@gmail.com>
Wed, 1 Jun 2011 03:28:54 +0000 (20:28 -0700)
committerdsc <david.schoonover@gmail.com>
Wed, 1 Jun 2011 03:28:54 +0000 (20:28 -0700)
17 files changed:
libs/sparrow/src/Classes/SPDisplayObject.h
libs/sparrow/src/Classes/SPDisplayObject.m
libs/sparrow/src/Classes/SPQuad.m
libs/sparrow/src/Extras/SHCircle.h
libs/sparrow/src/Extras/SHCircle.m
src/Tanks.h
src/game/QQActive.h
src/game/QQDisplayable.h
src/game/QQGame.mm
src/game/QQPhysical.h
src/game/actor/QQActor.mm
src/game/actor/QQActors.h [new file with mode: 0644]
src/game/actor/QQUnit.h
src/game/actor/QQUnit.mm
src/game/actor/unit/QQTank.mm
src/render/QQSparrowExtensions.mm
tanks.xcodeproj/project.pbxproj

index e6b931c..bcaf3e4 100644 (file)
@@ -88,6 +88,7 @@
     float mAlpha;
     BOOL mVisible;
     BOOL mTouchable;
+    BOOL mAutoUpdateReg;
     
     SPDisplayObjectContainer *mParent;    
     double mLastTouchTimestamp;
 /// The y coordinate of the object's rotational origin in local coordinates.
 @property (nonatomic, assign) float registrationY;
 
+/// Automatically updates registration to be half the object's size if concrete width or height changes.
+/// True by default; note that changes to scale do not effect concrete size.
+@property (nonatomic, readwrite, assign) BOOL autoUpdateReg;
+
 /// The rotation of the object in radians. (In Sparrow, all angles are measured in radians.)
 @property (nonatomic, assign) float rotation;
 
index d7c0378..fb72245 100644 (file)
@@ -26,6 +26,7 @@
 @synthesize scaleY = mScaleY;
 @synthesize registrationX = mRegX;
 @synthesize registrationY = mRegY;
+@synthesize autoUpdateReg = mAutoUpdateReg;
 @synthesize rotation = mRotationZ;
 @synthesize parent = mParent;
 @synthesize alpha = mAlpha;
@@ -40,7 +41,7 @@
     {
         [self release];
         [NSException raise:SP_EXC_ABSTRACT_CLASS 
-                    format:@"Attempting to initialize abstract class SPDisplayObject."];        
+                    format:@"Attempting to initialize abstract class SPDisplayObject."];
         return nil;
     }    
     #endif
@@ -52,6 +53,7 @@
         mScaleY = 1.0f;
         mRegX = 0;
         mRegY = 0;
+        mAutoUpdateReg = YES;
         mRotationZ = 0;
         mVisible = YES;
         mTouchable = YES;
     return [matrix autorelease];
 }
 
+- (NSString*) description {
+    return [NSString stringWithFormat:@"[%@ pos=(%f,%f), rotation=%f @ (%f,%f), scale=(%f,%f)]",
+        [super description], self.x,self.y, self.rotation, self.registrationX,self.registrationY, self.scaleX,self.scaleY];
+}
+
+
 @end
 
 // -------------------------------------------------------------------------------------------------
index 59400dd..5285a21 100644 (file)
 {
     if ((self = [super init]))
     {
-        mVertexCoords[2] = width; 
+        mVertexCoords[2] = width;
         mVertexCoords[5] = height; 
         mVertexCoords[6] = width;
         mVertexCoords[7] = height;
         
         self.color = color;
+        if (self.autoUpdateReg) {
+            self.registrationX = width  * 0.5f;
+            self.registrationY = height * 0.5f;
+        }
     }
-    return self;    
+    return self;
 }
 
 - (id)initWithWidth:(float)width height:(float)height
index 8324612..0965efd 100644 (file)
@@ -27,8 +27,6 @@
        float mCenterRotation;
 }
 
-@property (nonatomic, assign) float centerX;
-@property (nonatomic, assign) float centerY;
 @property (nonatomic, assign) float radiusX;
 @property (nonatomic, assign) float radiusY;
 @property (nonatomic, assign) BOOL fill;
index 86c01a5..bed42a6 100644 (file)
                mWidth = width;
                mHeight = height;
                
+               if (self.autoUpdateReg) {
+                       self.registrationX = width  * 0.5f;
+                       self.registrationY = height * 0.5f;
+               }
+               
+               
                mFill = YES;
                self.color = SP_WHITE;
                mBorder = NO;
     return [SPRectangle rectangleWithX:minX y:minY width:maxX-minX height:maxY-minY];    
 }
 
-- (void)setCenterX:(float)centerX {
-       self.x = centerX - (mWidth/2);
-}
-
-- (float)centerX {
-       return self.x + (mWidth/2);
-}
-
-- (void)setCenterY:(float)centerY {
-       self.y = centerY - (mHeight/2);
-}
-
-- (float)centerY {
-       return self.y + (mHeight/2);
-}
-
 - (void)setRadiusX:(float)radiusX {
        self.width = radiusX*2;
 }
 
 - (void)setWidth:(float)width {
        mWidth = width;
+       if (self.autoUpdateReg) self.registrationX = width  * 0.5f;
        [self drawVertices];
        [super setWidth:mWidth];
 }
 
 - (void)setHeight:(float)height {
        mHeight = height;
+       if (self.autoUpdateReg) self.registrationY = height * 0.5f;
        [self drawVertices];
        [super setHeight:mHeight];
 }
index 5234a2e..c9e4885 100644 (file)
@@ -1,2 +1,6 @@
+#ifndef TANKS_H
+#define TANKS_H
+#define TANKS_DEBUG_LOG 1
+#endif
 
 #import "render/QQSparrowExtensions.h"
index 9335dab..be63ea8 100644 (file)
@@ -5,7 +5,8 @@
  */
 @protocol QQActive <QQThing>
 
-@property (nonatomic, getter=isActive) BOOL active;
+@property (nonatomic, readwrite, getter=isActive) BOOL active;
+// @property (nonatomic, readwrite, getter=isSleeping) BOOL sleeping;
 
 - (void) tick:(float)elapsed;
 - (void) act;
index 4d0852e..ab60dbf 100644 (file)
@@ -9,10 +9,6 @@
 @property (nonatomic, readwrite, assign, getter=isDirty) BOOL dirty; // TODO: implement this and fix various [shape setPosition] calls
 @property (nonatomic, readwrite, retain) SPDisplayObject* shape;
 
-/** Intended center of the shape in points. */
-@property (nonatomic, readwrite, assign) float shapeCenterX;
-@property (nonatomic, readwrite, assign) float shapeCenterY;
-
 /**
  * Called to setup the Sparrow shape.
  */
index a44f611..7130e52 100644 (file)
@@ -1,8 +1,8 @@
-#import "QQGame.h"
-#import "game/actor/unit/QQTank.h"
-#import "game/actor/QQUnit.h"
 #import <Box2D/Box2D.h>
 
+#import "game/QQGame.h"
+#import "game/actor/QQActors.h"
+
 
 
 static QQGame* _CurrentGame = NULL;
@@ -10,20 +10,14 @@ static QQGame* _CurrentGame = NULL;
 
 
 @interface QQGame ()
+
 - (void) onEnterFrame:(SPEnterFrameEvent*)event;
+
 @end
 
 
 @implementation QQGame
 
-@synthesize world  = _world;
-@synthesize level  = _level;
-@synthesize actors = _actors;
-
-@synthesize ticks  = _ticks;
-@synthesize paused = _running;
-@synthesize debugDrawingEnabled = _debugDrawingEnabled;
-
 
 - (id) init {
     if (_CurrentGame) {
@@ -49,7 +43,10 @@ static QQGame* _CurrentGame = NULL;
         [_root addChild:_debugView];
         self.debugDrawingEnabled = YES;
         
-        _actors = [[NSMutableArray alloc] initWithCapacity:10];
+        _actors  = [[NSMutableSet alloc] initWithCapacity:10];
+        _awake   = [[NSMutableSet alloc] initWithCapacity:10];
+        _units   = [[NSMutableSet alloc] initWithCapacity:10];
+        _bullets = [[NSMutableSet alloc] initWithCapacity:10];
         
         CGSize frame = [UIScreen mainScreen].applicationFrame.size;
         float wMax = frame.width  / _world.scale;
@@ -64,11 +61,16 @@ static QQGame* _CurrentGame = NULL;
     [self removeEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
     [self removeAllChildren];
     
-    [_actors removeAllObjects];
-    [_actors release];
+    NSMutableSet* sets[] = {_actors, _awake, _units, _bullets};
+    for (int i = 0; i < 4; i++) {
+        NSMutableSet* set = sets[i];
+        [set removeAllObjects];
+        [set release];
+    }
     
     [_level release];
     [_debugView release];
+    [_root release];
     [_world release];
     
     _CurrentGame = NULL;
@@ -78,6 +80,16 @@ static QQGame* _CurrentGame = NULL;
 
 /// properties
 
+@synthesize world  = _world;
+@synthesize level  = _level;
+
+@synthesize actors = _actors;
+
+@synthesize ticks  = _ticks;
+@synthesize paused = _running;
+
+@synthesize debugDrawingEnabled = _debugDrawingEnabled;
+
 - (void) setDebugDrawingEnabled:(BOOL)enable {
     _debugDrawingEnabled = _debugView.visible = enable;
 }
@@ -86,27 +98,21 @@ static QQGame* _CurrentGame = NULL;
 
 /// methods
 
-- (void) start {
-    if (!_running) {
-        _running = YES;
-        [self addEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
-    }
-}
-
-- (void) stop {
-    if (_running) {
-        [self removeEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
-        _running = NO;
-    }
-}
-
 - (QQGame*) addActor:(QQActor*)actor {
     [_actors addObject:actor];
+    [_awake addObject:actor];
+    if ([actor isKindOfClass:[QQUnit class]])
+        [_units addObject:actor];
+    if ([actor isKindOfClass:[QQBullet class]])
+        [_bullets addObject:actor];
     return self;
 }
 
 - (QQGame*) removeActor:(QQActor*)actor {
-    [_actors removeObject:actor];
+    [_actors  removeObject:actor];
+    [_awake   removeObject:actor];
+    [_units   removeObject:actor];
+    [_bullets removeObject:actor];
     return self;
 }
 
@@ -118,7 +124,7 @@ static QQGame* _CurrentGame = NULL;
 - (void) tick:(float)elapsed {
     _ticks++;
     
-#ifdef DEBUG_LOG
+#if TANKS_DEBUG_LOG
     if ((_ticks % 100) == 0) {
         NSLog(@"[%ld] Time passed since last 100 frames: %f", _ticks, elapsed);
         for (QQActor* actor in self.actors) {
@@ -128,11 +134,28 @@ static QQGame* _CurrentGame = NULL;
     }
 #endif
     
-    for (QQActor* actor in self.actors) [actor tick:elapsed]; // XXX: self.awakeAgents
+    for (QQActor* actor in _awake) [actor tick:elapsed];
     [self.world step];
-    for (QQActor* actor in self.actors) [actor draw];    // XXX: self.drawableAgents
+    for (QQActor* actor in self.actors) [actor draw];
+}
+
+
+- (void) start {
+    if (!_running) {
+        _running = YES;
+        [self addEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
+    }
 }
 
+- (void) stop {
+    if (_running) {
+        [self removeEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
+        _running = NO;
+    }
+}
+
+
+
 + (QQGame*) current {
     if (!_CurrentGame)
         [[[QQGame alloc] init]  // init assigns to singleton, but singleton is a weakref,
index 72203b3..efe27e0 100644 (file)
@@ -10,6 +10,7 @@
 
 /// The y coordinate in the simulation.
 @property (nonatomic, readwrite, assign) float y;
+
 @property (nonatomic, readwrite) CGPoint position;
 - (void) setPositionX:(float)x y:(float)y;
 
index 92a4642..a5ebb92 100644 (file)
 @synthesize dirty    = _dirty;
 @synthesize delegate = _delegate;
 
-@dynamic shapeCenterX;
-@dynamic shapeCenterY;
+@dynamic shape;
 
 
 - (QQGame*)  game  { return QQGame.current; }
 - (QQWorld*) world { return self.game.world; }
 
-- (SPDisplayObject*) shape { return nil; }
-- (void) setShape:(SPDisplayObject*)newShape {}
-
 - (b2Body*) body { return _body; }
 - (b2Fixture*) fixture { return nil; }
 
 
 - (void) updateShapeX:(float)x y:(float)y rotation:(float)r {
     [self updateShapeX:x y:y];
-    SPDisplayObject* shape = self.shape;
-    shape.registrationX = self.shapeCenterX;
-    shape.registrationY = self.shapeCenterY;
-    shape.rotation = r;
+    // SPDisplayObject* shape = self.shape;
+    // shape.registrationX = self.shapeCenterX;
+    // shape.registrationY = self.shapeCenterY;
+    self.shape.rotation = r;
 }
 
 - (void) updateShape {
 
 - (void) setupPhysics {}
 
-- (NSString *)description {
+- (NSString*) description {
     b2Transform trans = self.body->GetTransform();
     b2Vec2 pos = trans.position;
     //b2Vec2 v = actor.body->GetLinearVelocity();
     SPDisplayObject* s = self.shape;
-    return [NSString stringWithFormat:@"[%@ w=%f, h=%f, pos=(%f,%f), rotation=%f @ (%f,%f), scale=(%f,%f), shape=[%@ center=(%f,%f)]]",
-        [super description], s.width,s.height, pos.x,pos.y, trans.GetAngle(), s.registrationX,s.registrationY, 
-        s.scaleX,s.scaleY, s, self.shapeCenterX,self.shapeCenterY];
+    return [NSString stringWithFormat:@"[%@ box2d=[ (%f,%f) rotation=%f], shape=%@]",
+        [super description], pos.x,pos.y, trans.GetAngle(), s];
 }
 
 
diff --git a/src/game/actor/QQActors.h b/src/game/actor/QQActors.h
new file mode 100644 (file)
index 0000000..bd83bb5
--- /dev/null
@@ -0,0 +1,5 @@
+#import "QQActor.h"
+#import "QQActorDelegate.h"
+#import "QQUnit.h"
+#import "bullet/QQBullet.h"
+#import "unit/QQTank.h"
index a69d48d..e963b45 100644 (file)
@@ -11,8 +11,6 @@
 
 @private
     SPDisplayObject* _shape;
-    float _shapeCenterX;
-    float _shapeCenterY;
 }
 
 /// properties
index a9b0e5b..6a899d6 100644 (file)
 @dynamic game;
 
 @synthesize shape = _shape;
-@synthesize shapeCenterX = _shapeCenterX;
-@synthesize shapeCenterY = _shapeCenterY;
 
+- (float) shapeCenterX {            return self.shape.registrationX; }
+- (void) setShapeCenterX:(float)x { self.shape.registrationX = x; }
+- (float) shapeCenterY {            return self.shape.registrationY; }
+- (void) setShapeCenterY:(float)y { self.shape.registrationY = y; }
 
 - (BOOL) canAttack { return NO; }
 
@@ -28,7 +30,8 @@
 }
 
 - (id) initAtX:(float)x y:(float)y width:(float)w height:(float)h color:(uint)color {
-    return [self initAtX:x y:y withShape:[SPQuad quadWithWidth:w height:h color:color]];
+    SPQuad* shape = [SPQuad quadWithWidth:w height:h color:color];
+    return [self initAtX:x y:y withShape:shape];
 }
 
 - (id) initAtX:(float)x y:(float)y withShape:(SPDisplayObject*)shape {
@@ -57,8 +60,6 @@
         [_shape release];
         
         _shape = [newShape retain];
-        _shapeCenterX = _shape.width  * 0.5f;
-        _shapeCenterY = _shape.height * 0.5f;
         [self updateShape];
         [self.game.level addChild:_shape];
     }
@@ -76,7 +77,6 @@
 
 - (void) draw {
     [super draw];
-    if ((self.game.ticks % 50) == 0) NSLog(@"%@", self);
 }
 
 
index cb6192a..fa94b81 100644 (file)
@@ -34,7 +34,7 @@
 }
 
 - (void) onTouch:(SPTouchEvent*)event {
-    SPTouch* touch = [[event touchesWithTarget:self.shape.parent] anyObject];
+    SPTouch* touch = [[event touchesWithTarget:(SPDisplayObject*)self.game] anyObject];
     if (touch && [self.coolAtk activate]) {
         // Touch's normal vector in local coords (rel unit origin)
         SPPoint* normVec = [[[touch locationInSpace:self.shape.parent] subtractPoint:self.shape.position] normalize];
index aaa9f4c..479c88f 100644 (file)
@@ -23,7 +23,7 @@
 - (float) centerY { return self.y + self.registrationY; }
 - (void) setCenterY:(float)y { self.y = y - self.registrationY; }
 
-/** Sets coordinates of the object relative to the local coordinates of the parent. */
+/** Sets coordinates of the object relative to the local coordinates of the parent, modified by the registration point. */
 - (id) setCenterX:(float)x y:(float)y {
     self.centerX = x;
     self.centerY = y;
index 72e59da..ce9facc 100644 (file)
@@ -31,6 +31,7 @@
                492D8115138C07540042D918 /* SXFPSMeter.h in Headers */ = {isa = PBXBuildFile; fileRef = 492D810A138C07540042D918 /* SXFPSMeter.h */; };
                492D8116138C07540042D918 /* SXFPSMeter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492D810B138C07540042D918 /* SXFPSMeter.m */; };
                494DE9971376927C00FDB3D7 /* libBox2D.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 494DE9961376927C00FDB3D7 /* libBox2D.a */; };
+               4978AD0E1395E5CE00930447 /* QQActors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4978AD0D1395E5CE00930447 /* QQActors.h */; };
                4995ABB213816CCE00334646 /* QQGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E834A513812427007A6598 /* QQGame.h */; };
                4995ABB313816CD400334646 /* QQUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E834A213812427007A6598 /* QQUnit.h */; };
                4995ABF91381C46B00334646 /* Icon-iPad.png in Resources */ = {isa = PBXBuildFile; fileRef = 4995ABCA1381C46B00334646 /* Icon-iPad.png */; };
                492D810A138C07540042D918 /* SXFPSMeter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SXFPSMeter.h; sourceTree = "<group>"; };
                492D810B138C07540042D918 /* SXFPSMeter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SXFPSMeter.m; sourceTree = "<group>"; };
                494DE9961376927C00FDB3D7 /* libBox2D.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libBox2D.a; sourceTree = SOURCE_ROOT; };
+               4978AD0D1395E5CE00930447 /* QQActors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQActors.h; sourceTree = "<group>"; };
                4995ABCA1381C46B00334646 /* Icon-iPad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-iPad.png"; sourceTree = "<group>"; };
                4995ABCB1381C46B00334646 /* Icon-iPhone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-iPhone.png"; sourceTree = "<group>"; };
                4995ABCC1381C46B00334646 /* Icon-iPhone@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-iPhone@2x.png"; sourceTree = "<group>"; };
                                492D80E9138BA4B40042D918 /* QQTank.h */,
                                492D80EA138BA4B40042D918 /* QQTank.mm */,
                        );
-                       name = unit;
-                       path = actor/unit;
+                       path = unit;
                        sourceTree = "<group>";
                };
                492D80ED138BA4BC0042D918 /* bullet */ = {
                                492D80EE138BA4BC0042D918 /* QQBullet.h */,
                                492D80EF138BA4BC0042D918 /* QQBullet.mm */,
                        );
-                       name = bullet;
-                       path = actor/bullet;
+                       path = bullet;
                        sourceTree = "<group>";
                };
                492D8100138C07540042D918 /* Extras */ = {
                        isa = PBXGroup;
                        children = (
                                49193BEE139280180005B3DD /* map */,
-                               492D80ED138BA4BC0042D918 /* bullet */,
-                               492D80E8138BA4B40042D918 /* unit */,
                                492D80DB138BA4910042D918 /* ability */,
                                49E8349F13812427007A6598 /* actor */,
+                               492D80F2138BA4CE0042D918 /* QQThing.h */,
                                49E8349E13812427007A6598 /* QQActive.h */,
                                49E834A413812427007A6598 /* QQDisplayable.h */,
                                492D80CB138B231B0042D918 /* QQPhysical.h */,
-                               492D80F2138BA4CE0042D918 /* QQThing.h */,
                                49E834A513812427007A6598 /* QQGame.h */,
                                49E834A613812427007A6598 /* QQGame.mm */,
                        );
                49E8349F13812427007A6598 /* actor */ = {
                        isa = PBXGroup;
                        children = (
-                               492D80FE138BCC9F0042D918 /* QQActorDelegate.h */,
+                               492D80ED138BA4BC0042D918 /* bullet */,
+                               492D80E8138BA4B40042D918 /* unit */,
+                               4978AD0D1395E5CE00930447 /* QQActors.h */,
                                49E834A013812427007A6598 /* QQActor.h */,
                                49E834A113812427007A6598 /* QQActor.mm */,
+                               492D80FE138BCC9F0042D918 /* QQActorDelegate.h */,
                                49E834A213812427007A6598 /* QQUnit.h */,
                                492D80FC138BCA840042D918 /* QQUnit.mm */,
                        );
                49F2D9B313764666000B6B8C /* render */ = {
                        isa = PBXGroup;
                        children = (
+                               4B8B2A4D137D090D00CA4076 /* animation */,
                                49D8645B1392DB2800BC341C /* QQShape.h */,
                                49D8645C1392DB2800BC341C /* QQShape.mm */,
-                               4B8B2A4D137D090D00CA4076 /* animation */,
                                49E834D1138166A6007A6598 /* QQSparrowExtensions.h */,
                                49E834D2138166A6007A6598 /* QQSparrowExtensions.mm */,
                        );
                                492D80FF138BCC9F0042D918 /* QQActorDelegate.h in Headers */,
                                49193BF5139280180005B3DD /* QQLevel.h in Headers */,
                                49D8645D1392DB2800BC341C /* QQShape.h in Headers */,
+                               4978AD0E1395E5CE00930447 /* QQActors.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };