androidandengine 是一款開源的2d遊戲引擎,功能還是強大的,但是用它寫遊戲還是有諸多不足之處。其中一個就是如題 資源的加密問題。對於一個公司或者個人來說,資源的保護非常的總要的。看來微雲有,u3d有。爲什麼我的andengine 就沒有。經過一段時間對andengine的架構解剖。嘿嘿。屌絲版加密就出來了。。下面我具體道來。
我用的是master 版的andengine Z這個是前提。
1)在Engine.java 中添加如下代碼
- //是否解碼
- private boolean isDecodeResource = false;
- public boolean isDecodeResource() {
- return isDecodeResource;
- }
- public void setDecodeResource(boolean isDecodeResource) {
- this.isDecodeResource = isDecodeResource;
- }
2)在IGameInterface.java 中添加一個解碼的方法.你 遊戲的activity 必須實現它。
- public interface IGameInterface {
- // ===========================================================
- // Final Fields
- // ===========================================================
- // ===========================================================
- // Methods
- // ===========================================================
- public Engine onLoadEngine();
- public void onLoadResources();
- public void onUnloadResources();
- public Scene onLoadScene();
- public void onLoadComplete();
- public void onPauseGame();
- public void onResumeGame();
- //解碼方法
- public InputStream decodeResource(InputStream in);
- }
3)改寫AssetBitmapTextureAtlasSource.java 中的構造方法public AssetBitmapTextureAtlasSource(final Context pContext, final String pAssetPath, final int pTexturePositionX, final int pTexturePositionY) 和 public Bitmap onLoadBitmap(final Config pBitmapConfig) 這兩方法
- public AssetBitmapTextureAtlasSource(final Context pContext, final String pAssetPath, final int pTexturePositionX, final int pTexturePositionY) {
- super(pTexturePositionX, pTexturePositionY);
- this.mContext = pContext;
- this.mAssetPath = pAssetPath;
- final BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
- decodeOptions.inJustDecodeBounds = true;
- InputStream in = null;
- try {
- in = pContext.getAssets().open(pAssetPath);
- final BaseGameActivity context = (BaseGameActivity)this.mContext;
- if(context.getEngine().isDecodeResource()){
- in = context.decodeResource(in);
- }
- BitmapFactory.decodeStream(in, null, decodeOptions);
- } catch (final IOException e) {
- Debug.e("Failed loading Bitmap in AssetBitmapTextureAtlasSource. AssetPath: " + pAssetPath, e);
- } finally {
- StreamUtils.close(in);
- }
- this.mWidth = decodeOptions.outWidth;
- this.mHeight = decodeOptions.outHeight;
- }
- @Override
- public Bitmap onLoadBitmap(final Config pBitmapConfig) {
- InputStream in = null;
- try {
- final BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
- decodeOptions.inPreferredConfig = pBitmapConfig;
- in = this.mContext.getAssets().open(this.mAssetPath);
- final BaseGameActivity context = (BaseGameActivity)this.mContext;
- if(context.getEngine().isDecodeResource()){
- in = context.decodeResource(in);
- }
- return BitmapFactory.decodeStream(in, null, decodeOptions);
- } catch (final IOException e) {
- Debug.e("Failed loading Bitmap in " + this.getClass().getSimpleName() + ". AssetPath: " + this.mAssetPath, e);
- return null;
- } finally {
- StreamUtils.close(in);
- }
- }
爲什麼在這個類中加入呢。
1.構造方法中要知道圖片的寬和高。
2.onLoadBitmap 被BitmapTextureAtlas 中的writeTextureToHardware(final GL10 pGL) 方法調用加入到底層opengl es 中去。所以在被生產爲Bitmap 之前。我們把他/它給解碼咯。。以便引擎調用。
4)生成新的jar 包
如果你保存你的android master 版的項目。在bin文件夾裏會生成一個jar包。如果不放心是否是新的包,可以刪除bin文件夾下的jar包。反正它會自動生成一個新的jar ^ ^ !
5)編碼自己的資源文件
自己寫個Java app 程序就搞定
- public static void encrImg(File src, File dest) throws Exception {
- ImageInputStream fis = new FileImageInputStream(src);
- ImageOutputStream fos = new FileImageOutputStream(dest);
- int read;
- while ((read = fis.read()) > -1) {
- fos.write(read ^ XOR_CONST);
- }
- fos.flush();
- fos.close();
- fis.close();
- }
- public static final int XOR_CONST = 0X99; //密鑰
- public static void main(String[] args) {
- // encrImg("E:\\項目\\TowerDefense\\圖片\\人物\\3d圖\\peasant1.png", "E:\\項目\\TowerDefense\\圖片\\人物\\3d圖\\peasant1c.png");
- // encrImg("E:\\項目\\TowerDefense\\圖片\\人物\\3d圖\\peasant1c.png", "E:\\項目\\TowerDefense\\圖片\\人物\\3d圖\\peasant12.png");
- }
可參考這篇文章 :Android簡單加密保護自有圖片資源
6)遊戲中解碼
- @Override
- public InputStream decodeResource(InputStream in){
- List<Byte> list = new ArrayList<Byte>();
- int read;
- byte[] arr = null;
- try {
- while ((read = in.read()) > -1) {
- read = read ^ XOR_CONST;
- list.add((byte) read);
- }
- arr = new byte[list.size()];
- int i = 0;
- for (Byte item : list) {
- arr[i++] = item;
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- InputStream iis = new ByteArrayInputStream(arr);
- return iis;
- }
主 activity 中重寫 decodeResource(InputStream in) 和 onLoadEngine() 中設置可以編碼
- @Override
- public Engine onLoadEngine() {
- instance = this;
- Engine engine = AndEnviroment.createEngine(ScreenOrientation.LANDSCAPE,
- true, true);
- // Attempt to set up multitouch support
- try {
- if (MultiTouch.isSupported(this)) {
- engine.setTouchController(new MultiTouchController());
- }
- } catch (final MultiTouchException e) {
- }
- engine.setDecodeResource(true);
- return engine;
- }
engine.setDecodeResource(true);
這句,一定要加上,不然會報找不到bitmap的錯誤
onLoadResources()方法中還是那樣 直接用就可以了 是不是非常有用呢!
- BitmapTextureAtlas tex = new BitmapTextureAtlas(pTextureWidth,
- pTextureHeight, TextureOptions.NEAREST_PREMULTIPLYALPHA);
- TextureRegion texReg = BitmapTextureAtlasTextureRegionFactory
- .createFromAsset(tex, AndEnviroment.getInstance().getContext(),
- pName, 0, 0);
- AndEnviroment.getInstance().getEngine().getTextureManager()
- .loadTexture(tex);
以上的解碼方式適合放在assets 文件下的圖片資源。
要修改其他加載方式的請看下圖 大同小異啦。。
1.res 目錄下的
類ResourceBitmaXXXXXXXSource.java FileBitmapXXXXXSource.java 中的 onLoadBitmap 方法改寫
2.texturepacker 擴展
TexturePackParser.java 中 parsetexture 方法中onGetInputStream() 方法改寫