Sunday, January 1, 2012

[Cocos2D Mac] Disable System Trackpad Gesture And Create Gestures Yourself

When you are making an application completely using trackpad with self-designed gestures, or using system gestures in different ways, you may want to disable system gestures like Four-Finger-Swipe, etc. For example, if we want to use Four-Finger-Swipe to show desktop instead of switch between screens, we should first keep the system from using Four-Finger-Swipe gesture. Unfortunately, the system gestures have the top priority in Mac OS X, that it still works when other applications are running. Thus, I found 2 ways to solve this problem, and I think the later is more applicable.

1. Using AppleScript in Cocoa

NSAppleScript *script = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"yourFile" ofType:@"scpt"]] error: nil];

[script executeAndReturnError: NULL];

2. Using EventTap

First, we should create an EventTap, which captures system defined gestures include NSEventMaskGesture, NSEventMaskMagnify, NSEventMaskSwipe, NSEventMaskRotate, NSEventMaskBeginGesture, and NSEventMaskEndGesture.
You can capture whatever gestures defined before by add a mask using CGEventMask. 
The following just captures swipe gestures:

In AppDelegate.m: 

- (void)createEventTap
{
    CFRunLoopSourceRef runLoopSource;
   
    CGEventMask eventMask = (NSEventMaskSwipe);
   
    eventTap = CGEventTapCreate(kCGHIDEventTap,
                                kCGHeadInsertEventTap,
                                kCGEventTapOptionDefault,
                                eventMask,
                                MyCGEventCallback,
                                NULL); 
   
    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
                                                  eventTap,
                                                  0);
   
    CFRunLoopAddSource(CFRunLoopGetCurrent(),
                       runLoopSource,
                       kCFRunLoopCommonModes);
   
    CGEventTapEnable(eventTap, true);

In method applicationDidFinishLaunching:


[self createEventTap]; 

Then you can use the gesture captured in your CGEventCallback, like:


CGEventRef MyCGEventCallback(CGEventTapProxy proxy,
                             CGEventType type,
                             CGEventRef theEvent,
                             void *refcon)
{
    return NULL;

In MyCGEventCallback, if you return NULL, then the system just ignores the gesture, which means our work is partly done. But we may want to use the gesture instead of just disable it. Then we can use touchEvents defined in Cocos2d, which defined as:

-(BOOL) ccTouchesBeganWithEvent:(NSEvent *)event;
-(BOOL) ccTouchesMovedWithEvent:(NSEvent *)event;
-(BOOL) ccTouchesEndedWithEvent:(NSEvent *)event;
-(BOOL) ccTouchesCancelledWithEvent:(NSEvent *)event;


In fact, they are defined in origin as:

- (void)touchesBeganWithEvent:(NSEvent *)event;
- (void)touchesMovedWithEvent:(NSEvent *)event;
- (void)touchesEndedWithEvent:(NSEvent *)event;

- (void)touchesCancelledWithEvent:(NSEvent *)event;

If you are using a CCLayer, use the first one. Otherwise, use the second one.
A simple example:


-(BOOL) ccTouchesBeganWithEvent:(NSEvent *)event

{
    //NSLog(@"touch begin");
    NSSet * touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:[[CCDirectorMac sharedDirector] openGLView]];
    [player onTouchBegan:[touches retain]];
    return YES;
}

Saturday, December 31, 2011

Conversion Between Rotation and Direction in Games

In games, we might encounter the problem of Conversion Between Rotation and Direction. For example, if we want to fire a projectile direct (1, 2), and want to change the direction of the projectle. Thus somehow we have to calculate the rotation of the sprite with the formula:

rotation = 90 - atan(d.y / d.x) * 180 / pi;

While it's time-consuming to calculating it each time. So I wrote a function per-recorded  CGPoint directions relating to 180 degrees. (180 is enough in real time animation). 

- (CGPoint)rotationToDirect:(int)rotation
{
    switch (rotation) {
        case 0:return ccp(0.000000, 1.000000);          case 1:return ccp(0.017452, 0.999848);      
        case 2:return ccp(0.034899, 0.999391);          case 3:return ccp(0.052336, 0.998630);      
        case 4:return ccp(0.069756, 0.997564);          case 5:return ccp(0.087156, 0.996195);      
        case 6:return ccp(0.104528, 0.994522);          case 7:return ccp(0.121869, 0.992546);      
        case 8:return ccp(0.139173, 0.990268);          case 9:return ccp(0.156434, 0.987688);      
        case 10:return ccp(0.173648, 0.984808);         case 11:return ccp(0.190809, 0.981627);      
        case 12:return ccp(0.207912, 0.978148);         case 13:return ccp(0.224951, 0.974370);      
        case 14:return ccp(0.241922, 0.970296);         case 15:return ccp(0.258819, 0.965926);      
        case 16:return ccp(0.275637, 0.961262);         case 17:return ccp(0.292372, 0.956305);      
        case 18:return ccp(0.309017, 0.951057);         case 19:return ccp(0.325568, 0.945519);      
        case 20:return ccp(0.342020, 0.939693);         case 21:return ccp(0.358368, 0.933580);      
        case 22:return ccp(0.374607, 0.927184);         case 23:return ccp(0.390731, 0.920505);      
        case 24:return ccp(0.406737, 0.913545);         case 25:return ccp(0.422618, 0.906308);      
        case 26:return ccp(0.438371, 0.898794);         case 27:return ccp(0.453991, 0.891007);      
        case 28:return ccp(0.469472, 0.882948);         case 29:return ccp(0.484810, 0.874620);      
        case 30:return ccp(0.500000, 0.866025);         case 31:return ccp(0.515038, 0.857167);      
        case 32:return ccp(0.529919, 0.848048);         case 33:return ccp(0.544639, 0.838671);      
        case 34:return ccp(0.559193, 0.829038);         case 35:return ccp(0.573576, 0.819152);      
        case 36:return ccp(0.587785, 0.809017);         case 37:return ccp(0.601815, 0.798636);      
        case 38:return ccp(0.615662, 0.788011);         case 39:return ccp(0.629320, 0.777146);      
        case 40:return ccp(0.642788, 0.766044);         case 41:return ccp(0.656059, 0.754710);      
        case 42:return ccp(0.669131, 0.743145);         case 43:return ccp(0.681998, 0.731354);      
        case 44:return ccp(0.694658, 0.719340);         case 45:return ccp(0.707107, 0.707107);      
        case 46:return ccp(0.719340, 0.694658);         case 47:return ccp(0.731354, 0.681998);      
        case 48:return ccp(0.743145, 0.669131);         case 49:return ccp(0.754710, 0.656059);      
        case 50:return ccp(0.766044, 0.642788);         case 51:return ccp(0.777146, 0.629320);      
        case 52:return ccp(0.788011, 0.615662);         case 53:return ccp(0.798635, 0.601815);      
        case 54:return ccp(0.809017, 0.587785);         case 55:return ccp(0.819152, 0.573576);      
        case 56:return ccp(0.829038, 0.559193);         case 57:return ccp(0.838671, 0.544639);      
        case 58:return ccp(0.848048, 0.529919);         case 59:return ccp(0.857167, 0.515038);      
        case 60:return ccp(0.866025, 0.500000);         case 61:return ccp(0.874620, 0.484810);      
        case 62:return ccp(0.882948, 0.469472);         case 63:return ccp(0.891007, 0.453991);      
        case 64:return ccp(0.898794, 0.438371);         case 65:return ccp(0.906308, 0.422618);      
        case 66:return ccp(0.913545, 0.406737);         case 67:return ccp(0.920505, 0.390731);      
        case 68:return ccp(0.927184, 0.374607);         case 69:return ccp(0.933580, 0.358368);      
        case 70:return ccp(0.939693, 0.342020);         case 71:return ccp(0.945519, 0.325568);      
        case 72:return ccp(0.951056, 0.309017);         case 73:return ccp(0.956305, 0.292372);      
        case 74:return ccp(0.961262, 0.275637);         case 75:return ccp(0.965926, 0.258819);      
        case 76:return ccp(0.970296, 0.241922);         case 77:return ccp(0.974370, 0.224951);      
        case 78:return ccp(0.978148, 0.207912);         case 79:return ccp(0.981627, 0.190809);      
        case 80:return ccp(0.984808, 0.173648);         case 81:return ccp(0.987688, 0.156434);      
        case 82:return ccp(0.990268, 0.139173);         case 83:return ccp(0.992546, 0.121869);      
        case 84:return ccp(0.994522, 0.104528);         case 85:return ccp(0.996195, 0.087156);      
        case 86:return ccp(0.997564, 0.069756);         case 87:return ccp(0.998630, 0.052336);      
        case 88:return ccp(0.999391, 0.034899);         case 89:return ccp(0.999848, 0.017452);      
        case 90:return ccp(1.000000, 0.000000);         case 91:return ccp(0.999848, -0.017452);      
        case 92:return ccp(0.999391, -0.034899);        case 93:return ccp(0.998630, -0.052336);      
        case 94:return ccp(0.997564, -0.069756);        case 95:return ccp(0.996195, -0.087156);      
        case 96:return ccp(0.994522, -0.104528);        case 97:return ccp(0.992546, -0.121869);      
        case 98:return ccp(0.990268, -0.139173);        case 99:return ccp(0.987688, -0.156434);      
        case 100:return ccp(0.984808, -0.173648);       case 101:return ccp(0.981627, -0.190809);      
        case 102:return ccp(0.978148, -0.207912);       case 103:return ccp(0.974370, -0.224951);      
        case 104:return ccp(0.970296, -0.241922);       case 105:return ccp(0.965926, -0.258819);      
        case 106:return ccp(0.961262, -0.275637);       case 107:return ccp(0.956305, -0.292372);      
        case 108:return ccp(0.951056, -0.309017);       case 109:return ccp(0.945519, -0.325568);      
        case 110:return ccp(0.939693, -0.342020);       case 111:return ccp(0.933580, -0.358368);      
        case 112:return ccp(0.927184, -0.374607);       case 113:return ccp(0.920505, -0.390731);      
        case 114:return ccp(0.913545, -0.406737);       case 115:return ccp(0.906308, -0.422618);      
        case 116:return ccp(0.898794, -0.438371);       case 117:return ccp(0.891007, -0.453991);      
        case 118:return ccp(0.882948, -0.469472);       case 119:return ccp(0.874620, -0.484810);      
        case 120:return ccp(0.866025, -0.500000);       case 121:return ccp(0.857167, -0.515038);      
        case 122:return ccp(0.848048, -0.529919);       case 123:return ccp(0.838671, -0.544639);      
        case 124:return ccp(0.829038, -0.559193);       case 125:return ccp(0.819152, -0.573576);      
        case 126:return ccp(0.809017, -0.587785);       case 127:return ccp(0.798635, -0.601815);      
        case 128:return ccp(0.788011, -0.615662);       case 129:return ccp(0.777146, -0.629320);      
        case 130:return ccp(0.766044, -0.642788);       case 131:return ccp(0.754710, -0.656059);      
        case 132:return ccp(0.743145, -0.669131);       case 133:return ccp(0.731354, -0.681998);      
        case 134:return ccp(0.719340, -0.694658);       case 135:return ccp(0.707107, -0.707107);      
        case 136:return ccp(0.694658, -0.719340);       case 137:return ccp(0.681998, -0.731354);      
        case 138:return ccp(0.669131, -0.743145);       case 139:return ccp(0.656059, -0.754710);      
        case 140:return ccp(0.642788, -0.766044);       case 141:return ccp(0.629320, -0.777146);      
        case 142:return ccp(0.615662, -0.788011);       case 143:return ccp(0.601815, -0.798636);      
        case 144:return ccp(0.587785, -0.809017);       case 145:return ccp(0.573576, -0.819152);      
        case 146:return ccp(0.559193, -0.829038);       case 147:return ccp(0.544639, -0.838671);      
        case 148:return ccp(0.529919, -0.848048);       case 149:return ccp(0.515038, -0.857167);      
        case 150:return ccp(0.500000, -0.866025);       case 151:return ccp(0.484810, -0.874620);      
        case 152:return ccp(0.469472, -0.882948);       case 153:return ccp(0.453991, -0.891007);      
        case 154:return ccp(0.438371, -0.898794);       case 155:return ccp(0.422618, -0.906308);      
        case 156:return ccp(0.406737, -0.913545);       case 157:return ccp(0.390731, -0.920505);      
        case 158:return ccp(0.374607, -0.927184);       case 159:return ccp(0.358368, -0.933580);      
        case 160:return ccp(0.342020, -0.939693);       case 161:return ccp(0.325568, -0.945519);      
        case 162:return ccp(0.309017, -0.951057);       case 163:return ccp(0.292372, -0.956305);      
        case 164:return ccp(0.275637, -0.961262);       case 165:return ccp(0.258819, -0.965926);      
        case 166:return ccp(0.241922, -0.970296);       case 167:return ccp(0.224951, -0.974370);      
        case 168:return ccp(0.207912, -0.978148);       case 169:return ccp(0.190809, -0.981627);      
        case 170:return ccp(0.173648, -0.984808);       case 171:return ccp(0.156434, -0.987688);      
        case 172:return ccp(0.139173, -0.990268);       case 173:return ccp(0.121869, -0.992546);      
        case 174:return ccp(0.104528, -0.994522);       case 175:return ccp(0.087156, -0.996195);      
        case 176:return ccp(0.069756, -0.997564);       case 177:return ccp(0.052336, -0.998630);      
        case 178:return ccp(0.034899, -0.999391);       case 179:return ccp(0.017452, -0.999848);      
        case 180:return ccp(0.000000, -1.000000);       case 181:return ccp(-0.017452, -0.999848);      
        case 182:return ccp(-0.034899, -0.999391);       case 183:return ccp(-0.052336, -0.998630);      
        case 184:return ccp(-0.069756, -0.997564);       case 185:return ccp(-0.087156, -0.996195);      
        case 186:return ccp(-0.104528, -0.994522);       case 187:return ccp(-0.121869, -0.992546);      
        case 188:return ccp(-0.139173, -0.990268);       case 189:return ccp(-0.156434, -0.987688);      
        case 190:return ccp(-0.173648, -0.984808);       case 191:return ccp(-0.190809, -0.981627);      
        case 192:return ccp(-0.207912, -0.978148);       case 193:return ccp(-0.224951, -0.974370);      
        case 194:return ccp(-0.241922, -0.970296);       case 195:return ccp(-0.258819, -0.965926);      
        case 196:return ccp(-0.275637, -0.961262);       case 197:return ccp(-0.292372, -0.956305);      
        case 198:return ccp(-0.309017, -0.951057);       case 199:return ccp(-0.325568, -0.945519);      
        case 200:return ccp(-0.342020, -0.939693);       case 201:return ccp(-0.358368, -0.933580);      
        case 202:return ccp(-0.374607, -0.927184);       case 203:return ccp(-0.390731, -0.920505);      
        case 204:return ccp(-0.406737, -0.913545);       case 205:return ccp(-0.422618, -0.906308);      
        case 206:return ccp(-0.438371, -0.898794);       case 207:return ccp(-0.453991, -0.891007);      
        case 208:return ccp(-0.469472, -0.882948);       case 209:return ccp(-0.484810, -0.874620);      
        case 210:return ccp(-0.500000, -0.866025);       case 211:return ccp(-0.515038, -0.857167);      
        case 212:return ccp(-0.529919, -0.848048);       case 213:return ccp(-0.544639, -0.838671);      
        case 214:return ccp(-0.559193, -0.829038);       case 215:return ccp(-0.573576, -0.819152);      
        case 216:return ccp(-0.587785, -0.809017);       case 217:return ccp(-0.601815, -0.798636);      
        case 218:return ccp(-0.615662, -0.788011);       case 219:return ccp(-0.629320, -0.777146);      
        case 220:return ccp(-0.642788, -0.766044);       case 221:return ccp(-0.656059, -0.754710);      
        case 222:return ccp(-0.669131, -0.743145);       case 223:return ccp(-0.681998, -0.731354);      
        case 224:return ccp(-0.694658, -0.719340);       case 225:return ccp(-0.707107, -0.707107);      
        case 226:return ccp(-0.719340, -0.694658);       case 227:return ccp(-0.731354, -0.681998);      
        case 228:return ccp(-0.743145, -0.669131);       case 229:return ccp(-0.754710, -0.656059);      
        case 230:return ccp(-0.766044, -0.642788);       case 231:return ccp(-0.777146, -0.629320);      
        case 232:return ccp(-0.788011, -0.615662);       case 233:return ccp(-0.798635, -0.601815);      
        case 234:return ccp(-0.809017, -0.587785);       case 235:return ccp(-0.819152, -0.573576);      
        case 236:return ccp(-0.829038, -0.559193);       case 237:return ccp(-0.838671, -0.544639);      
        case 238:return ccp(-0.848048, -0.529919);       case 239:return ccp(-0.857167, -0.515038);      
        case 240:return ccp(-0.866025, -0.500000);       case 241:return ccp(-0.874620, -0.484810);      
        case 242:return ccp(-0.882948, -0.469472);       case 243:return ccp(-0.891007, -0.453991);      
        case 244:return ccp(-0.898794, -0.438371);       case 245:return ccp(-0.906308, -0.422618);      
        case 246:return ccp(-0.913545, -0.406737);       case 247:return ccp(-0.920505, -0.390731);      
        case 248:return ccp(-0.927184, -0.374607);       case 249:return ccp(-0.933580, -0.358368);      
        case 250:return ccp(-0.939693, -0.342020);       case 251:return ccp(-0.945519, -0.325568);      
        case 252:return ccp(-0.951056, -0.309017);       case 253:return ccp(-0.956305, -0.292372);      
        case 254:return ccp(-0.961262, -0.275637);       case 255:return ccp(-0.965926, -0.258819);      
        case 256:return ccp(-0.970296, -0.241922);       case 257:return ccp(-0.974370, -0.224951);      
        case 258:return ccp(-0.978148, -0.207912);       case 259:return ccp(-0.981627, -0.190809);      
        case 260:return ccp(-0.984808, -0.173648);       case 261:return ccp(-0.987688, -0.156434);      
        case 262:return ccp(-0.990268, -0.139173);       case 263:return ccp(-0.992546, -0.121869);      
        case 264:return ccp(-0.994522, -0.104528);       case 265:return ccp(-0.996195, -0.087156);      
        case 266:return ccp(-0.997564, -0.069756);       case 267:return ccp(-0.998630, -0.052336);      
        case 268:return ccp(-0.999391, -0.034899);       case 269:return ccp(-0.999848, -0.017452);      
        case 270:return ccp(-1.000000, 0.000000);       case 271:return ccp(-0.999848, 0.017452);      
        case 272:return ccp(-0.999391, 0.034899);       case 273:return ccp(-0.998630, 0.052336);      
        case 274:return ccp(-0.997564, 0.069756);       case 275:return ccp(-0.996195, 0.087156);      
        case 276:return ccp(-0.994522, 0.104528);       case 277:return ccp(-0.992546, 0.121869);      
        case 278:return ccp(-0.990268, 0.139173);       case 279:return ccp(-0.987688, 0.156434);      
        case 280:return ccp(-0.984808, 0.173648);       case 281:return ccp(-0.981627, 0.190809);      
        case 282:return ccp(-0.978148, 0.207912);       case 283:return ccp(-0.974370, 0.224951);      
        case 284:return ccp(-0.970296, 0.241922);       case 285:return ccp(-0.965926, 0.258819);      
        case 286:return ccp(-0.961262, 0.275637);       case 287:return ccp(-0.956305, 0.292372);      
        case 288:return ccp(-0.951056, 0.309017);       case 289:return ccp(-0.945519, 0.325568);      
        case 290:return ccp(-0.939693, 0.342020);       case 291:return ccp(-0.933580, 0.358368);      
        case 292:return ccp(-0.927184, 0.374607);       case 293:return ccp(-0.920505, 0.390731);      
        case 294:return ccp(-0.913545, 0.406737);       case 295:return ccp(-0.906308, 0.422618);      
        case 296:return ccp(-0.898794, 0.438371);       case 297:return ccp(-0.891007, 0.453991);      
        case 298:return ccp(-0.882948, 0.469472);       case 299:return ccp(-0.874620, 0.484810);      
        case 300:return ccp(-0.866025, 0.500000);       case 301:return ccp(-0.857167, 0.515038);      
        case 302:return ccp(-0.848048, 0.529919);       case 303:return ccp(-0.838671, 0.544639);      
        case 304:return ccp(-0.829038, 0.559193);       case 305:return ccp(-0.819152, 0.573576);      
        case 306:return ccp(-0.809017, 0.587785);       case 307:return ccp(-0.798635, 0.601815);      
        case 308:return ccp(-0.788011, 0.615662);       case 309:return ccp(-0.777146, 0.629320);      
        case 310:return ccp(-0.766044, 0.642788);       case 311:return ccp(-0.754710, 0.656059);      
        case 312:return ccp(-0.743145, 0.669131);       case 313:return ccp(-0.731354, 0.681998);      
        case 314:return ccp(-0.719340, 0.694658);       case 315:return ccp(-0.707107, 0.707107);      
        case 316:return ccp(-0.694658, 0.719340);       case 317:return ccp(-0.681998, 0.731354);      
        case 318:return ccp(-0.669131, 0.743145);       case 319:return ccp(-0.656059, 0.754710);      
        case 320:return ccp(-0.642788, 0.766044);       case 321:return ccp(-0.629320, 0.777146);      
        case 322:return ccp(-0.615662, 0.788011);       case 323:return ccp(-0.601815, 0.798636);      
        case 324:return ccp(-0.587785, 0.809017);       case 325:return ccp(-0.573576, 0.819152);      
        case 326:return ccp(-0.559193, 0.829038);       case 327:return ccp(-0.544639, 0.838671);      
        case 328:return ccp(-0.529919, 0.848048);       case 329:return ccp(-0.515038, 0.857167);      
        case 330:return ccp(-0.500000, 0.866025);       case 331:return ccp(-0.484810, 0.874620);      
        case 332:return ccp(-0.469472, 0.882948);       case 333:return ccp(-0.453991, 0.891007);      
        case 334:return ccp(-0.438371, 0.898794);       case 335:return ccp(-0.422618, 0.906308);      
        case 336:return ccp(-0.406737, 0.913545);       case 337:return ccp(-0.390731, 0.920505);      
        case 338:return ccp(-0.374607, 0.927184);       case 339:return ccp(-0.358368, 0.933580);      
        case 340:return ccp(-0.342020, 0.939693);       case 341:return ccp(-0.325568, 0.945519);      
        case 342:return ccp(-0.309017, 0.951057);       case 343:return ccp(-0.292372, 0.956305);      
        case 344:return ccp(-0.275637, 0.961262);       case 345:return ccp(-0.258819, 0.965926);      
        case 346:return ccp(-0.241922, 0.970296);       case 347:return ccp(-0.224951, 0.974370);      
        case 348:return ccp(-0.207912, 0.978148);       case 349:return ccp(-0.190809, 0.981627);      
        case 350:return ccp(-0.173648, 0.984808);       case 351:return ccp(-0.156434, 0.987688);      
        case 352:return ccp(-0.139173, 0.990268);       case 353:return ccp(-0.121869, 0.992546);      
        case 354:return ccp(-0.104528, 0.994522);       case 355:return ccp(-0.087156, 0.996195);      
        case 356:return ccp(-0.069756, 0.997564);       case 357:return ccp(-0.052336, 0.998630);      
        case 358:return ccp(-0.034899, 0.999391);       case 359:return ccp(-0.017452, 0.999848);  
        default:return ccp(0, 0);
    }
}