存档

2014年2月 的存档

cocos2d-html5在cocos2d-x里面打包编译

2014年2月20日 没有评论

main.cpp打开USE_WIN32_CONSOLE输出

#include "main.h"
#include "AppDelegate.h"
#include "CCEGLView.h"

#define USE_WIN32_CONSOLE

USING_NS_CC;

// uncomment below line, open debug console
// #define USE_WIN32_CONSOLE

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

#ifdef USE_WIN32_CONSOLE
    AllocConsole();
    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
#endif
#include "main.h"
#include "AppDelegate.h"
#include "CCEGLView.h"

#define USE_WIN32_CONSOLE

USING_NS_CC;

// uncomment below line, open debug console
// #define USE_WIN32_CONSOLE

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

#ifdef USE_WIN32_CONSOLE
    AllocConsole();
    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
#endif

 

CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setViewName("游戏名");
    eglView->setFrameSize(960, 1440);

 

修改AppDelegate.cpp里面启动的js脚步

#if JSB_ENABLE_DEBUGGER
    ScriptingCore::getInstance()->enableDebugger();
    ScriptingCore::getInstance()->runScript("main.debug.js");
#else
    ScriptingCore::getInstance()->runScript("游戏名-jsb.js");
#endif

 和屏幕大小

// Set the design resolution
    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionShowAll);

 

 

在ScriptingCore.cpp(D:/DevTool/cocos2d-x-2.2.2/cocos2d-x-2.2.2/scripting/javascript/bindings)

void ScriptingCore::reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
    js_log("%s:%u:%s/n",
            report->filename ? report->filename : "<no filename=/"filename/">",
            (unsigned int) report->lineno,
            message);
};

里面加个断点,方便看脚步出错问题

 

 

分类: cocos2d 标签:

启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误

2014年2月20日 没有评论

原因1:给定目录下jvm.dll不存在。

对策:(1)重新安装jre或者jdk并配置好环境变量。(2)copy一个jvm.dll放在该目录下。

原因2:eclipse的版本与jre或者jdk版本不一致

对策:要么两者都安装64位的,要么都安装32位的,不能一个是32位一个是64位。

http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260-zhs.html 下载新版本

分类: cocos2d 标签:

cocos2d-html5将js编译为jsc

2014年2月19日 没有评论

在d:/DevTool/cocos2d-x-2.2.2/cocos2d-x-2.2.2/tools/cocos2d-console/console

cocos2d_jscompile.py

cocos2d_version.py

cocos2d.py

cocos2d_new.py

 

d:/DevTool/cocos2d-x-2.2.2/cocos2d-x-2.2.2/tools/cocos2d-console/console>python
cocos2d.py jscompile --help
Usage: cocos2d.py jscompile -s src_dir -d dst_dir [-c -o COMPRESSED_FILENAME -j
COMPILER_CONFIG]

Options:
  -h, --help            show this help message and exit
  -s SRC_DIR_ARR, --src=SRC_DIR_ARR
                        source directory of js files needed to be compiled,
                        supports mutiple source directory
  -d DST_DIR, --dst=DST_DIR
                        destination directory of js bytecode files to be
                        stored
  -c, --use_closure_compiler
                        Whether to use closure compiler to compress all js
                        files into just a big file
  -o COMPRESSED_FILENAME, --output_compressed_filename=COMPRESSED_FILENAME
                        Only available when '-c' option was True
  -j COMPILER_CONFIG, --compiler_config=COMPILER_CONFIG
                        The configuration for closure compiler by using JSON,
                        please refer to compiler_config_sample.json

下面说一下可选参数,可选参数的意思是使用closure compiler工具压缩代码为一个文件。

COMPRESSED_FILENAME是压缩后的文件名,最好使用xxx.js,因为工具会自动再后面加个c

COMPILER_CONFIG是压缩时调用的配置文件,需要根据项目需求自己填写,在bin目录下有一个做好的缺省例子可以使用,compiler_config_sample.json

 

android

由于android下先要执行pro.android/build_native.sh脚本,所以我们可以在脚本里加入自动编译的功能,代码如下:

COCOS2D_CONSOLE=$COCOS2DX_ROOT/tools/cocos2d-console/console/
python $COCOS2D_CONSOLE/cocos2d.py jscompile -s assets/script/ -d assets/src/;
cd assets/src;
find .-type f -name "*.js"| xargs rm -rf;
cd ../../;

 

以上代码要放在调用NDK编译之前。

ios

由于ios下编译没有对应的build_native.sh脚本,所以就没法使用类似的方式了。幸好xcode下编译时可以添加自定义的run script

选择 项目 -> TARGETS -> Build Phases -> Add Build Phases -> Add Run Script,添加如下的内容:

source ~/.bash_profile
CONSOLE_PATH=$COCOS2DX_ROOT"/tools/cocos2d-console/console/";
TARGET_DIR=$BUILT_PRODUCTS_DIR"/"$PRODUCT_NAME".app/";
JS_DIR=$TARGET_DIR"/src/";/usr/bin/python $CONSOLE_PATH/cocos2d.py jscompile -s $JS_DIR  -d $JS_DIR;
find $JS_DIR -type f -name "*.js"| xargs rm -rf;

 

这样在编译时就会自动调用该脚本。(需要在.bash_profile里定义cocos2dx的根目录,并且变量名为COCOS2DX_ROOT)

将js编译为字节码发布,就不用担心别人可以拿到js源代码了。

分类: cocos2d 标签:

create_project.py报错问题,建议用回python2.7

2014年2月18日 没有评论

d:/DevTool/cocos2d-x-2.2.2/cocos2d-x-2.2.2/tools/project-creator/create_project.py 报错

d:/DevTool/cocos2d-x-2.2.2/cocos2d-x-2.2.2/tools/project-creator>python create_p
roject.py -project HelloWorld -package org.HelloWorld.game
  File "create_project.py", line 27
    print "Usage: create_project.py -project PROJECT_NAME -package PACKAGE_NAME
-language PROGRAMING_LANGUAGE"

                             ^
SyntaxError: invalid syntax

原因,装的是python 3.3.4。

3.0之前python语法是:print ‘hello’

3.0开始是:print(’hello’)

分类: cocos2d 标签:

编辑器CocoStudio和CocosBuilder的对比

2014年2月11日 没有评论

来源:http://4137613.blog.51cto.com/4127613/1352805

 

  CocosBuilder CocoStudio
控件种类 支持大部分cocos2d-x自带的常用控件。但对很多常用高级控件没有支持,比如输入框,滚动列表,进度条等 开发了一套和cocos2d-x之前的控件功能类似的控件,自成体系,常用控件上比CocosBuilder支持的更完备,输入框,滚动列表,进度条都支持,很多控件可以开启九宫格做优化
裁剪 不支持 支持
按键回调 支持 支持
UI动画 支持 支持,但由于在UI动画界面中没有属性框,所以无法精确控制动画
UI缓动动画 支持 支持,且支持自定义缓动的函数曲线
UI动画中进行回调 支持动画中插入回调,支持动画结束的回调,动画开始的回调可以自己做很简单 不支持动画中插入回调,只支持动画开始和结束时的回调
UI动画中播放声音 支持 不支持
插件 代码开源,支持 代码暂未开放,没找到接口
单个对象点击交互 不支持 支持
中文文档与教程 数量一般且质量不高,但编辑器足够简单可以摸索,少量功能需要自行摸索 较多,但不够新
易学易用性 设计上高度一致性,一通百通 布局上功能多且繁杂,有一定学习成本
稳定性 一般,有时崩溃 稍好,还是偶尔崩溃,也可能跟VM虚拟机有关
操作系统 OS X Windows

 

综上,CocoStudio在控件数量上,和一些常用功能上(比如裁剪,九宫格,单个对象交互等)支持较好,且功能足够用。

 

CocosBuilder缺乏一些常用控件和功能,但整个设计更加优良,具备插件式结构且开源,所以有相当强的扩展性,有技术能力的公司可以自行完善,这样开发起来更加可控,如果只是添加控件的话,3~4周可以搞定。很多人对CocosBuilder的认识只限于UI编辑器,其实他是一个不错的动画编辑(虽然他其实并不支持骨骼动画)和特效编辑。但CocosBuilder使用的是cocos2d-iphone的运行库,现在cocos2d-iphone和cocos2d-x已经不再保证接口一致性了,所以未来扩展可能会遇到问题。

分类: cocos2d 标签:

shaderProgram in cocos2d 3.0 doesn't work

2014年2月5日 没有评论

I have just started with Cocos2d 3.0 after using 1.1 for a long time.
I wanted to test the shaders out and looked up some tutorials.
All tutorials seems to use the CCSprite property “shaderProgram”.
When I try it like this:

renderTexture.sprite.shaderProgram = [[CCGLProgram alloc] initWithVertexShaderByteArray:ccPositionTextureA8Color_vert fragmentShaderByteArray:ccPositionTextureColorAlphaTest_frag]

Xcode gives me an error saying: “Property ‘shaderProgram’ not found on object type CCSprite *”

Is this property removed or changed from version 2.0 to 3.0 and how would I go about using it in Cocos2d 3.0?

Thanks!

Adding this import:

#import "CCNode_Private.h"

allows you to access CCNode’s shaderProgram memberc

分类: cocos2d, stackoverflow精选 标签:

【HTML5物理小Demo】用Box2dWeb实现锁链+弹簧效果

2014年2月5日 没有评论

最近开始研究Box2dweb,Box2dweb是一款物理引擎,主要是对物理刚体和关节连接进行了封装,box2dweb很强大当然也有些复杂,不过幸好lufylegend.js做了这方面的封装,在制作时如果用lufylegend配合Box2dweb,那就简单多了。要学习box2dWeb我还是给大家推荐拉登大叔的博客,地址:http://www.ladeng6666.com/blog,写得相当好,话说他的文章中还运用了相当多的修辞手法呢,看他的文章边学技术,边学写作,哈哈。顺便也提一提,本次实现的效果也是模仿拉登大叔一篇文章中的效果,不过大叔的是ActionScript版本的,我是Js版的。

最后还是祝大家新年快乐吧~虽然这祝福来晚了,不过还是满含我的诚意……

好了,费话不多说,直接进入正题。

首先看截图吧,如下:

【HTML5物理小Demo】用Box2dWeb实现锁链+弹簧效果

【HTML5物理小Demo】用Box2dWeb实现锁链+弹簧效果

测试链接:http://game.h5stars.com/20141952ee70ee9c117/

接下来就来讲一讲实现步骤。

 

一,准备工作

首先你需要下载lufylegend和box2dweb 这两个引擎。

box2dweb可以到这里下载:

http://code.google.com/p/box2dweb/downloads/list

lufylegend可以到这里:

http://lufylegend.com/lufylegend

关于lufylegend怎么用,可以到这里看看API文档:

http://lufylegend.com/lufylegend/api

Box2dWeb怎么用?其实我也不太清楚,这次主要用lufylegend封装的API,用到原生API的时候我自己来讲讲吧,讲的差不要骂喔~

 

二,原理

这个小demo的原来其实很简单,就是将几块矩形小刚体用旋转关节连接起来。当然,说起来很容易,其实做起来还是要深究的。在我看到拉登大叔的文章之前,其实我也没有想到什么方法,于是就借鉴了大叔的文章,原理不是我独创的,所以呢,不好直说,免得大叔看到了不高兴,大家看一看拉登大叔的文章就能明白原理了。

文章地址如下:http://www.ladeng6666.com/blog/2012/11/25/create-box2d-linkage-or-bridge-effect-using-b2joint/

 

三,含详细注释的源代码

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>box2d demo</title>
	<script type="text/javascript" src="./Box2dWeb-2.1.a.3.min.js"></script>
	<script type="text/javascript" src="./lufylegend-1.8.7.min.js"></script>
	
	<script type="text/javascript">
		init(50,"mylegend",600,400,pageInit);
		function pageInit(){
			LStage.setDebug(true);
			LStage.box2d = new LBox2d();

			if(LStage.canTouch == true){
				document.body.style.margin = "0px 0px";
				LStage.stageScale = LStageScaleMode.SHOW_ALL;
				LSystem.screen(LStage.FULL_SCREEN);
			}

			var mainObj = new Main();
			addChild(mainObj);
		}

		/**
		 *Main
		 *@author: Yorhom
		 *@http://blog.csdn.net/yorhomwang
		*/
		function Main(){
			var s = this;
			base(s,LSprite,[]);

			/**加入围墙*/
			s.addWall();
			/**加入锁链桥*/
			s.addBridge();
			/**随机加入其他物体*/
			s.addRandomObj();
		}
		Main.prototype.addWall = function(){
			var s = this;
			
			//设置围墙大小
			var wallSize = 10;
			//设置围墙数据
			var wallList = [
				//左边
				[wallSize*0.5, LStage.height*0.5, wallSize, LStage.height],
				//右边
				[LStage.width-wallSize*0.5, LStage.height*0.5, wallSize, LStage.height],
				//上面
				[LStage.width*0.5, wallSize*0.5, LStage.width, wallSize],				
				//下面
				[LStage.width*0.5, LStage.height-wallSize*0.5, LStage.width, wallSize],
			];
			//通过遍历围墙数据,添加四面围墙
			for(var key in wallList){
				//获取数据
				var item = wallList[key];
				//创建围墙对象
				var wallLayer = new LSprite();
				//设定对象位置
				wallLayer.x = item[0];
				wallLayer.y = item[1];
				//加入刚体
				wallLayer.addBodyPolygon(item[2],item[3],0);
				//加入显示列表
				s.addChild(wallLayer);
			}
		};
		Main.prototype.addBridge = function(){
			var s = this;

			//关节向量
			var vec = new LStage.box2d.b2Vec2();
			//添加对象数量
			var amount = 6;
			//设置对象宽度和高度
			var bw=50,bh=15;
			//获取锁链桥总长度
			var bridgeWidth = bw*amount;
			//设置锁链桥开始位置
			var initX=(LStage.width-bridgeWidth)*0.5,
				initY=(LStage.height-bh)*0.5+30;
			//设置用于固定锁链桥的定点半径
			var anchorR = 15;

			/**用于固定锁链桥的定点A*/
			var anchorA = new LSprite();
			anchorA.x = initX-anchorR;
			anchorA.y = initY-anchorR;
			anchorA.addBodyCircle(anchorR,anchorR,anchorR,0);
			s.addChild(anchorA);
			/**用于固定锁链桥的定点B*/
			var anchorB = new LSprite();
			anchorB.x = bridgeWidth+initX-anchorR;
			anchorB.y = initY-anchorR;
			anchorB.addBodyCircle(anchorR,anchorR,anchorR,0);
			s.addChild(anchorB);

			//上一个对象
			var previousBlock = anchorA;

			/**循环添加刚体*/
			for(var i=0; i<amount; i++){
				//实例化对象
				var block = new LSprite();
				//设定对象位置
				block.x = initX+i*bw+bw*0.5;
				block.y = initY;
				//加入刚体
				block.addBodyPolygon(bw,bh,1);
				//设置鼠标拖动
				block.setBodyMouseJoint(true);
				//加入显示列表
				s.addChild(block);
				//加入关节
				var revoluteJoint = new LStage.box2d.b2RevoluteJointDef();
				vec.Set((initX+i*bw)/30, initY/30);
				revoluteJoint.Initialize(previousBlock.box2dBody,block.box2dBody,vec);
				LStage.box2d.world.CreateJoint(revoluteJoint);
				//更改上一个对象
				previousBlock = block;
			}
			//将最后一个刚体固定
			var revoluteJoint = new LStage.box2d.b2RevoluteJointDef();
			vec.Set((initX+i*bw)/30, initY/30);
			revoluteJoint.Initialize(previousBlock.box2dBody,anchorB.box2dBody,vec);
			LStage.box2d.world.CreateJoint(revoluteJoint);
		};
		Main.prototype.addRandomObj = function(){
			var s = this;
			for(var i=0; i<10; i++){
				//创建对象
				var obj = new LSprite();
				//设置对象位置
				obj.x = Math.floor(Math.random()*(400-200+1)+200);
				obj.y = 0;
				//加入显示列表
				s.addChild(obj);
				//根据随机数添加不同的刚体
				if(Math.random() > 0.5){
					//获取随机宽度和高度
					var w = Math.floor(Math.random()*10)+25;
					var h = Math.floor(Math.random()*10)+25;
					//重现设置y坐标
					obj.y += h*0.5;
					//添加矩形刚体
					obj.addBodyPolygon(w,h,1);
				}else{
					//获取随机半径
					var r = Math.floor(Math.random()*20)+5;
					//重现设置y坐标
					obj.y += r;
					//添加圆形刚体
					obj.addBodyCircle(r,r,r,1);
				}
				//设置鼠标拖动
				obj.setBodyMouseJoint(true);
			}
		};
	</script>
</head>
<body>
	<div id="mylegend"></div>
</body>
</html>

所有代码都在这里了,还是很少的,对吧。看了拉登大叔的原理讲解,再来看我写的js代码就非常容易了。主要是注意以下几个地方。

1,添加刚体

在box2dweb中添加刚体超级麻烦,把整个创建过程告诉大家估计大家都会觉得不耐烦,所以,我用到了lufylegend.js添加刚体,这样一来添加刚体就被简化成一步了。非常方便,不是吗?在lufylegend中添加刚体一共有这几个函数:

addBodyCircle() 添加原形刚体
addBodyPolygon() 添加矩形刚体
addBodyVertices() 添加不规则图形刚体

具体的参数说明和使用举例可以参见lufylegend的API文档中LSprite的API。文档地址已在文章的准备工作一栏写出。

2,添加关节

在lufylegend虽然也有添加关节的封装,但是不能设置关节点。所以我还是用了box2dweb原生方法。添加关节的代码如下:

var revoluteJoint = new LStage.box2d.b2RevoluteJointDef();
vec.Set((initX+i*bw)/30, initY/30);
revoluteJoint.Initialize(previousBlock.box2dBody,block.box2dBody,vec);
LStage.box2d.world.CreateJoint(revoluteJoint);

其他的好理解,主要是vec这个变量,它在这里是一个向量对象,实例化代码如下:

var vec = new LStage.box2d.b2Vec2();

其实这个b2Vec2这个类可以传参数,和它的成员函数Set的参数是一样的。但是这里又多个关节,所以就没有直接设置,而是在后面用Set方法设置。这个向量可以看成一个json吧,传的参数就是设定关节的位置(x,y)。

在创建了关节之后,千万别忘记下面的代码:

LStage.box2d.world.CreateJoint(revoluteJoint);

另外,Initialize方法传的参数是box2dweb的刚体对象,在LSprite中的 box2dBody就可以获取该LSprite添加的刚体。

3,固定动态刚体

在box2dweb中,刚体分动态和静态。静态刚体比较老实,就呆在原地不动;动态刚体很活泼,不停地在做运动。

拉登大叔其实也写过相关的文章,但是我没怎么看,于是就自己想了一个方法:首先在锁链的两端建立两个圆形静态刚体,然后把锁链两端的两块矩形刚体分别连在附近的圆形静态刚体上,圆形静态刚体就会帮忙把锁链拽着,不让它乱跑。但由于锁链中每个矩形刚体是动态的,所以他们还是可以互相牵扯的。

4,如果你自己在用lufylegend+box2dweb编写时看不到图象,该怎么办?

首先你要检测一下是否在最底层上加了一个LSprite,并且用这个LSprite的graphics画了一个不透明的背景。如果是的话,你可以把这个LSprite去掉,然后再看看有没有。如果还没有,可能有以下几种原因:(1)没有在用之前加入LStage.setDebug(true); (2)没有在使用box2dweb之前加入LStage.box2d = new LBox2d();

 

源代码在上面已经全部给出了,运行时需要配置一下引擎box2dweb和lufylegend,然后把引擎的压缩版本(文件名含.min)放在与html同级的文件目录下即可运行,测试愉快~

分类: box2D, html5 标签:

PivotJoints with friction and limits in Cocos2d V3 (Chipmunk)

2014年2月2日 没有评论

I try to convert a game which I started with SpriteKit to Cocos2d V3. I have some problems with the physics though. I create a human like playing figure. The limbs are connected via PinJoints in SpriteKit. I recreated that basic functionality via PivotJoints in Chipmunk. That works as expected.

But I need to add some friction to the joints. Right now they just rotate as fast as possible and even more important I need to limit the rotation angle of the joints. As you can imagine, most people can’t rotate their shoulders freely by 360 degrees. ;)

AFAIK I should use ChipmunkRotaryLimitJoint and ChipmunkGearJoint to achieve that. My problem is, that I can’t make it work because I don’t know how to attach them correctly. This is my code right now:

- (CCPhysicsJoint *)createPinJointWithBodyA:(CCPhysicsBody *)bodyA
                                      bodyB:(CCPhysicsBody *)bodyB
                                     anchor:(CGPoint)anchor
                                   friction:(CGFloat)friction
                                 lowerLimit:(CGFloat)lowerLimit
                                 upperLimit:(CGFloat)upperLimit
{

    CCPhysicsJoint *pin = [CCPhysicsJoint 
        connectedPivotJointWithBodyA:bodyA
                               bodyB:bodyB
                             anchorA:anchor];

    ChipmunkRotaryLimitJoint *limitJoint = [ChipmunkRotaryLimitJoint 
        rotaryLimitJointWithBodyA:bodyA.body 
                            bodyB:bodyB.body
                              min:CC_DEGREES_TO_RADIANS(lowerLimit)
                              max:CC_DEGREES_TO_RADIANS(upperLimit)];

    ChipmunkGearJoint *gearJoint = [ChipmunkGearJoint 
        gearJointWithBodyA:bodyA.body
                     bodyB:bodyB.body
                     phase:0.5
                     ratio:0.5];

    return pin;
}

(The values in the gearJoint call are just place holders!)

Does anybody have an idea how this is supposed to work? I found some things via Google, but all tutorials assume, that I use chipmunk in some other environment. Do I have to create my own CCPhysicJoint implementation for these limit and gear joints?

Thanks and best wishes,
Thomas

I think I solved this problem. It turned out I had to create my own CCPhysicsJoint Category that implements the ChipmunkRotaryLimitJoint and a ChipmunkRotaryDampedSpring. It’s not exactly the same but it works good enough for now.

The code looks like this right now:

[CCPhysicsJoint connectedRotaryLimitJointWithBodyA:bodyA
                                             bodyB:bodyB
                                               min:CC_DEGREES_TO_RADIANS(lowerLimit)
                                               max:CC_DEGREES_TO_RADIANS(upperLimit)];

[CCPhysicsJoint connectedDampedRotarySpringWithBodyA:bodyA
                                               bodyB:bodyB
                                           restAngle:0
                                           stiffness:friction *1000.0f
                                             damping:10000.0f];

I just asked if this should be included in the Cocos2D codebase. For the time being, this is the wrapper:

CCPhysicsJoint+THCAdditions.h

//
//  CCPhysicsJoint+THCAdditions.h
//
//  Created by Thomas Hempel on 02.02.14.
//  Copyright (c) 2014 Thomas Hempel. All rights reserved.
//

#import "CCPhysicsBody.h"
#import "CCPhysicsJoint.h"

@interface CCPhysicsJoint (THCAdditions)

+ (CCPhysicsJoint *)connectedRotaryLimitJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max;
+ (CCPhysicsJoint *)connectedGearJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio;
+ (CCPhysicsJoint *)connectedSimpleMotorJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate;
+ (CCPhysicsJoint *)connectedDampedRotarySpringWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:(CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping;

@end

CCPhysicsJoint+THCAdditions.m

//
//  CCPhysicsJoint+THCAdditions.m
//
//  Created by Thomas Hempel on 02.02.14.
//  Copyright (c) 2014 Thomas Hempel. All rights reserved.
//

#import "CCPhysicsJoint+THCAdditions.h"
#import "CCPhysics+ObjectiveChipmunk.h"

// ------------------------------------------------------------------------
#pragma mark - Rotary Limit Joint
// ------------------------------------------------------------------------

@interface CCPhysicsRotaryLimitJoint : CCPhysicsJoint
@end

@implementation CCPhysicsRotaryLimitJoint {
    ChipmunkRotaryLimitJoint *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max
{
    if ((self = [super init])){
        _constraint = [ChipmunkRotaryLimitJoint rotaryLimitJointWithBodyA:bodyA.body
                                                                    bodyB:bodyB.body
                                                                      min:min
                                                                      max:max];
        _constraint.userData = self;
    }
    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Gear Joint
// ------------------------------------------------------------------------

@interface CCPhysicsGearJoint : CCPhysicsJoint
@end

@implementation CCPhysicsGearJoint {
    ChipmunkGearJoint *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio
{
    if ((self = [super init])){
        _constraint = [ChipmunkGearJoint gearJointWithBodyA:bodyA.body
                                                      bodyB:bodyB.body
                                                      phase:phase
                                                      ratio:ratio];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Simple Motor Joint
// ------------------------------------------------------------------------

@interface CCPhysicsSimpleMotorJoint : CCPhysicsJoint
@end

@implementation CCPhysicsSimpleMotorJoint {
    ChipmunkSimpleMotor *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate
{
    if ((self = [super init])){
        _constraint = [ChipmunkSimpleMotor simpleMotorWithBodyA:bodyA.body
                                                          bodyB:bodyB.body
                                                           rate:rate];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Damped Rotary Spring
// ------------------------------------------------------------------------

@interface CCPhysicsDampedRotarySpring : CCPhysicsJoint
@end

@implementation CCPhysicsDampedRotarySpring {
    ChipmunkDampedRotarySpring *_constraint;
}

- (id)initWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:    (CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping
{
    if ((self = [super init])){
        _constraint = [ChipmunkDampedRotarySpring dampedRotarySpringWithBodyA:bodyA.body
                                                                        bodyB:bodyB.body
                                                                    restAngle:restAngle
                                                                    stiffness:stiffness
                                                                      damping:damping];
        _constraint.userData = self;
    }

    return self;
}

- (ChipmunkConstraint *)constraint
{
    return _constraint;
}

- (void)willAddToPhysicsNode:(CCPhysicsNode *)physics
{
}

@end

// ------------------------------------------------------------------------
#pragma mark - Implementation
// ------------------------------------------------------------------------


@implementation CCPhysicsJoint (THCAdditions)

+ (CCPhysicsJoint *)connectedRotaryLimitJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB min:(CGFloat)min max:(CGFloat)max
{

    CCPhysicsJoint *joint = [[CCPhysicsRotaryLimitJoint alloc] initWithBodyA:bodyA bodyB:bodyB min:min max:max];
    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedGearJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB phase:(CGFloat)phase ratio:(CGFloat)ratio
{
    CCPhysicsJoint *joint = [[CCPhysicsGearJoint alloc] initWithBodyA:bodyA bodyB:bodyB phase:phase ratio:ratio];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedSimpleMotorJointWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB rate:(CGFloat)rate
{
    CCPhysicsJoint *joint = [[CCPhysicsSimpleMotorJoint alloc] initWithBodyA:bodyA bodyB:bodyB rate:rate];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

+ (CCPhysicsJoint *)connectedDampedRotarySpringWithBodyA:(CCPhysicsBody *)bodyA bodyB:(CCPhysicsBody *)bodyB restAngle:(CGFloat)restAngle stiffness:(CGFloat)stiffness damping:(CGFloat)damping
{
    CCPhysicsJoint *joint = [[CCPhysicsDampedRotarySpring alloc] initWithBodyA:bodyA bodyB:bodyB restAngle:restAngle stiffness:stiffness damping:damping];

    [bodyA addJoint:joint];
    [bodyB addJoint:joint];

    [bodyA.physicsNode.space smartAdd:joint];

    return joint;
}

@end

Best wishes,
Thomas