cocos2d-x安卓静态库

cocos2d-x的新建工程项目重新编译整个引擎,在windows系统下好说,只需要把库指定。android和IOS如果也是每个项目都生成引擎,游戏项目多硬盘空间也吃紧。适用cocos2d3.13 ,3.5版不通过

  1.  首先找到一个cocos2d-x的测试项目(如cpp_test),进行一次编译。完成后,在proj.android/obj/local目录下可以找到中间过程中生成的所有静态库文件。把这些静态库文件(带上ABI目录)复制出来,objs-debug和objs文件夹可删除,放到一个新的目录(如:cclib)中。
  2.  在cclib中创Android.mk文件,文件内容见代码附1.
  3. 新建Windows环境变量 CC_SRC_ROOT 为cocos2d源码目录(即cocos与external的上层目录)
  4. 在编译你的项目时依赖cclib即可,不需要依赖cocos2d目录下的Android.mk 附2

附1(cclib/Android.mk)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := cc_static
LOCAL_MODULE_FILENAME := libcc

LOCAL_EXPORT_C_INCLUDES := $(CC_SRC_ROOT)/cocos \
                    $(CC_SRC_ROOT)/cocos/. \
                    $(CC_SRC_ROOT)/cocos/.. \
                    $(CC_SRC_ROOT)/cocos/platform \
                    $(CC_SRC_ROOT)/cocos/base \
					$(CC_SRC_ROOT)/extensions \
                    $(CC_SRC_ROOT)/external \
                    $(CC_SRC_ROOT)/external/tinyxml2 \
                    $(CC_SRC_ROOT)/external/unzip \
                    $(CC_SRC_ROOT)/external/chipmunk/include/chipmunk \
                    $(CC_SRC_ROOT)/external/xxhash \
                    $(CC_SRC_ROOT)/external/nslog \
                    $(CC_SRC_ROOT)/external/poly2tri \
                    $(CC_SRC_ROOT)/external/poly2tri/common \
                    $(CC_SRC_ROOT)/external/poly2tri/sweep \
					$(CC_SRC_ROOT)/cocos/platform/android \
					$(CC_SRC_ROOT)/cocos/audio/include \
					$(CC_SRC_ROOT)/external/curl/include/android \
					$(CC_SRC_ROOT)/external/websockets/include/android \
					$(CC_SRC_ROOT)/cocos/editor-support \
					$(CC_SRC_ROOT)/external/Box2D \
					$(CC_SRC_ROOT)/external/flatbuffers \
					$(CC_SRC_ROOT)/external

LOCAL_CFLAGS   :=  -DUSE_FILE32API -fexceptions

LOCAL_CPPFLAGS := -Wno-deprecated-declarations -Wno-extern-c-compat

LOCAL_EXPORT_CFLAGS   := -DUSE_FILE32API -fexceptions

LOCAL_EXPORT_CPPFLAGS := -Wno-deprecated-declarations -Wno-extern-c-compat

LOCAL_EXPORT_LDLIBS := -lGLESv2 \
                       -llog \
                       -landroid \
               -lGLESv1_CM \
                       -lEGL \
               -lOpenSLES

# define the macro to compile through support/zip_support/ioapi.c


LOCAL_WHOLE_STATIC_LIBRARIES := cocos_freetype2_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_png_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jpeg_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_tiff_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_webp_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_chipmunk_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_zlib_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_curl_static
LOCAL_WHOLE_STATIC_LIBRARIES += websockets_static

LOCAL_WHOLE_STATIC_LIBRARIES += flatbuffers_static
LOCAL_WHOLE_STATIC_LIBRARIES += libaudioengine_static
LOCAL_WHOLE_STATIC_LIBRARIES += libbox2d_static
LOCAL_WHOLE_STATIC_LIBRARIES += libbullet_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocos2d_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocos2dandroid_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocos2dxinternal_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocos3d_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocosbuilder_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += libcocostudio_static
#LOCAL_WHOLE_STATIC_LIBRARIES += libcpufeatures_static
LOCAL_WHOLE_STATIC_LIBRARIES += libextension_static
LOCAL_WHOLE_STATIC_LIBRARIES += libnetwork_static
LOCAL_WHOLE_STATIC_LIBRARIES += librecast_static
LOCAL_WHOLE_STATIC_LIBRARIES += libspine_static
LOCAL_WHOLE_STATIC_LIBRARIES += libui_static

include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := flatbuffers_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/flatbuffers.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libaudioengine_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libaudioengine.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libbox2d_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libbox2d.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libbullet_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libbullet.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocos2d_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocos2d.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocos2dandroid_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocos2dandroid.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocos2dxinternal_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocos2dxinternal.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocos3d_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocos3d.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocosbuilder_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocosbuilder.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocosdenshion_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocosdenshion.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcocostudio_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcocostudio.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libcpufeatures_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcpufeatures.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libextension_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libextension.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libnetwork_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libnetwork.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := librecast_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/librecast.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libspine_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libspine.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libui_static
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libui.a
include $(PREBUILT_STATIC_LIBRARY)

#==============================================================
$(call import-module,freetype2/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,zlib/prebuilt/android)
$(call import-module,jpeg/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)
$(call import-module,chipmunk/prebuilt/android)
$(call import-module,curl/prebuilt/android)
$(call import-module,websockets/prebuilt/android)

附2(cpp-empty-test)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := cpp_empty_test_shared

LOCAL_MODULE_FILENAME := libcpp_empty_test

LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES := main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
                    $(LOCAL_PATH)/../../../../extensions \
                    $(LOCAL_PATH)/../../../.. \
                    $(LOCAL_PATH)/../../../../cocos/editor-support

#LOCAL_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES := cc_static
include $(BUILD_SHARED_LIBRARY)

#$(call import-module,.)
$(call import-module,cclib)

参考:http://www.cnblogs.com/leaving/p/5362918.html

批量编码转换utf-8

批量转换编码是很痛苦的事情,一种办法是自己去写代码来实现,你得解析判断文件编码的类型utf-8 utf-16 ansi ucs-2,然后判断,难保证都成功的转换。提供一种利用第三方工具批量转换成utf-8 ansi等。

安装nodepad++及插件

  1. 安装https://notepad-plus-plus.org/
  2. Plugins->Plugin Manager->Show Plugin Manager
  3. Python Script安装重启Notepad++
  4. Plugins->Python Script->New script
  5. 输入名字toUtf-8,然后复制下面python脚本
  6. 运行脚本Plugins->Python Script->scripts->toUtf-8

python脚本

转换utf-8、注意备份,是直接把文件编码转换,不支持中文路径

import os;
import sys;
from Npp import notepad #这里必须导入nodepad++ if i note this line, it says, "notepad is not defined"
filePathSrc="E:\\Beyond2\\"#"E:\\Songs2\\" # Path to the folder with files to convert
for root, dirs, files in os.walk(filePathSrc):
    for fn in files:
        if fn[-4:] == '.dtx': # Specify type of the files 判断指定的后缀名
            notepad.open(root + "\\" + fn)
            notepad.runMenuCommand("Encoding", "Convert to UTF-8")#想转成ANSI 替换UTF-8
            notepad.save()
            notepad.close()

 

Cocos2d-x在XP上完美运行

本文描述cocos2d-x 3.x版本的windows xp版本,即完美在xp系统上运行。

必备:

vs2013 update5 vs2015 update3,笔者系统win10 x64系统
cocos2d-x 3.X版本,已成功运行起来的的版本有3.4 3.5 3.10 3.13版本,其他版没试验,都很类似的修改。

libcocos2d项目属性修改

编译发布版的Release

添加预编译宏

项目菜单->项目属性->配置属性->C/C++->预编译
WIN32_WINNT=0x0501

添加链接库

项目菜单->项目属性->配置属性->链接->输入
user32.lib
gdi32.lib
advapi32.lib
Shell32.lib
ws2_32.lib

cocos2d-x源代码修改:

5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(47): error C2065: 'LPWSAPOLLFD' : undeclared identifier (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(47): error C2146: syntax error : missing ')' before identifier 'fdarray' (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(47): error C2165: 'left-side modifier' : cannot modify pointers to data (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(47): error C2513: 'INT *' : no variable declared before '=' (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(47): error C2059: syntax error : ')' (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(50): error C2065: 'LPWSAPOLLFD' : undeclared identifier (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(50): error C2146: syntax error : missing ')' before identifier 'fdarray' (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(50): warning C4229: anachronism used : modifiers on data are ignored (..networkWebSocket.cpp)
5>e:sdkcocos2d-x-cocos2d-x-3.10externalwebsocketsincludewin32win32helpers/websock-w32.h(50): error C2059: syntax error : ')' (..networkWebSocket.cpp)

直接注释掉

5>..baseCCConsole.cpp(412): error C3861: 'inet_pton': identifier not found
5>..baseCCConsole.cpp(417): error C3861: 'inet_pton': identifier not found
5>..baseCCConsole.cpp(443): error C3861: 'inet_ntop': identifier not found
5>..baseCCConsole.cpp(450): error C3861: 'inet_ntop': identifier not found

同样注释掉,如果你要用到就自己重写net_ntop函数,网上有教程。

依赖库修改

3.4 3.5版这一步直接跳过
xp错误的提示:InitializeCriticalsectionEx,
curl新版库用了函数,xp系统是没的,删除curl文件夹,再放旧版的,这里下载:http://pan.baidu.com/s/1mhvjlHm
cocos2d-x 3.13删除替换 webp :http://pan.baidu.com/s/1qYLA1ti

编译说明&vs运行库安装

Release每次都会重新编译
1、C/C++  -> Genera -> Debug Information Format: Program Database for Edit & Continue (/ZI), 或者 Program Database (/Zi) ,或者删除None
2、在你工程加入链接库libcocos2d.lib,移除掉libcocos2d的依赖项目
除了f#不用装,都勾上下载地址:http://pan.baidu.com/s/1c1e4ALq ,注意如果是2015安装:https://www.microsoft.com/en-hk/download/details.aspx?id=48145

总结

同样如果你想编译xp项目,也可以做参考,特别是要指定WIN32_WINNT=0x0501。
项目菜单->项目属性->配置属性->常规->平台工具集,选择“VS2013WindowsXP(v120_xp)”。
项目菜单->项目属性->配置属性->链接->系统->5.01
提示不是有效的应用程序,一般是缺少运行库。
提示无法定位程序输入点 xxx 于动态链接库XX上的,就要检查你源代码或者依赖的库里面有XP不存在函数,把函数移除,或重写。

cocos2d-3.X-xp

cocos2d-x背景无限滚动

最近项目做一个需要背景无限滚动,适用飞机,跑酷类型无限背景滚动等游戏,在网上找了一些例子,发现都犯严重的错误,就是滚动不和时间挂钩,会看到卡顿现象。每一帧+速度,正确来是s =v*dt,v速度,dt每一帧时间。

原理

现有一张图片,并排到一起是无缝衔接,假设你的分辨率是1280*720,用的图片长度是1552,如放一张图片,是足够长度的,至于为啥要是为了并排的图,能在移动时候,出现短暂黑的。

  1. 两个精灵分别A B 都是用同一张图片
  2. AB 同时移动 speed*dt,这里注意一定要乘时间
  3. 当B的位置移动到<0.0f时(表示后面的图片完全在屏幕上,A已移动到屏幕外面),把A放到B后面,这个时候就是BA。然后又到A移到<0.0f。

滚动代码

资源和图:http://pan.baidu.com/s/1mf2WY

BgScroll.h

#ifndef BGSCROLL_H
#define BGSCROLL_H
#include "cocos2d.h"
using namespace cocos2d;
class BgScroll :public Node
{
public:
	BgScroll();
	virtual ~BgScroll();
	CREATE_FUNC(BgScroll);
private:
	void update(float dt);
	Sprite* _sprite[2];
	float speed;
	float tex_length;
};

#endif

BgScroll.cpp

#include "BgScroll.h"
BgScroll::BgScroll():
speed(60.0f)
{
	auto tex = Director::getInstance()->getTextureCache()->addImage("taiko-bg.png");
	tex_length = tex->getPixelsWide();
	for (int i = 0; i < 2; ++i)
	{
		Sprite* node = Sprite::createWithTexture(tex);
		node->setAnchorPoint(Vec2(0, 0));
		this->addChild(node);
		node->setPosition(i*Vec2(tex_length, 0));
		_sprite[i] = node;
	}
	this->scheduleUpdate();
}
BgScroll::~BgScroll()
{

}

void BgScroll::update(float dt)
{
	for (int i = 0; i < 2; ++i)
	{
		auto node = _sprite[i];
		node->setPositionX(node->getPositionX() - speed*dt);
	}
	float x1 = _sprite[0]->getPositionX();
	float x2 = _sprite[1]->getPositionX();
	if (x2 < 0.0f)
	{
		_sprite[0]->setPositionX(x2 + tex_length);
		std::swap(_sprite[0], _sprite[1]);
	}
}

使用方法

 auto _bg_scroll = BgScroll::create();
    this->addChild(_bg_scroll);

总结

在游戏里面的任何动作,都需要*时间,因为每一帧的时间不是固定的,以前在某段时间会卡顿一下。

bgscroll

7zip开发

本文是描述7z sdk 下C语言的开发使用。

在7zip一个开源的解压缩自由软件,在LGPL协议下,即自由使用,只要你没修改7z里面的源代码,仅仅作为库的引用,勿需公开你的源码。可惜在网上找类似的开发7zip教程解压缩太少,如应用起来也需要折腾一段时间,本文应运而生。

特征

不介绍了官方挺细的。地址:http://sparanoid.com/lab/7z/中文介绍。

支持语言:(C、C++、C#、Java),因为C语言,so它是可以跨平台的,在安卓是可以使用的,比如你用来打包游戏资源,虽安卓apk包本来就是压缩包。

缺点,或者也解压的软件都有通用的特点,就是需要速度,解压的速度是消耗时间,当然有的解压压软件做的速度上杠杠,压缩率就会低。7zip做为相对高压缩率的,它的解压速度有点慢。

VS2013工程生成

  • SDK下载http://sparanoid.com/lab/7z/sdk.html
  • 路径lzma1505CUtil7z,右击7z.dsp用vs2013
  • 修改项目属性:
    • 通用->输出目录修改:$(SolutionDir)$(Configuration).win32
    • 通用->中间目录修改:$(Configuration).win32
    • 链接库->一般修改:$(OutDir)$(ProjectName).exe
  • 退出的时保存默认sln路径

源码说明

本节通过例子来阐述LZMA SDK的使用。项目属性->调试->命令参数

压缩包内容列表

“l” “lzma1505.7z”

解压

“x” “lzma1505.7z”

应用到游戏

思路,笔者没去实现也本想很cocos2d-x里面做个结合,据其他游戏引擎加载压缩包资源也是类似步骤。

  1. add压缩包到游戏资源
  2. 建立map容器:把压缩包文件内容映射进去
  3. 游戏加载的时候通过map查找是否存在这个文件,是加载,分之再从游戏指定的目录搜索文件
  4. 是否需要多线程加载?这点是个补充,多线程加载利于不卡住渲染主线程

Face++ 人脸识别

简介

本文简单说明Face++ android 人脸检测器的使用方法,在线和离线人脸识别算法,算法支持android ios。最好给出结合Cocos2d-x应用。

注意:SDK 中包含armeabi 以及armeabi-v7a 两种架构的编译版本,其中armeabi 架构由于缺少浮点运算指令,因此运行速度仅能达到armeabi-v7a 编译版本的一半水平,请根据需求选用。

相关文件

demo.zip:离线检测器使用示例工程
doc.zip:SDK 接口javadoc 描述
libs/faceapi.jar SDK 接口
libs/armeabi SDK :依赖库(armeabi 架构)
libs/armeabi-v7a SDK :依赖库(armeabi-v7a 架构)

使用流程

本节内容通过介绍demo 工程来讲解SDK 的使用方式。

  1. 建立一个java 工程。
  2. 在AndroidManifest.xml 中添加权限
  3. 根据需求选择离线SDK 中依赖库以及libs/faceapi.jar 拷入工程内的libs 文件夹内,例如若APP 的运行环境为armeabi 架构,如下图所示: libs-faceapi
  4. 接着,在程序中初始化一个com.faceplusplus.api.FaceDetector 类。注意,类初始化时需要使用到当前context 以及使用者对应的API_Key, 这个API_Key 必须与下载离线检测器的App 对应的API_Key 一致才可以正确调用这个库。下面是一个调用示例:
    1. 初始化 :libs-faceapi-init
    2. 检测,并获取检测结果: libs-faceapi-detecter
    3. 若图像由摄像头采集,则原始数据将以YUV 格式存储,可以先将图像旋转到正确的方向后使用灰度图的形式传入检测器 libs-faceapi-detecter-yuv
  5. 离线检测器与线上API 的协同功能:如果需要用到线上API 的更多功能,可以将本地的检测结果直接上传(从而节省传输的数据量,仅会上传脸部图像)。使用离线SDK 中HttpRequest 的新方法offlineDetect,可将离线结果直接同步至线上,并获取face_id 进行后续操作,如下图所示:  libs-faceapi-detecter-http

库及key

本节提供库:http://pan.baidu.com/s/1i9szc

及下面是Key

  • API Key:636c34abb317f0c62985cabd73ebc8c8
  • API Secret:TCLJv-6PZtqSzVbthX0r2-IElnpW3z1t
  • API Url:apicn.faceplusplus.com

在Cocos2d-x应用人脸识别

静态检测

  1. 利用摄像机拍照保存图像RGBA8888,路径存到安卓程序的目录下,获取目录函数:FileUtils::getInstance()->getWritablePath()
  2. 和JNI交互使用,参考cocosplatformandroidjava下面的Cocos2dxHelper.java,及jni下面的Java_org_cocos2dx_lib_Cocos2dxHelper

动态检测

需要把摄像机嵌入到cocos2d-x里,有空就写个教程出来。

AES加解密

这篇文章是对Cocos2d-x游戏资源加密解决方案的补充吧。说AES 数据的加密,解密过程。可以应用到cocos2d-x的数据加解密上面,比如玩家分数加密,写入到UserDefault写xml文件上面。

AES简单介绍

作为加密很有aes、des 、3des,三者对称加密中,AES256目前是3者中最安全的。比如:你现在的数据是”abcd”,这个时候你不想人家知道,最简单的办法就是^”密码”,界面再^”密码”。当然这个是很容易给解出来的。如果你想好一点加密数据就用AES,现在的网络有很多源代码,笔者找过的库有aes-des-3des,aes-src-18-02-14,Botan-1.10.8,OpenAES-0.9.0,openssl-1.0.1i,xyssl_0.9,cryptopp562,通过对比,最终选择了xyssl_0.9里面的AES库的解密速度快,在安卓下可以使用,最重要的是在cocos2d-x下的项目上做个实验,效率可以。AES有下面三个特点。

  1. 是对称加密算法,即密钥是相同。
  2. 密钥长度有128,192或256比特。密钥长的好。
  3. 消耗资源,毕竟要解密,是需要时间的。

AES加解密

加解步骤

  1. 初始化IV 和key,不同平台可能默认不同初始化,一定要自己memset。
  2. 设置aes_setkey_enc。
  3. cbc模式,当然你也可以用其他模式。

aes加解密代码示例

#include "aes.h"
void AesEncDec(char* in_buffer, char* out_buffer,bool b_enc)
{
    aes_context aes_ctx;
    unsigned char IV[16];
    unsigned char key[32];
    memset(key, 0, 32);
    memset(IV, 0, sizeof(IV));
    char password[32] = "123456";
    memcpy(key, password, strlen(password));

    int length = strlen(in_buffer);//注意strlen第一个字符串结束符'\0'为止,如果中间有'\0' ,后面的就失败,自己可固定长度,感谢味精指出
    int enc_buff_length = length + 16 - length % 16;
    if (b_enc)
    {
        aes_setkey_enc(&aes_ctx, key, 256);
        aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, enc_buff_length, IV, (unsigned char*)in_buffer, (unsigned char*)out_buffer);
    }
    else
    {
        aes_setkey_dec(&aes_ctx, key, 256);
        aes_crypt_cbc(&aes_ctx, AES_DECRYPT, length, IV, (unsigned char*)in_buffer, (unsigned char*)out_buffer);
    }
}
//AES测试代码
char buffer[32] = {"123456789123"};
//int length = strlen(buffer);
AesEncDec(buffer, buffer, true);
AesEncDec(buffer, buffer, false);

文件加解密

作为文件,他只是数据存储,你只关心他数据本身的加解密。无论是在游戏,或者其他应用。我关于cocos2d-x png图片的资源加密保护,用这方法。在游戏引擎里面你也只把文件读取出数据进行解密。

  1. 打开文件。
  2. 读取文件内容。
  3. 进行加密,或解密。
  4. 写入加密内容。

源码下载

http://pan.baidu.com/s/1qWqTtEk

Box2d在cocos2d-x应用

先介绍box2d基础,再和cocos2d-x结合应用,最后给利用PhysicsEditor工具导出的数据,水果从上面掉下来的例子。

Box2d基本概念

Box2D是一个用于游戏的2D刚体仿真库。程序员可以使用它在他们的游戏使物体在现实的方式,让游戏世界更生动。就是说它只是数据计算,比如两个物体的碰撞,它会告诉程序员,至于你两个物体是怎么的显示,那是渲染的事。

  • shape :2D 的几何对象,如:圆形或者对变形
  • rigid body:刚体,也就我们用到的物体,有动态和静态刚体。
  • fixture:夹具,它是绑定在body,它包含有,shape ,密度,摩擦系数,碰撞过滤。
  • constraint:约束,比如摆钟,你绕着那一点来摆。
  • contact constraint:一种特殊的约束,比你的不能穿透另外个刚体,和模拟摩擦及恢复形状。
  • joint:用来约束两个或者更多的body,支持多种节点类型:revolute, prismatic, distance等。
  • joint limit:
  • joint motor:
  • world:物理世界,是body,fixture,constraint集和到一起。box2d支持创建多个word,但何必。
  • solver:
  • continuous collision :

Box2d的简单使用

box2d简单的使用是需要经过下面四个步骤:

  1. 创建物理世界
  2. 在物理世界里面加入刚体
  3. 模拟步进计算
  4. 获取模拟后的坐标和弧度

box2d HelloWorld

 //创建物理世界
 b2Vec2 gravity(0.0f, -10.0f);
 b2World world(gravity);

//定义创建刚体
 b2BodyDef bodyDef;
 bodyDef.type = b2_dynamicBody;
 bodyDef.position.Set(0.0f, 4.0f);
 b2Body* body = world.CreateBody(&bodyDef);
 b2PolygonShape dynamicBox;
 dynamicBox.SetAsBox(1.0f, 1.0f);
//定义夹具 形状等,附加刚体上
 b2FixtureDef fixtureDef;
 fixtureDef.shape = &dynamicBox;
 fixtureDef.density = 1.0f;
 fixtureDef.friction = 0.3f;
 body->CreateFixture(&fixtureDef);

//模拟步进
 float32 timeStep = 1.0f / 60.0f;
 int32 velocityIterations = 6;
 int32 positionIterations = 2;
 world.Step(timeStep, velocityIterations, positionIterations);

//获取box2d模拟后的数据包括坐标和弧度
 b2Vec2 position = body->GetPosition();
 float32 angle = body->GetAngle();

box2d和 cocos2d-x应用

建议使用cocos2d-x 3.5以上。

文件说明:

  • GLES-Render:用显示box2d调试数据
  • GB2ShapeCache-x:解析PhysicsEditor导出的box2d数据,原来的版本是2.X的,已经修改过适应3.X的版本
  • HelloWorldScene:场景

PhysicsEditor使用:

官网有教程,就不在写了。记得导出的时候选择cocos plist格式,当然如果你导出其他的格式,就自己对应的解析。

注意事项:

  • box2d单位和像素是1:30,即是box2d一单位等于30像素。
  • box2d弧度和cocos2d-x弧度是要反的。
  • 注意设置他们锚点(setAnchorPoint);

总结

例子里面只是写刚体的创建,一直在增加,并没有销毁刚体,在一些游戏当中,比如你打中了,销毁掉自身,就需要调用world->DestroyBody(body),同样上面没有说到相互直接的碰撞过滤,等等,。。但是不在本文目的范围之内,呵呵。。。。。。

例子下载图及参考

下载地址:http://pan.baidu.com/s/1pJ1JhVH

box2d的英文手册: http://box2d.org/manual.pdf

Box2dCocos2d

Cocos2d-x :plist反解工具:SplitTool

缘由:

在网上拿到一些素材,是用TexturePackerGUI合成一张大图的,它的算法会把每张图的多余的空白部分删除掉再合拼。网上也有Anti_TexturePacker,这个工具,可惜作者不更新,因为它只会按图里面实际的大小截取出来,所以SplitTool诞生!

功能:

(1):还原合拼前的原始图片大小

(2):支持固定大小分割图片

使用说明:

cocos2d-x plist格式图片反解 :

1: 拖拽图片或者plist文件到窗口(png图片和plist同目录,不支持中文路径)

2: 按导出

导出的文件在Out文件夹下

图片按固定大小分割

图片按固定大小分割:

1 拖拽图片(不支持中文路径)

2:输入你要分的行数,列数,按分割

分割后的文件在Out文件夹下,

SplitTool主界面

下载地址:

http://pan.baidu.com/s/1eQeUOrK

总结:

工具只对没加密的图片,plist有效!

Cocos2d-x游戏资源加密解决方案

概述:

  1. 功能
  2. 演示效果
  3. 工具使用
  4. 应用到cocos2d-x项目
  5. 下载
  6. 总结
  7. 参考资料

功能:

功能:使用AES CBC 模式对文件及目录加解密,可以应用各个跨平台,目前已经在cocos2d-x win32平台和安卓平台通过测试:

关于AES CBC
优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.误差传送:一个明文单元损坏影响多个单元;
3.唯一的IV;

演示效果:

enc_thumb.jpg

工具使用:

运行于win7系统 ,输出文件及目录,是工具确定的,不可指定。工具会判断是否已经存在文件或目录,如果存在就会删除

  1. 输入需要加密文件,如:D:SDKpng.png  输出D:SDKpng-enc.png
  2. 输入需要解密文件,如:D:SDKpng.png 输出D:SDKpng-dec.png
  3. 输入需要加密目录,如:D:SDKpng 输出D:SDKpng-enc
  4. 输入需要解密目录,如:D:SDKpng 输出D:SDKpng-dec

应用到cocos2d-x项目

cocos2d-x 是通过getData来读取文件内容的,只是加密plist png jpg 等。
UserDefault这个是读取xml的要小心,本次的应用跳过这个,因为涉及到xml的文件的解析问题,
所以解密的时候判断是不是if (!forString)

  • Win32
    把aes.c aes.h拷贝进到该目录cocos2dcocosplatformwin32
    同时在工程增加两个文件
    CCFileUtilsWin32.cpp插入代码 密码是:123456 自己可以修改

#include “aes.h”

if (!forString)
{
     aes_context aes_ctx;
     unsigned char IV[16];
     unsigned char key[32];
     memset(IV, 0, sizeof(IV));
     memset(key, 0, sizeof(key));
     char password[32] = "123456";
     memcpy(key, password, strlen(password));
     aes_setkey_dec(&aes_ctx, key, 256);
     //CCLOG("buffer :%s", buffer);
     aes_crypt_cbc(&aes_ctx, AES_DECRYPT, size, IV, (unsigned char*)buffer, (unsigned char*)buffer);
     //CCLOG("buffer dec:%s", buffer);
}
  • android
    同样把aes.c aes.h 两文件拷贝进去到cocos2dcocosplatformandroid
    在CCFileUtilsAndroid.cpp插入代码 密码是:123456 自己可以修改

#include “aes.h”

if (!forString)
{
    aes_context aes_ctx;
    unsigned char IV[16];
    unsigned char key[32];
    memset(IV, 0, sizeof(IV));
     memset(key, 0, sizeof(key));
    char password[32] = "123456";
     memcpy(key, password, strlen(password));
    aes_setkey_dec(&aes_ctx, key, 256);
    //LOGD("data :%s", data);
    aes_crypt_cbc(&aes_ctx, AES_DECRYPT, size, IV, (unsigned char*)data, (unsigned char*)data);
    //LOGD("data dec:%s", data);
}

打开目录下 Android.mk 增加
aes.c

  • Mac||Ios
    参考上面的吧笔者没有Xcode

下载

aec.c aec.h 已包含在工具压缩包里面
下载地址:http://pan.baidu.com/s/1dDnb33r

总结:

这个aes算法是可以应用于任何数据加密的,,aes是16位块加密。所以工具加密后,文件大小是会增加一点,因为是得补齐16位,这不足16为的,补’/0’
已经单独放出AES数据加解密:http://www.freeyun.com/aes.html

参考资料:

aes cbc几种模式:http://www.cnblogs.com/happyhippy/archive/2006/12/23/601353.html
aes 开源项目代码,这次是用的源代码是从那抽出来的:https://www.openhub.net/p/xyssl
aes加解密http://www.freeyun.com/aes.html