pngのパレット変換等、実行ファイルの容量削減について色々と述べてきました。


 それもこれも携帯機器での実行という環境のせいなのですが…そこを言っては元も子もありませんし、例えどのような環境で実行するにしても、ファイル容量を削減するに越したことはありません。





 さて、今日は一枚の画像ファイルを複数に分割することを考えましょう。


public Image[] makeImagechip(Image img,int col,int row) {


/* img :分割前の画像


* col :横に分割する個数


* row:縦に分割する個数


*/


 int width = img.getWidth()/col;


 int height = img.getHeight()/row;

Image[] result = new Image[col*row];


 for(int i=0;i<col;i++){


   for(int j=0;j<row;j++){

     result[i*row+j] = Image.createImage(img, i*width, j*height, width, height, Sprite.TRANS_NONE);


   }

}

return result;

}





 目新しいものと言えばSprite.TRANS_NONEでしょう。


 これは前にも述べたSpriteクラスで定義されている定数で、画像コピー時の変形方法と捉えてかまいません。


この他には左右反転するTRANS_MIRROR や 180度回転するTRANS_ROT180、これらを組み合わせたTRANS_MIRROR_ROT180等があり、わざわざ自分で定義しなくても高度な機能を提供してくれます。





これで、共通のパレットを持った複数の画像を一枚のpngに収めることが可能です。


画像は容量削減の最大の敵ですからね…こちらも最大限工夫して挑みましょう!


まずは、お詫びから…


以前自分で作った簡易スプライトとしてSpriteクラスを紹介しましたが、


import javax.microedition.lcdui.game.Sprite;


なるれっきとしたSpriteクラスが提供されていました。


という訳で、こちらを使った方が確実に便利だと思われます。


といいますかこのSpriteクラス、色々多機能なようで、Javaも奥が深いなぁ…と思わせられますね。


長い間J2MEに触れてきましたが、未知の便利なクラスが提供されてたりと、情報収集の手は休まる暇もありませんね^^;





もう一つ、pngの話題です。


pngを以前紹介したようにbyte[]として読み込み、パレット部のデータを書き換えることで、プログラム上から色違い画像を作成することに成功しました。


どうも、CRCはいじらなくても大丈夫なようです。





自分のコードをそのまま載せるだけで恐縮なのですが、


byte[] b = qf.readFileAsBytes("bat.png");

b[53] = 0;

b[54] = 0;

b[55] = 0;

enemy_lib[1].img = Image.createImage(b, 0, b.length);





として、パレットの一部を(0,0,0)(黒にあたりますね)に変更することが出来ました。


これで実行ファイルのサイズ削減に大きな貢献ができますね!


早速ですが、ボタン入力の実装例です。








MyButtenHash keys = new MyButtenHash();



//Stringのkeyとbooleanのvalueを用いるハッシュ



keys.put("KEY_UP",false);










public void keyPressed(int keyCode) {


  int key = getGameAction(keyCode);


  if(key == Canvas.UP)


    keys.set("KEY_UP",true);


  else if(key == Canvas.LEFT)


    keys.set("KEY_LEFT",true);


  …


}









public void keyReleased(int keyCode) {


  int key = getGameAction(keyCode);


  if(key == Canvas.UP)


    keys.set("KEY_UP",false);


  else if(key == Canvas.LEFT)


    keys.set("KEY_LEFT",false);


  …


}








public boolean keyPressing(String key) {



  if(keys.get(key)){


    return !keysuspend;



  }


   return false;


}









メインループで特定のキーが押されているかを調べたい時は、keyPressing(String key)を呼び出して判断します。



実際に扱う場合には、ハッシュの代わりにfinal int KEY_UP = 1;等として、配列を用いた方が処理が軽い&メモリ効率がいい気がします。今回は分かりやすいようにハッシュで書きました。



keysuspendは、キー入力を差し止めるかどうかのフラグです。キー入力は差し止めたいが押し続けているかどうかは判断したい、などという稀有な事態の時を除いてこれで一括管理できると思います。



なお、コマンドのボタン(commandAction)のときも、同一のハッシュや配列にキー情報を保存することで、区別なく扱うことが出来る点を覚えておいて下さい。








//ちなみに、今製作中の携帯ゲームです→http://twitpic.com/12jo03