ホームへ戻る

s2.7 障害物を作る.1


 本アプリでは、色んな形の障害物を作る予定です。



三角や四角や星・・それらは「障害物」という共通の要素を持っていますから、「障害物」という抽象クラスから派生させることを考えます。



動きやあたり判定は全て抽象クラスが行い、それぞれの形に依存した座標のセットだけ、継承先で行えばよい造りにしてみます。
まずは障害物であるBarricadeクラスです。

↓Barricade.java
(新規追加
)
public class Barricade extends Task {

        public enum eType { // 障害物のタイプ
                OUT, // あたるとアウトなタイプ
                GOAL // あたるとゴールなタイプ
        }

        protected PointF _center = new PointF(0, 0); // 図形の中心点
        protected PointF _pt[]; // 図形の頂点
        protected Paint _paint = new Paint(); // ペイント
        protected eType _type; // タイプ(当たるとアウトな壁、ゴールの壁、等)
        protected float _rotaSpeed = 0; // 回転スピード

        // コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
        public Barricade(int n, BConf conf) {
                if (conf != null) {
                        _rotaSpeed = conf.speed; // 回転スピード
                        _type = conf.type; // 物体のタイプ
                }
                switch (_type) {
                case OUT: // 接触してアウトな物
                        _paint.setColor(Color.RED); // 赤に
                        break;
                case GOAL: // 接触してゴールな物
                        _paint.setColor(Color.GREEN); // 緑に
                        break;
                }
                _pt = new PointF[n]; // 頂点配列を作る
                for (int i = 0; i < n; i++) {
                        _pt[i] = new PointF(); // 頂点を作る
                }
        }

        // 更新する
        public boolean onUpdate() {
                return true;
        }

        // 接触しているかを問う。円cirが接触していれば接触した線分をvecに格納し、物体のタイプを返す。接触していなければNOを返す
        public Def.eHitCode isHit(final Circle cir, Vec vec) {
                /* ここで接触判定  */
                return Def.eHitCode.NO;
        }

        // 描画する
        public void onDraw(Canvas c) {
                if (_pt.length < 1) { // 頂点が1未満なんて図形はありえない
                        return;
                }
                Path path = new Path();
                path.moveTo(_pt[0].x, _pt[0].y); // パスの初期位置をセット
                for (int i = 0; i < _pt.length; i++) {
                        path.lineTo(_pt[i].x, _pt[i].y); // 頂点の位置へラインを引いていく
                }
                c.drawPath(path, _paint); // 引いたラインを描画する
        }
}


障害物には「当たるとアウトなタイプ」「当たるとゴールなタイプ」の2種類存在します。
その識別を変数 _type に持たせます。
ポイントは _pt[] です。
コンストラクタで、何角形であるかという数値が渡されてきます。
渡されてきた頂点の数だけ頂点を用意します。
そうすれば後は線分が全て分かりますし、配列要素分計算をループすればいいので、何角形にでも対応可能です。

また、図形は回転するとか、移動するとか、色んな設定したい情報を持つことがあるでしょう。
そのような設定情報はコンストラクタの引数である BConf に設定します。
BConfについては↓で後述。

isHitメソッドでは、引数で指定したcirが示す円との当たり判定を計算します。
自分(障害物)のどこか一辺でも接触していれば、接触した辺のベクトルを引数に格納して、当たった物体のタイプを返します。
呼び出し元では、これがアウトな物体であればゲームオーバーに、ゴールな物体であれば、ゲームクリアにすればよいわけです。
この返り値は別途定義しています。

↓Def.java (新規追加)

public class Def {
        public enum eHitCode{
                NO,
                OUT,
                GOAL,
        }
}


描画はonDrawで行っています。
Pathを使えば、書いた軌跡を図形にして描画してくれます。
moveToでパスの初期位置をセットし、lineToで軌跡を書きます。
頂点を一つずつ順に渡して行けば良いです。
後はCanvas#drawPathで描画出来ます。

↓BConf.java
(新規追加
)
public class BConf {
        public float speed = (float)Math.PI/180;
        public Barricade.eType type = Barricade.eType.OUT;
        
        public BConf(Barricade.eType atype){
                type = atype;
        }

        public BConf(float aspeed){
                speed = aspeed;
        }
}


設定出来る項目は現在最小限にしています。
「物体の種類」「回転スピード」の二種類です。
このコンフィグ情報を作らずにコンストラクタに渡すとデフォルトの情報が設定されます。

後は、アクティビティで、全画面設定をしておきます。

↓IrairabarActivity.java
(一部変更 
赤字部)
public class IrairaBarActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//フルスクリーンに設定
                requestWindowFeature(Window.FEATURE_NO_TITLE);

                setContentView(new GameSurfaceView(this));
                AcSensor.Inst().onCreate(this); // センサー初期化
        }

        @Override
        protected void onResume() { // アクティビティが動き始める時呼ばれる
                super.onResume();
                AcSensor.Inst().onResume();// 開始時にセンサーを動かし始める
        }

        @Override
        protected void onPause() { // アクティビティの動きが止まる時呼ばれる
                super.onPause();
                AcSensor.Inst().onPause();// 中断時にセンサーを止める
        }
}


実行結果


特に見た目変わりません。
画面が全画面になった位ですね。
具体的な物体は次の章以降で作ります。

この章のプロジェクトをダウンロード

→分からないことがあれば掲示板で質問して下さい


Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.

- Remical Soft -