float mY;
float mScaleX;
float mScaleY;
+ float mRegX;
+ float mRegY;
float mRotationZ;
float mAlpha;
BOOL mVisible;
/// @name Properties
/// ----------------
-/// The x coordinates of the object relative to the local coordinates of the parent.
+/// The x coordinate of the object relative to the local coordinates of the parent.
@property (nonatomic, assign) float x;
-/// The y coordinates of the object relative to the local coordinates of the parent.
+/// The y coordinate of the object relative to the local coordinates of the parent.
@property (nonatomic, assign) float y;
/// The horizontal scale factor. "1" means no scale, negative values flip the object.
/// The height of the object in points.
@property (nonatomic, assign) float height;
+/// The x coordinate of the object's rotational origin in local coordinates.
+@property (nonatomic, assign) float registrationX;
+
+/// The y coordinate of the object's rotational origin in local coordinates.
+@property (nonatomic, assign) float registrationY;
+
/// The rotation of the object in radians. (In Sparrow, all angles are measured in radians.)
@property (nonatomic, assign) float rotation;
@synthesize y = mY;
@synthesize scaleX = mScaleX;
@synthesize scaleY = mScaleY;
+@synthesize registrationX = mRegX;
+@synthesize registrationY = mRegY;
@synthesize rotation = mRotationZ;
@synthesize parent = mParent;
@synthesize alpha = mAlpha;
mAlpha = 1.0f;
mScaleX = 1.0f;
mScaleY = 1.0f;
+ mRegX = 0;
+ mRegY = 0;
+ mRotationZ = 0;
mVisible = YES;
mTouchable = YES;
}
{
SPMatrix *matrix = [[SPMatrix alloc] init];
- if (mScaleX != 1.0f || mScaleY != 1.0f) [matrix scaleXBy:mScaleX yBy:mScaleY];
- if (mRotationZ != 0.0f) [matrix rotateBy:mRotationZ];
if (mX != 0.0f || mY != 0.0f) [matrix translateXBy:mX yBy:mY];
+ if (mRotationZ != 0.0f) {
+ bool regMatters = (mRegX != 0.0f || mRegY != 0.0f);
+ if (regMatters) [matrix translateXBy:mRegX yBy:mRegY];
+ [matrix rotateBy:mRotationZ];
+ if (regMatters) [matrix translateXBy:-mRegX yBy:-mRegY];
+ }
+ if (mScaleX != 1.0f || mScaleY != 1.0f) [matrix scaleXBy:mScaleX yBy:mScaleY];
return [matrix autorelease];
}
- (id)init
{
- if (self = [super init])
+ if ((self = [super init]))
{
mBoundTextureID = UINT_MAX;
mPremultipliedAlpha = YES;
{
float x = object.x;
float y = object.y;
+ float regX = object.registrationX;
+ float regY = object.registrationY;
float rotation = object.rotation;
float scaleX = object.scaleX;
float scaleY = object.scaleY;
if (x != 0.0f || y != 0.0f) glTranslatef(x, y, 0);
- if (rotation != 0.0f) glRotatef(SP_R2D(rotation), 0.0f, 0.0f, 1.0f);
- if (scaleX != 0.0f || scaleY != 0.0f) glScalef(scaleX, scaleY, 1.0f);
+ if (rotation != 0.0f) {
+ bool regMatters = (regX != 0.0f || regY != 0.0f);
+ if (regMatters) glTranslatef(regX, regY, 0);
+ glRotatef(SP_R2D(rotation), 0.0f, 0.0f, 1.0f);
+ if (regMatters) glTranslatef(-regX, -regY, 0);
+ }
+ if (scaleX != 0.0f || scaleY != 0.0f) glScalef(scaleX, scaleY, 1.0f);
}
+ (void)setupOrthographicRenderingWithLeft:(float)left right:(float)right
@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.
*/
#import "Sparrow.h"
#import "physics/QQWorld.h"
+#import "physics/debug/QQPhysicsDebugView.h"
#import "game/actor/QQActor.h"
+#import "game/map/QQLevel.h"
@interface QQGame : SPStage {
- long _ticks;
-
@private
QQWorld* _world;
+ QQLevel* _level;
+ SPSprite* _root;
+
NSMutableSet* _actors;
NSMutableSet* _awake;
NSMutableSet* _units;
NSMutableSet* _bullets;
+
+ QQPhysicsDebugView* _debugView;
+ BOOL _debugDrawingEnabled;
+
+ long _ticks;
+ BOOL _running;
}
-@property (nonatomic, assign, readonly) long ticks;
+@property (nonatomic, readonly) QQWorld* world;
+@property (nonatomic, readonly) QQLevel* level;
+@property (nonatomic, readonly) NSSet* actors;
+
+@property (nonatomic, readonly, assign) long ticks;
+@property (nonatomic, readonly, getter=isPaused) BOOL paused;
+@property (nonatomic, readwrite, assign) BOOL debugDrawingEnabled;
+
+- (void) start;
+- (void) stop;
-@property (nonatomic, retain) QQWorld* world;
-@property (nonatomic, retain) NSSet* actors;
- (void) tick:(float)elapsed;
@implementation QQGame
-@synthesize ticks = _ticks;
@synthesize world = _world;
+@synthesize level = _level;
@synthesize actors = _actors;
+@synthesize ticks = _ticks;
+@synthesize paused = _running;
+@synthesize debugDrawingEnabled = _debugDrawingEnabled;
+
- (id) init {
if (_CurrentGame) {
if ( (self = [super init]) ){
_CurrentGame = self;
_ticks = 0;
- _actors = [[NSMutableArray alloc] initWithCapacity:10];
+ _running = NO;
+
_world = [[QQWorld alloc] init];
- _world.debugDrawingEnabled = YES;
+ _root = [SPSprite sprite];
+ [self addChild:_root];
+ _level = [[QQLevel alloc] init];
+ [_root addChild:_level];
+ _debugView = [[QQPhysicsDebugView alloc] initWithWorld:_world];
+ [_root addChild:_debugView];
+ self.debugDrawingEnabled = YES;
+
+ _actors = [[NSMutableArray alloc] initWithCapacity:10];
- CGSize screen = [UIScreen mainScreen].bounds.size;
- float wMax = screen.width / _world.scale;
- float hMax = screen.height / _world.scale;
+ CGSize frame = [UIScreen mainScreen].applicationFrame.size;
+ float wMax = frame.width / _world.scale;
+ float hMax = frame.height / _world.scale;
[[[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];
-
- [self addEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
}
return self;
}
- (void) dealloc {
[self removeEventListener:@selector(onEnterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME];
+ [self removeAllChildren];
+
[_actors removeAllObjects];
[_actors release];
+
+ [_level release];
+ [_debugView release];
[_world release];
+
_CurrentGame = NULL;
[super dealloc];
}
+
+/// properties
+
+- (void) setDebugDrawingEnabled:(BOOL)enable {
+ _debugDrawingEnabled = _debugView.visible = enable;
+}
+
+
+
+/// 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];
return self;
- (void) onEnterFrame:(SPEnterFrameEvent*)event {
- [self tick:event.passedTime];
+ if (_running) [self tick:event.passedTime];
}
- (void) tick:(float)elapsed {
_ticks++;
+
+#ifdef DEBUG_LOG
if ((_ticks % 100) == 0) {
NSLog(@"[%ld] Time passed since last 100 frames: %f", _ticks, elapsed);
for (QQActor* actor in self.actors) {
b2Vec2 v = actor.body->GetLinearVelocity();
- NSLog(@"[%@ pos:(%f,%f) impulse:(%f,%f)]", actor, actor.x,actor.y, v.x,v.y);
+ NSLog(@"[%@ impulse:(%f,%f)]", actor, v.x,v.y);
}
}
+#endif
for (QQActor* actor in self.actors) [actor tick:elapsed]; // XXX: self.awakeAgents
[self.world step];
*/
@protocol QQPhysical
+/// The x coordinate in the simulation.
@property (nonatomic, readwrite, assign) float x;
+
+/// The y coordinate in the simulation.
@property (nonatomic, readwrite, assign) float y;
@property (nonatomic, readwrite) CGPoint position;
-
- (void) setPositionX:(float)x y:(float)y;
+@property (nonatomic, readwrite, assign) float rotation;
+
+/// The width of the object in simulation units.
+//@property (nonatomic, assign) float width;
+
+/// 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;
- (id) initAtX:(float)x y:(float)y;
- (id) initType:(b2BodyType)type atX:(float)x y:(float)y;
+/// internal methods
+
+/** Updates the Shape using values from Box2D. */
+- (void) updateShape;
+
+/** Updates the Shape's position, pulling rotation from Box2D. */
+- (void) updateShapeX:(float)x y:(float)y;
+
+/** Updates the Shape's position and rotation. */
+- (void) updateShapeX:(float)x y:(float)y rotation:(float)r;
+
@end
@synthesize dirty = _dirty;
@synthesize delegate = _delegate;
+@dynamic shapeCenterX;
+@dynamic shapeCenterY;
+
+
- (QQGame*) game { return QQGame.current; }
- (QQWorld*) world { return self.game.world; }
- (b2Body*) body { return _body; }
- (b2Fixture*) fixture { return nil; }
+- (float) rotation { return self.body->GetAngle(); }
+- (void) setRotation:(float)r { self.body->SetTransform(self.body->GetPosition(), r); }
- (CGPoint) position {
b2Vec2 pos = self.body->GetPosition();
}
- (void) setPositionX:(float)x y:(float)y {
self.body->SetTransform(b2Vec2(x,y), self.body->GetAngle());
+ // [self updateShapeX:x y:y];
+}
+
+- (void) updateShapeX:(float)x y:(float)y {
float px = self.world.scale;
- [self.shape setPositionX:x*px y:y*px];
+ [self.shape setCenterX:x*px y:y*px];
+}
+
+- (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;
+}
+
+- (void) updateShape {
+ b2Transform trans = self.body->GetTransform();
+ [self updateShapeX:trans.position.x y:trans.position.y rotation:trans.GetAngle()];
}
+
- (float) x { return self.body->GetPosition().x; }
- (void) setX:(float)x { [self setPositionX:x y:self.y]; }
}
- (void) draw {
- float px = self.world.scale;
- b2Vec2 pos = self.body->GetPosition();
- [self.shape setPositionX:pos.x*px y:pos.y*px];
+ [self updateShape];
}
- (void) setupPhysics {}
+- (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];
+}
+
+
+
@end
@private
SPDisplayObject* _shape;
+ float _shapeCenterX;
+ float _shapeCenterY;
}
/// properties
#include <Box2D/Box2D.h>
#import "Sparrow.h"
-#import "QQUnit.h"
+#import "game/actor/QQUnit.h"
+#import "game/QQGame.h"
#import "render/QQSparrowExtensions.h"
@dynamic game;
@synthesize shape = _shape;
+@synthesize shapeCenterX = _shapeCenterX;
+@synthesize shapeCenterY = _shapeCenterY;
+
- (BOOL) canAttack { return NO; }
- (void) setShape:(SPDisplayObject*)newShape {
if (_shape != newShape) {
- [self.game removeChild:_shape];
+ [self.game.level removeChild:_shape];
[_shape release];
_shape = [newShape retain];
- float px = self.world.scale;
- [_shape setPositionX:self.x*px y:self.y*px];
- [self.game addChild:_shape];
+ _shapeCenterX = _shape.width * 0.5f;
+ _shapeCenterY = _shape.height * 0.5f;
+ [self updateShape];
+ [self.game.level addChild:_shape];
}
}
[self setShape:[[[SPImage alloc] autorelease] initWithContentsOfFile:filename]];
}
+- (void) act {
+ if ((self.game.ticks % 50) == 0) {
+ self.rotation += b2_pi / 8;
+ }
+}
+
+- (void) draw {
+ [super draw];
+ if ((self.game.ticks % 50) == 0) NSLog(@"%@", self);
+}
- (void) attack:(QQActor*)actor {
--- /dev/null
+#import "Sparrow.h"
+
+@interface QQLevel : SPDisplayObjectContainer {
+@private
+
+}
+
+
+
+@end
--- /dev/null
+#import "QQLevel.h"
+
+
+@implementation QQLevel
+
+- (id) init {
+ if ((self = [super init])){
+
+ }
+ return self;
+}
+
+- (void) render:(SPRenderSupport*)support {
+ // glTranslatef(100, 100, 0);
+ [super render:support];
+}
+
+@end
float _timestep;
int _velocityIterations;
int _positionIterations;
- BOOL _debugDrawingEnabled;
+
float _scale;
}
@property (nonatomic, assign) float timestep;
@property (nonatomic, assign) int velocityIterations;
@property (nonatomic, assign) int positionIterations;
-@property (nonatomic, assign) BOOL debugDrawingEnabled;
-@property (nonatomic, assign) float scale; // pixels per meter
+
+@property (nonatomic, assign) float scale; // pixels per meter // TODO: move this somewhere else!
-- (QQWorld*) init;
+- (id) init;
- (void) setGravityX:(float)x y:(float)y;
@synthesize timestep = _timestep;
@synthesize velocityIterations = _velocityIterations;
@synthesize positionIterations = _positionIterations;
-@synthesize debugDrawingEnabled = _debugDrawingEnabled;
@synthesize scale = _scale;
@synthesize world = _world;
-- (QQWorld*) init {
+- (id) init {
if ((self = [super init])) {
_timestep = 1.0f/60.0f;
_velocityIterations = 10;
_positionIterations = 10;
- _debugDrawingEnabled = NO;
_scale = 5.0f;
_world = new b2World(b2Vec2(0.0f, 0.0f), true); // b2World(gravity, doSleep)
- _debugDraw = new QQGLESDebugDraw();
+ _debugDraw = new QQGLESDebugDraw(0.75f);
+ _debugDraw->SetAllFlags();
_world->SetDebugDraw(_debugDraw);
_walls = [[NSMutableArray alloc] initWithCapacity:4];
- CGSize screen = [UIScreen mainScreen].bounds.size;
- float pad = 5;
- float w = screen.width / _scale;
- float h = screen.height / _scale;
- b2Vec2 origin = b2Vec2(pad, pad);
- b2Vec2 horz = b2Vec2(w-2*pad, pad);
- b2Vec2 vert = b2Vec2(pad, h-2*pad);
+ CGSize screen = [UIScreen mainScreen].applicationFrame.size;
+ float padv = 5;
+ float w = screen.width / _scale - 2*padv;
+ float h = screen.height / _scale - 2*padv;
- b2Vec2 positions[] = {
- b2Vec2(w*0.5f, h*0.0f),
- b2Vec2(w*0.5f, h*1.0f),
- b2Vec2(w*0.0f, h*0.5f),
- b2Vec2(w*1.0f, h*0.5f)
- };
- b2Vec2 bounds[] = {horz, horz, vert, vert};
+ b2Vec2 origin = b2Vec2(0, 0);
+ b2Vec2 pad = b2Vec2(padv, padv);
+ b2Vec2 bound = b2Vec2(w, h);
+
+ b2Vec2 horz = b2Vec2(w, 0);
+ b2Vec2 hpos = horz + pad;
+ b2Vec2 vert = b2Vec2(0, h);
+ b2Vec2 vpos = vert + pad;
+
+ b2Vec2 positions[] = {pad, vpos, pad, hpos};
+ b2Vec2 endpoints[] = {horz, horz, vert, vert};
for (int i=0; i<4; ++i) {
b2BodyDef bd;
b2Body* wall = _world->CreateBody(&bd);
b2PolygonShape shape;
- shape.SetAsEdge(origin, bounds[i]);
-
+ shape.SetAsEdge(origin, endpoints[i]);
wall->CreateFixture(&shape, 0.0f);
// [_walls addObject:wall]; // doh, b2Body so does not descend from NSObject, and so is not an (id)
}
// }
[_walls removeAllObjects];
[_walls release];
+ delete _debugDraw;
delete _world; // b2World destructor destroys all physics entities and releases all heap memory.
[super dealloc];
}
}
- (void) drawDebug {
- if (_debugDrawingEnabled) _world->DrawDebugData();
+ _world->DrawDebugData();
}
- (void) setGravityX:(float)x y:(float)y {
public:
float32 globalAlpha;
- QQGLESDebugDraw();
+ QQGLESDebugDraw(float32 alpha=1);
+
+ void SetAllFlags();
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
-
+
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
-
+
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color);
-
+
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
-
+
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
-
+
void DrawTransform(const b2Transform& xf);
-
+
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color);
-
+
void DrawString(int x, int y, const char* string, ...);
-
+
void DrawAABB(b2AABB* aabb, const b2Color& color);
};
#include "QQGLESDebugDraw.h"
-
#include <cstdio>
#include <cstdarg>
-
#include <cstring>
-QQGLESDebugDraw::QQGLESDebugDraw() {
- globalAlpha = 1;
+
+
+QQGLESDebugDraw::QQGLESDebugDraw(float32 alpha) {
+ globalAlpha = alpha;
+ m_drawFlags = 0;
+}
+
+void QQGLESDebugDraw::SetAllFlags() {
+ // uint32 flags = 0;
+ // flags += b2DebugDraw::e_shapeBit;
+ // flags += b2DebugDraw::e_jointBit;
+ // flags += b2DebugDraw::e_aabbBit;
+ // flags += b2DebugDraw::e_pairBit;
+ // flags += b2DebugDraw::e_centerOfMassBit;
+
+ SetFlags((1 << 6) - 1); // should be all flag bits
}
void QQGLESDebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
-#import <UIKit/UIKit.h>
-#import <OpenGLES/EAGL.h>
-#import <OpenGLES/ES1/gl.h>
-#import <OpenGLES/ES1/glext.h>
-
#include <Box2D/Box2D.h>
+#import "Sparrow.h"
+#import "SPRenderSupport.h"
#import "physics/QQWorld.h"
-/*
-This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
-The view content is basically an EAGL surface you render your OpenGL scene into.
-Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
-*/
-@interface QQPhysicsDebugView : UIView {
+
+@interface QQPhysicsDebugView : SPDisplayObjectContainer {
@private
QQWorld* _world;
BOOL _panning;
-
- // Position offset and scale
- float sceneScale;
- CGPoint positionOffset;
-
- CGPoint lastWorldTouch;
- CGPoint lastScreenTouch;
-
- b2MouseJoint* mouseJoint;
- b2Vec2 mouseWorld;
- int32 stepCount;
-
- /// OpenGL ///
-
- /* The pixel dimensions of the backbuffer */
- GLint backingWidth;
- GLint backingHeight;
+ BOOL _zooming;
- EAGLContext *context;
-
- /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
- GLuint viewRenderbuffer, viewFramebuffer;
-
- /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
- GLuint depthRenderbuffer;
+ CGPoint _lastWorldTouch;
+ CGPoint _lastScreenTouch;
+ b2MouseJoint* _mouseJoint;
+ b2Vec2 _mouseWorld;
}
@property (nonatomic, readwrite, retain) QQWorld* world;
-@property (nonatomic, readonly, assign, getter=isPanning) BOOL panning;
-- (void) drawView;
+@property (nonatomic, readonly, getter=isPanning) BOOL panning;
+@property (nonatomic, readonly, getter=isZooming) BOOL zooming;
-@end
+- (id) initWithWorld:(QQWorld*)world;
-// Render Settings
-struct Settings {
-
- Settings() :
- hz(60.0f),
- velocityIterations(10),
- positionIterations(4),
- drawStats(0),
- drawShapes(1),
- drawJoints(1),
- drawAABBs(0),
- drawPairs(0),
- drawContactPoints(0),
- drawContactNormals(0),
- drawContactForces(0),
- drawFrictionForces(0),
- drawCOMs(0),
- enableWarmStarting(1),
- enableContinuous(1),
- pause(0),
- singleStep(0)
- {}
-
- float32 hz;
- int32 velocityIterations;
- int32 positionIterations;
- int32 drawShapes;
- int32 drawJoints;
- int32 drawAABBs;
- int32 drawPairs;
- int32 drawContactPoints;
- int32 drawContactNormals;
- int32 drawContactForces;
- int32 drawFrictionForces;
- int32 drawCOMs;
- int32 drawStats;
- int32 enableWarmStarting;
- int32 enableContinuous;
- int32 pause;
- int32 singleStep;
-};
+- (void) render:(SPRenderSupport*)support;
+
+@end
-#import <QuartzCore/QuartzCore.h>
-#import <OpenGLES/EAGLDrawable.h>
-
#import "QQPhysicsDebugView.h"
-#define USE_DEPTH_BUFFER 0
-#define kAccelerometerFrequency 30
-#define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10
-
-
-
-// A class extension to declare private methods
-@interface QQPhysicsDebugView ()
-
-@property (nonatomic, retain) EAGLContext *context;
-
-- (void) setup;
-
-- (BOOL) createFramebuffer;
-- (void) destroyFramebuffer;
-
-- (void) prepContext;
-- (void) flushContext;
-
-@end
-
-
-
@implementation QQPhysicsDebugView
@synthesize world = _world;
-@synthesize panning = _panning;
-
-@synthesize context;
+@synthesize panning = _panning;
+@synthesize zooming = _zooming;
-// You must implement this method
-+ (Class)layerClass {
- return [CAEAGLLayer class];
-}
-- (id) initWithFrame:(CGRect)aRect {
- if ((self = [super initWithFrame:aRect])) {
- [self setup];
- }
- return self;
+- (id) init {
+ return [self initWithWorld:nil];
}
-//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
-- (id) initWithCoder:(NSCoder*)coder {
- if ((self = [super initWithCoder:coder])) {
- [self setup];
+- (id) initWithWorld:(QQWorld*)world {
+ if ((self = [super init])) {
+ self.world = world;
+ self.scaleX = self.scaleY = self.world.scale; // TODO: the view should hold the scale
+
+ _panning = NO;
+ _zooming = NO;
+
+ _lastWorldTouch = CGPointMake(0,0);
}
return self;
}
-- (void) setup {
- // Get the layer
- CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
-
- eaglLayer.opaque = NO;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
- kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
- nil];
-
- context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
-
- if (!context || ![EAGLContext setCurrentContext:context]) {
- [self release];
- return;
- }
-
- sceneScale = 10.0f;
- positionOffset = CGPointMake(0,0);
- lastWorldTouch = CGPointMake(0,0);
-
-// [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
-// [[UIAccelerometer sharedAccelerometer] setDelegate:self];
-}
-
- (void) dealloc {
- if ([EAGLContext currentContext] == context)
- [EAGLContext setCurrentContext:nil];
- [context release];
[_world release];
[super dealloc];
}
+/// Rendering
-/// Methods ///
-
-- (CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation {
- screenLocation.x -= 160;
- screenLocation.y -= 240;
- screenLocation.x /= 160;
- screenLocation.y /= 160;
- screenLocation.x *= sceneScale;
- screenLocation.y *= -sceneScale;
-
- screenLocation.x -= positionOffset.x;
- screenLocation.y -= positionOffset.y;
-
- return screenLocation;
-}
-
-
-/// Events ///
-
-- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
- _panning = false;
- for (UITouch *touch in touches) {
- CGPoint touchLocation = [touch locationInView:self];
- CGPoint worldPosition = [self screenSpaceToWorldSpace:touchLocation];
- //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
- lastScreenTouch = touchLocation;
- lastWorldTouch = worldPosition;
-
- // test->MouseDown(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
- // if (!test->m_mouseJoint) panning=true;
- }
-}
-
-- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
- for (UITouch *touch in touches) {
- CGPoint touchLocation = [touch locationInView:self];
- CGPoint worldPosition = [self screenSpaceToWorldSpace:touchLocation];
- //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
-
-
- CGPoint screenDistanceMoved = CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y);
- if (_panning) {
- screenDistanceMoved.x /= 160;
- screenDistanceMoved.y /= 160;
- screenDistanceMoved.x *= sceneScale;
- screenDistanceMoved.y *= -sceneScale;
- positionOffset.x += screenDistanceMoved.x;
- positionOffset.y += screenDistanceMoved.y;
- }
-
- lastScreenTouch = touchLocation;
- lastWorldTouch = worldPosition;
- // test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
- }
-}
-
-- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
- // test->MouseUp(b2Vec2(lastWorldTouch.x, lastWorldTouch.y));
-}
-
-- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {
- // Only run for valid values
- if (acceleration.y != 0 && acceleration.x != 0) {
- if (self.world) [self.world setGravityX:acceleration.x y:acceleration.y];
- }
-}
-
-
-
-
-/// OpenGL ///
-
-- (void) layoutSubviews {
- [EAGLContext setCurrentContext:context];
- [self destroyFramebuffer];
- [self createFramebuffer];
- [self drawView];
-}
-
-- (void) prepContext {
- [EAGLContext setCurrentContext:context];
+- (void) render:(SPRenderSupport*)support {
+ [support bindTexture:nil];
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
- glViewport(0, 0, backingWidth, backingHeight);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(positionOffset.x, positionOffset.y, 0);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glEnable(GL_BLEND);
+ // XXX: i think this is unnecessary based on what i think bindTexture does, but i'm not clear what happens with nil
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ // set viewport pan and zoom
+ self.scaleX = self.scaleY = self.world.scale; // TODO: the view should hold the scale
+
glEnableClientState(GL_VERTEX_ARRAY);
-}
-
-- (void) drawView {
- [self prepContext];
[self.world drawDebug];
- [self flushContext];
-}
-
-- (void) flushContext {
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- [context presentRenderbuffer:GL_RENDERBUFFER_OES];
-}
-
-
-- (BOOL) createFramebuffer {
-
- glGenFramebuffersOES(1, &viewFramebuffer);
- glGenRenderbuffersOES(1, &viewRenderbuffer);
-
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
- [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
-
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+ glDisableClientState(GL_VERTEX_ARRAY);
- if (USE_DEPTH_BUFFER) {
- glGenRenderbuffersOES(1, &depthRenderbuffer);
- glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
- glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
- glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
- }
-
- if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
- NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
- return NO;
- }
-
- return YES;
-}
-
-
-- (void) destroyFramebuffer {
-
- glDeleteFramebuffersOES(1, &viewFramebuffer);
- viewFramebuffer = 0;
- glDeleteRenderbuffersOES(1, &viewRenderbuffer);
- viewRenderbuffer = 0;
-
- if(depthRenderbuffer) {
- glDeleteRenderbuffersOES(1, &depthRenderbuffer);
- depthRenderbuffer = 0;
- }
+ [super render:support];
}
@end
--- /dev/null
+#import <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+#include <Box2D/Box2D.h>
+
+#import "physics/QQWorld.h"
+
+
+/*
+This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
+The view content is basically an EAGL surface you render your OpenGL scene into.
+Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
+*/
+@interface QQPhysicsDebugView : UIView {
+@private
+ QQWorld* _world;
+ BOOL _panning;
+
+ // Position offset and scale
+ float sceneScale;
+ CGPoint positionOffset;
+
+ CGPoint lastWorldTouch;
+ CGPoint lastScreenTouch;
+
+ b2MouseJoint* mouseJoint;
+ b2Vec2 mouseWorld;
+ int32 stepCount;
+
+ /// OpenGL ///
+
+ /* The pixel dimensions of the backbuffer */
+ GLint backingWidth;
+ GLint backingHeight;
+
+ EAGLContext *context;
+
+ /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
+ GLuint viewRenderbuffer, viewFramebuffer;
+
+ /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
+ GLuint depthRenderbuffer;
+
+}
+
+@property (nonatomic, readwrite, retain) QQWorld* world;
+@property (nonatomic, readonly, assign, getter=isPanning) BOOL panning;
+
+- (void) drawView;
+
+@end
+
+
+// Render Settings
+struct Settings {
+
+ Settings() :
+ hz(60.0f),
+ velocityIterations(10),
+ positionIterations(4),
+ drawStats(0),
+ drawShapes(1),
+ drawJoints(1),
+ drawAABBs(0),
+ drawPairs(0),
+ drawContactPoints(0),
+ drawContactNormals(0),
+ drawContactForces(0),
+ drawFrictionForces(0),
+ drawCOMs(0),
+ enableWarmStarting(1),
+ enableContinuous(1),
+ pause(0),
+ singleStep(0)
+ {}
+
+ float32 hz;
+ int32 velocityIterations;
+ int32 positionIterations;
+ int32 drawShapes;
+ int32 drawJoints;
+ int32 drawAABBs;
+ int32 drawPairs;
+ int32 drawContactPoints;
+ int32 drawContactNormals;
+ int32 drawContactForces;
+ int32 drawFrictionForces;
+ int32 drawCOMs;
+ int32 drawStats;
+ int32 enableWarmStarting;
+ int32 enableContinuous;
+ int32 pause;
+ int32 singleStep;
+};
--- /dev/null
+#import <QuartzCore/QuartzCore.h>
+#import <OpenGLES/EAGLDrawable.h>
+
+#import "QQPhysicsDebugView.h"
+
+
+#define USE_DEPTH_BUFFER 0
+#define kAccelerometerFrequency 30
+#define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10
+
+
+
+// A class extension to declare private methods
+@interface QQPhysicsDebugView ()
+
+@property (nonatomic, retain) EAGLContext *context;
+
+- (void) setup;
+
+- (BOOL) createFramebuffer;
+- (void) destroyFramebuffer;
+
+- (void) prepContext;
+- (void) flushContext;
+
+@end
+
+
+
+
+@implementation QQPhysicsDebugView
+
+@synthesize world = _world;
+@synthesize panning = _panning;
+
+@synthesize context;
+
+
+// You must implement this method
++ (Class)layerClass {
+ return [CAEAGLLayer class];
+}
+
+- (id) initWithFrame:(CGRect)aRect {
+ if ((self = [super initWithFrame:aRect])) {
+ [self setup];
+ }
+ return self;
+}
+
+//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
+- (id) initWithCoder:(NSCoder*)coder {
+ if ((self = [super initWithCoder:coder])) {
+ [self setup];
+ }
+ return self;
+}
+
+- (void) setup {
+ // Get the layer
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+ eaglLayer.opaque = NO;
+ eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
+ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+ nil];
+
+ context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+
+ if (!context || ![EAGLContext setCurrentContext:context]) {
+ [self release];
+ return;
+ }
+
+ sceneScale = 10.0f;
+ positionOffset = CGPointMake(0,0);
+ lastWorldTouch = CGPointMake(0,0);
+
+// [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
+// [[UIAccelerometer sharedAccelerometer] setDelegate:self];
+}
+
+- (void) dealloc {
+ if ([EAGLContext currentContext] == context)
+ [EAGLContext setCurrentContext:nil];
+ [context release];
+ [_world release];
+ [super dealloc];
+}
+
+
+
+/// Methods ///
+
+- (CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation {
+ screenLocation.x -= 160;
+ screenLocation.y -= 240;
+ screenLocation.x /= 160;
+ screenLocation.y /= 160;
+ screenLocation.x *= sceneScale;
+ screenLocation.y *= -sceneScale;
+
+ screenLocation.x -= positionOffset.x;
+ screenLocation.y -= positionOffset.y;
+
+ return screenLocation;
+}
+
+
+/// Events ///
+
+- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
+ _panning = false;
+ for (UITouch *touch in touches) {
+ CGPoint touchLocation = [touch locationInView:self];
+ CGPoint worldPosition = [self screenSpaceToWorldSpace:touchLocation];
+ //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
+ lastScreenTouch = touchLocation;
+ lastWorldTouch = worldPosition;
+
+ // test->MouseDown(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
+ // if (!test->m_mouseJoint) panning=true;
+ }
+}
+
+- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
+ for (UITouch *touch in touches) {
+ CGPoint touchLocation = [touch locationInView:self];
+ CGPoint worldPosition = [self screenSpaceToWorldSpace:touchLocation];
+ //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
+
+
+ CGPoint screenDistanceMoved = CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y);
+ if (_panning) {
+ screenDistanceMoved.x /= 160;
+ screenDistanceMoved.y /= 160;
+ screenDistanceMoved.x *= sceneScale;
+ screenDistanceMoved.y *= -sceneScale;
+ positionOffset.x += screenDistanceMoved.x;
+ positionOffset.y += screenDistanceMoved.y;
+ }
+
+ lastScreenTouch = touchLocation;
+ lastWorldTouch = worldPosition;
+ // test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
+ }
+}
+
+- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
+ // test->MouseUp(b2Vec2(lastWorldTouch.x, lastWorldTouch.y));
+}
+
+- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {
+ // Only run for valid values
+ if (acceleration.y != 0 && acceleration.x != 0) {
+ if (self.world) [self.world setGravityX:acceleration.x y:acceleration.y];
+ }
+}
+
+
+
+
+/// OpenGL ///
+
+- (void) layoutSubviews {
+ [EAGLContext setCurrentContext:context];
+ [self destroyFramebuffer];
+ [self createFramebuffer];
+ [self drawView];
+}
+
+- (void) prepContext {
+ [EAGLContext setCurrentContext:context];
+
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
+ glViewport(0, 0, backingWidth, backingHeight);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(positionOffset.x, positionOffset.y, 0);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+}
+
+- (void) drawView {
+ [self prepContext];
+ [self.world drawDebug];
+ [self flushContext];
+}
+
+- (void) flushContext {
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+ [context presentRenderbuffer:GL_RENDERBUFFER_OES];
+}
+
+
+- (BOOL) createFramebuffer {
+
+ glGenFramebuffersOES(1, &viewFramebuffer);
+ glGenRenderbuffersOES(1, &viewRenderbuffer);
+
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+ [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
+
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+
+ if (USE_DEPTH_BUFFER) {
+ glGenRenderbuffersOES(1, &depthRenderbuffer);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
+ }
+
+ if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
+ NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+ return NO;
+ }
+
+ return YES;
+}
+
+
+- (void) destroyFramebuffer {
+
+ glDeleteFramebuffersOES(1, &viewFramebuffer);
+ viewFramebuffer = 0;
+ glDeleteRenderbuffersOES(1, &viewRenderbuffer);
+ viewRenderbuffer = 0;
+
+ if(depthRenderbuffer) {
+ glDeleteRenderbuffersOES(1, &depthRenderbuffer);
+ depthRenderbuffer = 0;
+ }
+}
+
+@end
#ifdef __OBJC__
#import <Foundation/Foundation.h>
+ #import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#endif
--- /dev/null
+#import "Sparrow.h"
+
+
+@interface QQShape : SPQuad
+
+@end
--- /dev/null
+#import "QQShape.h"
+
+
+@implementation QQShape
+
+- (void) render:(SPRenderSupport*)support {
+ [super render:support];
+}
+
+@end
/** Sets coordinates of the object relative to the local coordinates of the parent. */
- (id) setPositionX:(float)x y:(float)y;
+@property (nonatomic, readwrite, assign) float centerX;
+@property (nonatomic, readwrite, assign) float centerY;
+
+/** Sets coordinates of the object relative to the local coordinates of the parent. */
+- (id) setCenterX:(float)x y:(float)y;
+
+/** Coordinates of the center of the object relative to the local coordinates of the parent. */
+@property (nonatomic, readwrite, assign) SPPoint* center;
+
+
@end
return self;
}
+- (float) centerX { return self.x + self.width*0.5f; }
+- (void) setCenterX:(float)x { self.x = x - self.width*0.5f; }
+
+- (float) centerY { return self.y + self.height*0.5f; }
+- (void) setCenterY:(float)y { self.y = y - self.height*0.5f; }
+
+/** Sets coordinates of the object relative to the local coordinates of the parent. */
+- (id) setCenterX:(float)x y:(float)y {
+ self.centerX = x;
+ self.centerY = y;
+ return self;
+}
+
+- (SPPoint*) center {
+ return [SPPoint pointWithX:self.centerX y:self.centerY];
+}
+
+- (void) setCenter:(SPPoint*)pt {
+ [self setCenterX:pt.x y:pt.y];
+}
+
+
@end
#import "physics/debug/QQPhysicsDebugView.h"
-@interface QQAppDelegate : NSObject <UIApplicationDelegate>
-{
+@interface QQAppDelegate : NSObject <UIApplicationDelegate> {
+
+@private
+ UIApplication* _app;
UIWindow* window;
SPView* sparrowView;
- QQPhysicsDebugView* _debugView;
+ // QQPhysicsDebugView* _debugView;
QQGame* _game;
}
@property (nonatomic, retain) IBOutlet UIWindow* window;
@property (nonatomic, retain) IBOutlet SPView* sparrowView;
-@property (nonatomic, retain) QQPhysicsDebugView* debugView;
+// @property (nonatomic, retain) QQPhysicsDebugView* debugView;
@property (nonatomic, retain) QQGame* game;
@end
\ No newline at end of file
@synthesize window;
@synthesize sparrowView;
-@synthesize debugView = _debugView;
@synthesize game = _game;
- (void) applicationDidFinishLaunching:(UIApplication*)application {
+ _app = application;
+ _app.statusBarHidden = YES;
+
SP_CREATE_POOL(pool);
[SPStage setSupportHighResolutions:YES];
[SPAudioEngine start];
if ( sparrowView.frameRate != 60.0f )
sparrowView.frameRate = 60.0f;
- // sparrowView.stage = [[[SPStage alloc] init] autorelease];
self.game = [[[QQGame alloc] init] autorelease];
sparrowView.stage = _game;
- self.debugView = [[[QQPhysicsDebugView alloc] initWithFrame:sparrowView.frame] autorelease];
- [window addSubview:self.debugView];
+ [_game start];
[window makeKeyAndVisible];
[sparrowView start];
}
- (void) dealloc {
- // [self setGame:nil];
+ _app = nil;
[_game release];
[sparrowView release];
[window release];
<string key="NSFrame">{{284, 501}, {200, 22}}</string>
<reference key="NSSuperview" ref="62075450"/>
<reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<object class="IBUIView" id="607297697">
<reference key="NSNextResponder" ref="62075450"/>
<int key="NSvFlags">292</int>
- <string key="NSFrameSize">{768, 1003}</string>
+ <string key="NSFrameSize">{768, 1024}</string>
<reference key="NSSuperview" ref="62075450"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="348798989"/>
</object>
</object>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
+ <integer value="512" key="IBUIAccessibilityTraits"/>
+ </object>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
</array>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">15</int>
+ <int key="maxID">17</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBUIView" id="851352140">
<reference key="NSNextResponder" ref="380026005"/>
<int key="NSvFlags">1316</int>
- <string key="NSFrame">{{0, 21}, {320, 459}}</string>
+ <string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview" ref="380026005"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="723173800"/>
</object>
</object>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <object class="IBUIAccessibilityConfiguration" key="IBUIAccessibilityConfiguration">
+ <integer value="512" key="IBUIAccessibilityTraits"/>
+ </object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
objects = {
/* Begin PBXBuildFile section */
+ 49193BF5139280180005B3DD /* QQLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 49193BEF139280180005B3DD /* QQLevel.h */; };
+ 49193BF6139280180005B3DD /* QQLevel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 49193BF0139280180005B3DD /* QQLevel.mm */; };
492D80CC138B231B0042D918 /* QQPhysical.h in Headers */ = {isa = PBXBuildFile; fileRef = 492D80CB138B231B0042D918 /* QQPhysical.h */; };
492D80E4138BA4910042D918 /* QQCooldown.h in Headers */ = {isa = PBXBuildFile; fileRef = 492D80DE138BA4910042D918 /* QQCooldown.h */; };
492D80E5138BA4910042D918 /* QQCooldown.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492D80DF138BA4910042D918 /* QQCooldown.mm */; };
49966919136930E8006E8125 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49966914136930E8006E8125 /* OpenAL.framework */; };
4996691A136930E8006E8125 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49966915136930E8006E8125 /* OpenGLES.framework */; };
4996691B136930E8006E8125 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49966916136930E8006E8125 /* QuartzCore.framework */; };
+ 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 */; };
49DA67D5137847A7004841E9 /* QQWorld.mm in Sources */ = {isa = PBXBuildFile; fileRef = 49DA67D3137847A7004841E9 /* QQWorld.mm */; };
49E834A713812427007A6598 /* QQActive.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E8349E13812427007A6598 /* QQActive.h */; };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 49193BEF139280180005B3DD /* QQLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQLevel.h; sourceTree = "<group>"; };
+ 49193BF0139280180005B3DD /* QQLevel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQLevel.mm; sourceTree = "<group>"; };
492D80CB138B231B0042D918 /* QQPhysical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QQPhysical.h; path = src/game/QQPhysical.h; sourceTree = SOURCE_ROOT; };
492D80DE138BA4910042D918 /* QQCooldown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQCooldown.h; sourceTree = "<group>"; };
492D80DF138BA4910042D918 /* QQCooldown.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQCooldown.mm; sourceTree = "<group>"; };
49966914136930E8006E8125 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
49966915136930E8006E8125 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
49966916136930E8006E8125 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ 49D8645B1392DB2800BC341C /* QQShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQShape.h; sourceTree = "<group>"; };
+ 49D8645C1392DB2800BC341C /* QQShape.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQShape.mm; sourceTree = "<group>"; };
49DA67D2137847A7004841E9 /* QQWorld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQWorld.h; sourceTree = "<group>"; };
49DA67D3137847A7004841E9 /* QQWorld.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QQWorld.mm; sourceTree = "<group>"; };
49E8349E13812427007A6598 /* QQActive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQActive.h; sourceTree = "<group>"; };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 49193BEE139280180005B3DD /* map */ = {
+ isa = PBXGroup;
+ children = (
+ 49193BEF139280180005B3DD /* QQLevel.h */,
+ 49193BF0139280180005B3DD /* QQLevel.mm */,
+ );
+ path = map;
+ sourceTree = "<group>";
+ };
492D80DB138BA4910042D918 /* ability */ = {
isa = PBXGroup;
children = (
49E8349D13812427007A6598 /* game */ = {
isa = PBXGroup;
children = (
+ 49193BEE139280180005B3DD /* map */,
492D80ED138BA4BC0042D918 /* bullet */,
492D80E8138BA4B40042D918 /* unit */,
492D80DB138BA4910042D918 /* ability */,
49F2D9AE13764666000B6B8C /* src */ = {
isa = PBXGroup;
children = (
- 49E8349D13812427007A6598 /* game */,
- 49F2D9B113764666000B6B8C /* physics */,
49F2D9B313764666000B6B8C /* render */,
49E834AF13812555007A6598 /* ui */,
+ 49F2D9B113764666000B6B8C /* physics */,
+ 49E8349D13812427007A6598 /* game */,
49F2D9B013764666000B6B8C /* main.mm */,
49F2D9B213764666000B6B8C /* prefix.pch */,
);
49F2D9B313764666000B6B8C /* render */ = {
isa = PBXGroup;
children = (
+ 49D8645B1392DB2800BC341C /* QQShape.h */,
+ 49D8645C1392DB2800BC341C /* QQShape.mm */,
4B8B2A4D137D090D00CA4076 /* animation */,
49E834D1138166A6007A6598 /* QQSparrowExtensions.h */,
49E834D2138166A6007A6598 /* QQSparrowExtensions.mm */,
49F2DADB13764ED6000B6B8C /* SPPoolObject.h in Headers */,
49F2DADD13764ED6000B6B8C /* SPUtils.h in Headers */,
49F2DADF13764ED6000B6B8C /* Sparrow.h in Headers */,
+ 492D810C138C07540042D918 /* BEParallaxSprite.h in Headers */,
+ 492D810E138C07540042D918 /* SHCircle.h in Headers */,
+ 492D8110138C07540042D918 /* SHLine.h in Headers */,
+ 492D8112138C07540042D918 /* SHPolygon.h in Headers */,
+ 492D8115138C07540042D918 /* SXFPSMeter.h in Headers */,
+ 492D8114138C07540042D918 /* SparrowExtras.h in Headers */,
49DA67D4137847A7004841E9 /* QQWorld.h in Headers */,
4B8B2A50137D098500CA4076 /* QQAnimationContainer.h in Headers */,
49E834A713812427007A6598 /* QQActive.h in Headers */,
492D80F0138BA4BC0042D918 /* QQBullet.h in Headers */,
492D80F3138BA4CE0042D918 /* QQThing.h in Headers */,
492D80FF138BCC9F0042D918 /* QQActorDelegate.h in Headers */,
- 492D810C138C07540042D918 /* BEParallaxSprite.h in Headers */,
- 492D810E138C07540042D918 /* SHCircle.h in Headers */,
- 492D8110138C07540042D918 /* SHLine.h in Headers */,
- 492D8112138C07540042D918 /* SHPolygon.h in Headers */,
- 492D8114138C07540042D918 /* SparrowExtras.h in Headers */,
- 492D8115138C07540042D918 /* SXFPSMeter.h in Headers */,
+ 49193BF5139280180005B3DD /* QQLevel.h in Headers */,
+ 49D8645D1392DB2800BC341C /* QQShape.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
49F2DADA13764ED6000B6B8C /* SPNSExtensions.m in Sources */,
49F2DADC13764ED6000B6B8C /* SPPoolObject.m in Sources */,
49F2DADE13764ED6000B6B8C /* SPUtils.m in Sources */,
+ 492D810D138C07540042D918 /* BEParallaxSprite.m in Sources */,
+ 492D810F138C07540042D918 /* SHCircle.m in Sources */,
+ 492D8111138C07540042D918 /* SHLine.m in Sources */,
+ 492D8113138C07540042D918 /* SHPolygon.m in Sources */,
+ 492D8116138C07540042D918 /* SXFPSMeter.m in Sources */,
+ 49E834CE13814F7D007A6598 /* QQGLESDebugDraw.mm in Sources */,
+ 4B91A15A138F644000EF4D7C /* QQPhysicsDebugView.mm in Sources */,
49DA67D5137847A7004841E9 /* QQWorld.mm in Sources */,
4B8B2A51137D098500CA4076 /* QQAnimationContainer.mm in Sources */,
- 49F2D9C413764666000B6B8C /* main.mm in Sources */,
49E834A913812427007A6598 /* QQActor.mm in Sources */,
49E834AE13812427007A6598 /* QQGame.mm in Sources */,
49E834BF13812555007A6598 /* QQAppDelegate.mm in Sources */,
49E834C113812555007A6598 /* QQAppDelegate_iPad.mm in Sources */,
49E834C413812555007A6598 /* QQAppDelegate_iPhone.mm in Sources */,
49E834C713812555007A6598 /* QQViewport.mm in Sources */,
- 49E834CE13814F7D007A6598 /* QQGLESDebugDraw.mm in Sources */,
49E834D4138166A6007A6598 /* QQSparrowExtensions.mm in Sources */,
492D80E5138BA4910042D918 /* QQCooldown.mm in Sources */,
- 4B91A15A138F644000EF4D7C /* QQPhysicsDebugView.mm in Sources */,
492D80EC138BA4B40042D918 /* QQTank.mm in Sources */,
492D80F1138BA4BC0042D918 /* QQBullet.mm in Sources */,
492D80FD138BCA840042D918 /* QQUnit.mm in Sources */,
- 492D810D138C07540042D918 /* BEParallaxSprite.m in Sources */,
- 492D810F138C07540042D918 /* SHCircle.m in Sources */,
- 492D8111138C07540042D918 /* SHLine.m in Sources */,
- 492D8113138C07540042D918 /* SHPolygon.m in Sources */,
- 492D8116138C07540042D918 /* SXFPSMeter.m in Sources */,
+ 49193BF6139280180005B3DD /* QQLevel.mm in Sources */,
+ 49F2D9C413764666000B6B8C /* main.mm in Sources */,
+ 49D8645E1392DB2800BC341C /* QQShape.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};