Cocos2dx工程总结
2016-02-29 00:12
429 查看
Cocos2dx 学习过程
1. 学习 Cocos2dx
Cocos官网 (这个不用说)天涯海阁
红孩儿的博客
老G的小屋
子龙山人
Himi的博客
笨木头的博客
2. 学习 JNI 与 NDK 开发
JNI 与 NDK 开发这个必须要掌握的知识点。网上没看到比较全面的介绍。1. 学习JNI 与 NDK 开发推荐大家看Android框架揭秘第4章-JNI与NDK,讲解的简单易懂,也比较全。2. 了解 jni.c 代码3. 解决技术难点
将图片从 Android 传递到 Cocos
* //解决思路:android 端将图片生成 byte[], 通过 jni 接口传到C生成 Texture2D* signed char* data = (signed char*)info.env->GetByteArrayElements(bitmapinfo_byte, 0); Texture2D* textureView = new Texture2D(); Image* image = new Image(); bool bRet = image->initWithImageData((unsigned char*)data, bitmapinfo_length); if (textureView && textureView->initWithImage(image)) { image->release(); } info.env->ReleaseByteArrayElements(bitmapinfo_byte, data, 0);
将对象从 Android 传递到 Cocos (由 C 调用 JAVA 返回对象)
JniMethodInfo info; const char* clazzName = "org.cocos2dx.cpp.AppActivity"; const char* clazzSingle = "getInstance"; const char* clazzSingleSignature = "()Ljava/lang/Object;"; const char* ExxName = "getViewBitmap"; const char* ExxSignature = "()Lcom/cocos2dx/JniClass/BitmapInfo;"; const char* BitmapInfo_getBitByte = "getBitByte"; const char* getBitByteSignature = "()[B"; const char* BitmapInfo_getLength = "getLength"; const char* getLengthSignature = "()I"; if (JniHelper::getStaticMethodInfo(info, clazzName, clazzSingle, clazzSingleSignature)) { jclass header_class = info.env->FindClass(clazzName); jmethodID instance_id = info.env->GetStaticMethodID(header_class, clazzSingle, clazzSingleSignature); jobject instance_object = (jobject)info.env->CallStaticObjectMethod(header_class, instance_id); jmethodID Exx_id = info.env->GetMethodID(header_class, ExxName, ExxSignature); jobject bitmapinfo_object = (jobject)info.env->CallObjectMethod(instance_object, Exx_id); jclass bitmapinfo_class = info.env->GetObjectClass(bitmapinfo_object); jmethodID bitByte_id = info.env->GetMethodID(bitmapinfo_class, BitmapInfo_getBitByte, getBitByteSignature); jbyteArray bitmapinfo_byte = (jbyteArray)info.env->CallObjectMethod(bitmapinfo_object, bitByte_id); jmethodID length_id = info.env->GetMethodID(bitmapinfo_class, BitmapInfo_getLength, getLengthSignature); jint bitmapinfo_length = (jint)info.env->CallIntMethod(bitmapinfo_object, length_id); }
JAVA 编写的代码
public static AppActivity appInstance;// 定义单例 public static Object getInstance() { return appInstance; } public BitmapInfo getBitmap() { BitmapInfo info = new BitmapInfo(); return info; } public class BitmapInfo{ private byte[] bitByte; private int length; public byte[] getBitByte() { return bitByte; } public void setBitByte(byte[] bitByte) { this.bitByte = bitByte; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } }
将对象从 Android 传递到 Cocos (由 JAVA 将对象传给 C )
JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_strokeViewonPenUp(JNIEnv *env, jobject clazz, jobject object) { const char* fuctionA = "A"; const char* fuctionASignature = "()Z"; const char* fuctionB = "B"; const char* fuctionBSignature = "()I"; const char* fuctionC = "C"; const char* fuctionCSignature = "()I"; JudgementResult* result = new JudgementResult(); jclass result_class = env->GetObjectClass(object); jmethodID A_id = env->GetMethodID(result_class, fuctionA, fuctionASignature); result->setA((bool)env->CallBooleanMethod(object, A_id)); jmethodID B_id = env->GetMethodID(result_class, fuctionB, fuctionBSignature); result->setB((int)env->CallIntMethod(object, B_id)); jmethodID C_id = env->GetMethodID(result_class, fuctionC, fuctionCSignature); result->setC((int)env->CallIntMethod(object, C_id)); result->retain(); NotificationCenter::getInstance()->postNotification(msg_HYH_Penup, result); }
JAVA 编写的代码
public native void strokeViewonPenUp(Object result);
将数组对象从 Cocos 传递到 Android (由 C 将数组对象传给 JAVA )
void CLASS::initView(__Array* mDataArray) { if (mDataArray == nullptr) { return; } int size = mDataArray->count(); JniMethodInfo info; const char* clazzName = "org.cocos2dx.cpp.AppActivity"; const char* clazzSingle = "getInstance"; const char* clazzSingleSignature = "()Ljava/lang/Object;"; const char* fuctionName = "initView"; const char* fuctionSignature = "([Lcom/cocos2dx/ViewData;)V"; const char* ViewDataClazz = "com/cocos2dx/ViewData"; const char* ViewDataConstructor = "<init>"; const char* ViewDataConstructorSignature = "()V"; const char* SetA = "setA"; const char* setASignature = "(Ljava/lang/String;)V"; const char* setB = "setB"; const char* setBSignature = "(I)V"; if (JniHelper::getStaticMethodInfo(info, clazzName, clazzSingle, clazzSingleSignature)) { jclass header_class = info.env->FindClass(clazzName); jmethodID instance_id = info.env->GetStaticMethodID(header_class, clazzSingle, clazzSingleSignature); jobject instance_object = (jobject)info.env->CallStaticObjectMethod(header_class, instance_id); jmethodID fuction_id = info.env->GetMethodID(header_class, fuctionName, fuctionSignature); jobjectArray viewDataArray; jclass clsViewData = info.env->FindClass(ViewDataClazz); if (clsViewData == NULL) { cocos2d::log("null"); return; } viewDataArray = info.env->NewObjectArray(size, clsViewData, NULL); if (viewDataArray == NULL) { cocos2d::log("null"); return; } for (int i = 0; i < size; ++i) { ViewData *data = (ViewData *)mDataArray->objectAtIndex(i); jmethodID viewDataFuction_id = info.env->GetMethodID(clsViewData, ViewDataConstructor, ViewDataConstructorSignature); jobject viewDataObject = info.env->NewObject(clsViewData, viewDataFuction_id);//对象无参构造函数 viewDataFuction_id = info.env->GetMethodID(clsViewData, SetA, setASignature); jstring jword = info.env->NewStringUTF(data->getA()); info.env->CallVoidMethod(viewDataObject, viewDataFuction_id, jword); info.env->DeleteLocalRef(jword); viewDataFuction_id = info.env->GetMethodID(clsViewData, setB, setBSignature); info.env->CallVoidMethod(viewDataObject, viewDataFuction_id, data->getB()); info.env->SetObjectArrayElement(viewDataArray, i, viewDataObject); info.env->DeleteLocalRef(viewDataObject); } // info.env->CallVoidMethod(instance_object, fuction_id, viewDataArray); } return; }
读取SD卡中图片
有时图片资源太大,如果直接放在apk中,会使安装包很大。采用的策略:将资源单独下载,资源缓存到SD卡中,然后读取SD卡中的资源Texture2D* getTexture(const char* filePath) { char * TextureBuffer; long length; ifstream in(filePath, ios::in | ios::binary | ios::ate); length = in.tellg(); log("length.2=%ld", length); in.seekg(0, ios::beg); TextureBuffer = new char[length + 1]; in.read(TextureBuffer, length); in.close(); TextureBuffer[length] = '\0';//防止内存问题 Image *image = new Image(); if (false == image->initWithImageData((unsigned char*)TextureBuffer, length)) { log("cocos2dx can not load PNG"); } delete[] TextureBuffer; Texture2D * texture2D = new Texture2D(); texture2D->initWithImage(image); image->release(); return texture2D; }
Cocos2dx 由 JAVA 与 C 层传递数据的几种解决方案
在 C 端采用全局变量,将数据存到全局变量中,只能主动读取全局变量(缺点:不知道变量何时更新)不管是 C 到 Java,还是 Java 到 C,就是把数据组装成json然后转成字符串传递(缺点:效率比较低)
在 C 端使用 NotificationCenter 消息机制,将数据打包分发(优点:异步回调)
使用 Android View 控件
之前做过一个项目,需要用到 Android 中的自定义的 View 控件,如何解决呢,这就需要了解 Android 框架。参考Android源码设计模式解析与实战第15章的深度拓展。查看 Cocos2dxActivity.java 中
@Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); CocosPlayClient.init(this, false); onLoadNativeLibraries(); sContext = this; this.mHandler = new Cocos2dxHandler(this); Cocos2dxHelper.init(this); this.mGLContextAttrs = getGLContextAttrs(); this.init(); if (mVideoHelper == null) { mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout); } if(mWebViewHelper == null){ mWebViewHelper = new Cocos2dxWebViewHelper(mFrameLayout); } }
查看 init();
protected FrameLayout mFrameLayout = null; // =========================================================== // Methods // =========================================================== public void init() { // FrameLayout ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); mFrameLayout = new FrameLayout(this); mFrameLayout.setLayoutParams(framelayout_params); // Cocos2dxEditText layout ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); Cocos2dxEditText edittext = new Cocos2dxEditText(this); edittext.setLayoutParams(edittext_layout_params); // ...add to FrameLayout mFrameLayout.addView(edittext); // Cocos2dxGLSurfaceView this.mGLSurfaceView = this.onCreateView(); // ...add to FrameLayout mFrameLayout.addView(this.mGLSurfaceView); // Switch to supported OpenGL (ARGB888) mode on emulator if (isAndroidEmulator()) this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer()); this.mGLSurfaceView.setCocos2dxEditText(edittext); // Set framelayout as the content view setContentView(mFrameLayout); }
setContentView(mFrameLayout); 这个就是需要找到的。
所以对于 Android 自定义 View 添加到 mFrameLayout 即可。
4. 现在使用比较多的引擎
Cocos Creator(多平台)白鹭HTML引擎(多平台)
Unity3d(3D)
相关文章推荐
- cocos2d-x 有关Node
- 初试cocos2d-x坐标系
- cocos2d-x与lua数据传输操作之C++版ByteArray
- COCOS学习笔记--粒子系统
- 【Quick-COCOS2D-X 3.3 怎样绑定自己定义类至Lua之四】使用绑定C++至Lua的自己定义类
- cocos2d-x 3.10 屏幕适配问题
- Cocos2d-x 3.9 Lua 自定义事件
- Cocos2d-x 3.x引用计数
- cocos2d-x Lua绑定C++ 自定义类到Runtime(Lua-binding)
- Cocos2d-x 3.x物理世界
- cocos2d-x-bug集
- ScrollView模拟上拉刷新
- cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检測
- 【Cocos2d-x 001】VS2012打开Cocos解决方案显示加载失败
- Cocos2d-x优化中多线程并发訪问
- cocos2dx实现象棋之运动
- spine3.0导出文件转换成cocos3.8可使用文件工具
- Cocos2dx实现象棋之布局
- cocos2d-实现读取.plist文件(使用数组CCArray)
- cocos2dx 3.0调用点击事件