Androidアプリ、インターフェースについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mi_l

Androidアプリ、インターフェースについて

#1

投稿記事 by mi_l » 13年前

いつもお世話になっています。

この質問は少し前の私の質問の続きとなっております

前の質問

この質問は「解決」という状態になっており、今回訊きたいのは、そこで教えてもらったことについてなので新しいトピックにしました。


前回からご教授していただいている方へ

最後に返信をせず、新たな質問にいってしまい、申し訳ありません。
最後にご指摘いただいた時は、すでに動作が確認され、動作の変更もできるようになり、自分なりにステージを作っていたら、少し期間があいてしましました。


*とりあえず今回やりたいことを書きます

今回の主題は上記「前の質問」にあるNo,37よりISLe様よりご指摘いただいた事柄についてです。

移動確認がとれ、1ステージを作ったこの状況まで来たので質問させていただきます。

ISLe様の指摘では、書いてある通り、

「既にBMoverで作ってあるところを書き換えないようにするためにはインターフェースの名前がBMoverでないといけません。
Eclipseなら一発で置き換えできますが、コードを書き換えずに拡張することに意味があります。」

とあります。

そして、自分なりにやってみました

BMover.javaファイルはもうあるので、インターフェースだけのBMover.javaファイルは作れません。

ですので、私はBMover.javaファイルのクラスの上にためしに記述してみましたが、「すでに型がある」と注意され、できませんでした。


そこで、私が今の段階でできた、自分なりのソースを載せますので、ご指摘お願いします。
(インターフェースの名前は「BMover」ではありませんがお願いします。)

BMoveConf.java
(前回からの追記箇所:6行目、15~19、29行目)

コード:

package net.dixq.irairabar;

public class BMoveConf extends BConf
{
	protected BMover mover ;
	protected BMoverA moverA;
	protected int f_cnt=0;//フレームカウンタ

	public BMoveConf(BMover mover)
	{
		super(Barricade.eType.OUT);
		this.mover = mover;
	}

	public BMoveConf(BMoverA moverA)
	{
		super(Barricade.eType.OUT);
		this.moverA = moverA;
	}

	//
	@Override
	public void doUpdate(Barricade barricade)
	{

		//BMoverのdoUpdateメソッド呼び出し
		//mover.doUpdate(barricade, f_cnt);
		mover.doUpdateA(barricade, f_cnt);
		moverA.doUpdate(barricade, f_cnt);


		f_cnt++;//カウントを加算
	}

}
BMover.java
(追記箇所:BMoveConfにもある通り、51~83行目の追加個所が実際に移動するものになっております)
(インターフェースもここにかいております)

コード:

package net.dixq.irairabar;

interface  BMovers
{
	public void doUpdate(Barricade barricade , int count);

}

public class BMover implements BMovers
{
	//60フレームで60px移動だから・・・・
		public int num_frames = 60;//フレーム数
		public int distance = 60;//移動距離



	public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
	{
		//メンバ変数に登録(格納)
		//num_frames = frame;
		//distance = dis;
	}

	//Barricadeの座標を更新する(ver1)(なしと考える
	public void doUpdate(Barricade barricade, int count)
	{
		float dx = 0.0f;//x座標
        float dy = 0.0f;//y座標
        //count = 0;

        // distanceピクセルの距離を・・・・、
        // num_framesフレーム掛けて下り
        // num_framesフレーム掛けて上がる
        count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる

      //  if (count < num_frames)
        {
            // 行き
            dy = (float)distance / num_frames;
        }// else
        {
            // 帰り
            dy = -(float)distance / num_frames;
        }

        barricade.move(dx, dy);


	}

	//Barricadeの座標を更新する(ver2)追加した分
		public void doUpdateA(Barricade barricade, int count)
		{
			float dx = 0.0f;//x座標
	        float dy = 0.0f;//y座標
	        //count = 0;

	        // distanceピクセルの距離を・・・・、
	        // num_framesフレーム掛けて下り
	        // num_framesフレーム掛けて上がる
	        count %= num_frames * 3; // 往復だとnum_framesの倍の時間かかる

	        if (count < num_frames)
	        {
	            // 行き
	            dy = (float)distance / num_frames;
	        }
	        else if(count >= num_frames && count < (num_frames*2))
	        {
	        	//停止
	        	dy = (float)distance / num_frames * 0;

	        }
	        else
	        {
	        	// 帰り
	            dy = -(float)distance / num_frames;
	        }

	        barricade.move(dx, dy);


		}

}
BMoverA.java
(追加した分です(新たな動きです))

コード:

package net.dixq.irairabar;

public class BMoverA implements BMovers
{
	//60フレームで60px移動だから・・・・
		public int num_frames = 60;//フレーム数
		public int distance = 60;//移動距離



	public BMoverA(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
	{
		//メンバ変数に登録(格納)
		//num_frames = frame;
		//distance = dis;
	}

	//Barricadeの座標を更新する(ver1)
	public void doUpdate(Barricade barricade, int count)
	{
		float dx = 0.0f;//x座標
        float dy = 0.0f;//y座標
        //count = 0;

        // distanceピクセルの距離を・・・・、
        // num_framesフレーム掛けて下り
        // num_framesフレーム掛けて上がる
        count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる

      //  if (count < num_frames)
        {
            // 行き
            dy = (float)distance / num_frames;
        }// else
        {
            // 帰り
            dy = -(float)distance / num_frames;
        }

        barricade.move(dx, dy);


	}

}
BarricadeSquare.java
(一応、移動する四角障害物クラス)

コード:

package net.dixq.irairabar;

import android.graphics.Bitmap;


public class BarricadeSquare extends Barricade {

    public BarricadeSquare( float x, float y, float w, float h, BConf conf, Bitmap img ){
        super(4,conf, img);
        _pt[0].x  = x;      _pt[0].y = y;
        _pt[1].x  = x+w;    _pt[1].y = y;
        _pt[2].x  = x+w;    _pt[2].y = y+h;
        _pt[3].x  = x;      _pt[3].y = y+h;
        _center.x = x+w/2;
        _center.y = y+h/2;


    }
    public BarricadeSquare( float x, float y, float w, float h, BConf conf)
    {
        this(x, y ,w, h, conf, null);

    }

}
GameMgr.java
(34、49行目追記)

コード:

package net.dixq.irairabar;

import java.util.ArrayList;
import java.util.LinkedList;

import net.dixq.irairabar.Barricade.eType;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;


public class GameMgr {

    private enum eStatus{
        NORMAL,
        GAMEOVER,
        GAMECLEAR
    };

    private static final float PI = (float) Math.PI;
    private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
    private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
    private eStatus _status = eStatus.NORMAL;
    private Player _player;

    private BMover bm  = new BMover();
    private BMoverA bma = new BMoverA();

    private int Dflag = 0;//描画フラグ
    private float x , y;

    GameMgr(Context con)
    {

        Resources res = con.getResources();
        Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);

       // _barrList.add(new BarricadeSquare(  20,  30, 700,800, null));

        _barrList.add(new BarricadeSquare(  70 , 60, 100, 100, new BMoveConf(bm) , bits));// 画面4隅に四角形を配置

        _barrList.add(new BarricadeSquare( 150, 100, 100, 100, new BMoveConf(bma), bits));
/*
        _barrList.add(new BarricadeTriangle(  0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
        _barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形

        _barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
        _barrList.add(new BarricadeStar(240, 240, 20,  80, new BConf(+PI / 360)));// 中央に回転する星

        _barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
        _barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
        _barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//

        _barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線

        _barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー

        _barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
        _barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
        _barrList.add(new BarricadeSquare(185, 600,  55, 20, new BConf(+PI / 360)));// 左下回転するバー

*/
    //  _barrList.add(new BarricadeSquare(20, 680,  80, 20, null));// ゴールに接触したバー

    //  _barrList.add(new BarricadeSquare(20, 700,  80, 80, new BConf(eType.GOAL)));// ゴール

        for (Barricade bar : _barrList) {
            _taskList.add(bar); //タスクリストに障害物を追加
        }

        _player = new Player();
        _taskList.add(_player);
        _taskList.add(new FpsController());
    }

    private boolean Collision(){
        Vec vec = new Vec();
        final Circle cir = _player.getPt();
        for(Barricade barr : _barrList){
            Def.eHitCode code = barr.isHit(cir, vec);
            switch(code){
            case OUT:
                _status = eStatus.GAMEOVER;
                return true;
            case GOAL:
                _status = eStatus.GAMECLEAR;
                return true;
            }
        }
        return false;
    }

    public boolean onUpdate()
    {

        if( _status != eStatus.NORMAL ){
            return true;
        }
        if( Collision() ){
            return true;
        }
        for (int i = 0; i < _taskList.size(); i++) {
            if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
                _taskList.remove(i); // そのタスクを消す
                i--;
            }
        }
        return true;
    }

    private void drawStatus(Canvas c){
        switch( _status ){
        case GAMEOVER:
            {
                Paint paint = new Paint();
                paint.setTextSize(80);
                paint.setColor(Color.BLACK);
                c.drawText("GameOver", 40, 100, paint);
            }
            break;
        case GAMECLEAR:
            {
                Paint paint = new Paint();
                paint.setTextSize(80);
                paint.setColor(Color.BLACK);
                c.drawText("GameClear", 40, 100, paint);
            }
            break;
        }
    }


@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}

}

ここまでの記述でエラーはありません、

BMoverでは降下→停止→上昇
BMoverAでは降下→上昇

の移動を書きました

そしてGameMgrでコメントされてない二つの障害物に設定したところ、

実機で「予期せず停止しました」となりました・・・

予想では、二つの障害物が現れ、一つはBMoverの動き、もう一つはBMoverAの動きをするのだとおもっておりましたが・・・

どこかおかしい箇所のご指摘、またご教授お願いします。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: Androidアプリ、インターフェースについて

#2

投稿記事 by ISLe » 13年前

Java言語の入門書などでインターフェースや継承についてしっかり勉強することをお勧めします。
このまま話を進めても、インターフェースや継承の概念やら使い方やら基礎から説明しなければいけません。
というか前スレでさんざん説明したことも理解されていませんよね。

文法の解説だけでなくサンプルも豊富なものを選ぶと良いでしょう。
具体的なコードを提示せずともわたしが言わんとしていることを理解できるようになってください。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: Androidアプリ、インターフェースについて

#3

投稿記事 by ISLe » 13年前

ある意味丸投げ回答ですが、Eclipseでの作業手順です。
ソースコードが正しく構成されていないとどういう結果になるか予測できません。
前スレ終了段階のソースコードで実行するのが安全です。

手順.1 BMoverクラスをBMoverAクラスに変更します。
BMoverクラスに対して、メニューの『リファクタリング』→『名前変更...』を選択しダイアログを開きます。
『新しい名前』をBMoverAにして、『次へ』ボタンを押します。
『実行される変更』からコンパイル単位名(ソースファイル名)の変更のチェックだけを残し、それ以外のチェックを外し、『完了』ボタンを押します。

手順.2 BMoverインターフェースを作成します。
手順.1で作成したBMoverAクラスに対して、メニューの『リファクタリング』→『インターフェースの抽出...』を選択しダイアログを開きます。
『インターフェース名』をBMover、『インターフェース内で宣言されるメンバー』のdoUpdateメソッドにチェックを入れ、『OK』ボタンを押します。

GameMgrクラスでBMoverのインスタンスを作成していたら(エラーになるので)BMoverAに変更します。

mi_l

Re: Androidアプリ、インターフェースについて

#4

投稿記事 by mi_l » 13年前

BMoverクラスの名前を変えたらできました・・・

お手数かけました

mi_l

Re: Androidアプリ、インターフェースについて

#5

投稿記事 by mi_l » 13年前

自分のトピックのページを開きっぱなしにしてたので返信に気づきませんでした・・・

eclipseのことも調べたら出てきました。

丁寧にありがとうございます。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: Androidアプリ、インターフェースについて

#6

投稿記事 by ISLe » 13年前

mi_l さんが書きました:BMoverクラスの名前を変えたらできました・・・
doUpdateAメソッドなんて追加して呼び出したらインターフェースを作る意味がないのですけども。

前スレで、引数のBConfにいままでどおり渡せるようにBConfを継承してBMoveConfを作ったこととか、BConfに空のdoUpdateメソッドを追加してBMoveConfでオーバーライドしたこととか、何も覚えていないし理解していないのでしょうか。
移動パターンを増やすにはBMoverを継承するという説明もしました。

BConfをBMoverに変えて前スレと同じことを繰り返しているのですが、気付いていますか?

前の前のスレから既存のコードは変更なしで従来どおり動くという方針で進めてきたのを毎度台無しにするのを見ると切ないです。

(追記)
質問文に「コードを書き換えずに拡張することに意味があります」が引用されているのにどうしてだろう。

閉鎖

“C言語何でも質問掲示板” へ戻る