アンドロイドでゲームアプリなどを作成する際はゲーム画面のサイズは基本的にその端末の画面サイズに依存する。

その画面サイズの違いがゲームに影響を与えるゲームと与えないゲームが有る。
前者はアクションゲームやシューティングゲームなどで画面が大きければ見える範囲が端末ごとに違ってくる。画面が大きいとより見える情報が大きくなるのはユーザーごとに情報量の違いが生じてしまう。

後者はUIなどを押すのみだけのような、アクション要素がないものなどである。

今回は描画をする際に端末間ごとの描画を同じにする手法について考える
描画については2Dの場合だけを考える(x,y座標のみ 3Dは行列とか使ってやるんだよね...)
  
まず、考える上で必要となる用語について整理する。
 この用語が正規の用語であるかどうかは考慮していません

  • 物理座標:実際の端末に表示されるときの座標。端末ごとにサイズが違ってくる(1920*1080,720*1074とか)
  • 論理座標:プログラム内で仮定される仮想的な座標。プレイヤーや敵の大きさを規定するときにもこれを元に考えていると思う.(600*800とか)
  • 正規座標:グラフィックAPI(Open GLやDirect X)などで使用される座標、Open GL では(-1~1)でDirect Xでは (0~1)で表現される。*グラフィックAPIは描画について特化した機能のまとまり。スマートフォンでは Open GL の軽量版の Open GL ES というのが使用されている

もし論理座標がなければ、敵の大きさも背景の大きさも規定できません。なぜなら、表示する画面ごとにサイズは変わってしまうからです(比率でやろうと思えば出来ないことも無いと思いますが・・・)

これを端末が違っても同じ物を描画するためには
論理座標と物理座標との比率を論理座標にかけて正規座標にすればいいじゃないでしょうか
例:
画面上に表示されるx座標  = 物理座標の幅(ex:700)/論理座標の幅(ex:600) *論理座標のx座標

コレについてJavaでのテストが以下のコードです
 
public class DisplayComplementTest {
    public static void main(String[] args) {
        //物理サイズ
        int real_width =700;
        int real_height =1074;
        //論理サイズ
        int log_width =600;
        int log_height =800;

        //論理座標における座標
        int x =199;
        int y =300;
        //論理座標を正規化
        float nor_x =((float)(x*2 -log_width))/log_width;
        System.out.println(nor_x);
        //論理座標を物理座標に変換
        float com_x =x*((float)real_width/log_width);
        //物理座標での座標の正規化
        float nor_com_x =((com_x*2 -real_width))/real_width;
        System.out.println(nor_com_x);

    }
}
l
出力結果 
 
 
-0.33666667
-0.3366667
l論理座標と物理座標に変換された論理座標のそれぞれの正規座標が同じ値を取ることが変換によって実現しました。

これを描画する座標に変換をかければ端末間のサイズを保管できるのではないでしょうか 

ちょっと前にゲームを作ろうとしていたときにある端末だけで作成していてそのときに論理座標を定義せずに端末の画面サイズで作成していて他の端末でやったときに挙動が全然違って苦労した過去よりこの記事は作成されました。