質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.36%

drawRectした短形をonTouchで滑らかに移動させたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,831

ブロック崩しを作っています。

クラス
Main
Ball
Bar
Block

Ballの移動スピード 
vx =15
vy=15

Barクラスののインスタンスを利用してdrawrect()して短形を作成
onTouchでdrawrectされた短形を移動させたい。

タッチしたx座標にdrawrectされたバーが遷移するようにしたい。
(Ballの移動スピードと同じにしたい)


bar.x //drawrectしたバーのx座標
touchX// (onTouchを利用)タップされた際のx座標

現時点で bar.x = touchX しているため
drawrectされたバーが、瞬間移動している。

※バーが消えないようにしたい。
https://www.youtube.com/watch?v=bMGebET8hHs
参考
http://2byteresearch.blogspot.jp/2011/04/android_16.html

瞬間移動しているので、上の動画のように瞬間移動しないで移動するようにしたい

Main.java ontouch

@Override
        public boolean onTouchEvent(MotionEvent event) {

            int x =(int)event.getRawX();//タッチした座標
            int y=(int)event.getRawY();
            touchAction=event.getAction();

            switch (touchAction) {
                case MotionEvent.ACTION_DOWN:
                    int screenX = x;
                    int screenY = y;

                    break;
                case MotionEvent.ACTION_MOVE:
                   int diffX = bar.x - screenX;//差分
                   int diffY = bar.y - screenY;
                   diffX/2;
                   diffY/2;


                    break;
                case MotionEvent.ACTION_UP:
                    break;

            }

            return super.onTouchEvent(event);
        }


Ball.java

public Ball(int _x, int _y, int width, int height) {
        //初期座標をセット
        x = (float) _x;
        y = (float) _y;
        //ビューの幅と高さをセット
        view_w = width;
        view_h = height;
        vx = 15;//ボールの移動速度
        vy = 15;
    }


Main.javaほぼ全文

package com.example.blockbreak;

import android.content.Context;


public class MainActivity extends AppCompatActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //カスタムビュークラスのインスタンスをコンテントにセット
        setContentView(new CustomView(this));

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

    }

    class CustomView extends SurfaceView implements SurfaceHolder.Callback, Runnable {



        Block[] block,block2,block3,block4,block5,block6,block7,block8,block9,block10;
        Bar  bar;              //バー
        int view_w, view_h;    // SurfaceViewの幅と高さ
        Ball ball;
        int num; //カウンターiの最大値変数 画面サイズによって表示個数を変えるため

        //Blockの情報
        int blockWidth = 40;//ブロックの半分の横の長さ
        int blockHeight = 10;//ブロックの半分の高さ
        int margin =5;

        float touchX,touchY;
        int touchAction;//x座標、y座標,アクション種別の取得



        //コンストラクタ
        public CustomView(Context context) {
            super(context);
            // SurfaceView描画に用いるコールバックを登録する。
            getHolder().addCallback(this);
            // 描画用の準備


//            ViewGroup root = (ViewGroup)getWindow().getDecorView().findViewById(android.R.id.content);
//            view_h = root.getHeight();
//            view_w = root.getWidth();
//            Log.d("width", "view_w:" +view_w);
//            Log.d("height", "view_h:" +view_h);

            WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
            // ディスプレイのインスタンス生成
            Display disp = wm.getDefaultDisplay();
            Point size = new Point();
            disp.getSize(size);
            view_w =size.x;
            view_h =size.y;

            //ボールを生成
            ball = new Ball(view_w/2, view_h/3 , view_w, view_h );

            // バーを生成  view_w/2画面の半分
            bar  = new Bar( view_w/2 , view_h - 150 );


        }



        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height) {

        }


        // SurfaceView生成時に呼び出されるメソッド。
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // 背景
            Canvas canvas = holder.lockCanvas();
            canvas.drawColor(Color.BLACK);
            holder.unlockCanvasAndPost(canvas);
            // スレッド開始
            mainLoop = new Thread(this);
            mainLoop.start();

        }


        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
//            Canvas canvas = getHolder().lockCanvas();

            touchX =event.getRawX();
            touchY=event.getRawY();
            touchAction=event.getAction();
//            float diffX = bar.x - touchX;

            switch (touchAction) {
                case MotionEvent.ACTION_DOWN:
                    bar.x = touchX;
                    bar.y = touchY;

                    break;
                case MotionEvent.ACTION_MOVE:

                    bar.x = touchX;
                    bar.y = touchY;
//                  canvas.drawRect(touchX-bar.halfBar,bar.y +10, touchX + bar.halfBar, bar.y +10,paint3);

                    break;
                case MotionEvent.ACTION_UP:
                    break;

            }
//            if(flag) {
//                bar.x =touchX -bar.halfBar;
//            }

            return super.onTouchEvent(event);
        }


        @Override
        public void run(){

            while (true) {
                Canvas canvas = getHolder().lockCanvas();
                if (canvas != null)
                {
                    //背景
                    canvas.drawColor(Color.BLACK);

                    //max720 1280 画面サイズ
                    num =(view_w - 32 + margin)/(blockWidth*2);//横ブロックの個数. 

//---中略----


                    //バーを描画する   left top right bottom
                    canvas.drawRect(bar.x - bar.halfBar , bar.y +bar.height , bar.x + bar.halfBar , bar.y - bar.height , paint3);
                    //Ballクラスからボールを描画
                    canvas.drawCircle( ball.x, ball.y, ball.size , paint5);



                    //Ballクラスのボールを移動
                    ball.x += ball.vx;
                    ball.y += ball.vy;
                    //TODO:ボールの中心で判定されてるので、ボールの幅で判定するようにする(Option)
                    //壁に衝突
                    if (ball.x < 0 || getWidth() < ball.x)  ball.vx *= -1;
                    if (ball.y < 0 || getHeight() < ball.y) ball.vy *= -1;
                    //バーに衝突
                    if (ball.x + ball.size >=bar.x) ball.vx *= -1;
                    if (ball.x <= bar.x + bar.halfBar) ball.vx *= -1;
                    if (ball.y >= bar.y) ball.vx *= -1;



                    getHolder().unlockCanvasAndPost(canvas);

                }
            }

        }




    }





}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

onToucheventの返り値がsuperになってるので単にreturn true;
とする。

return super....がAndroid Studioで補完されるので return true;に書き換えなさいよ。

参考

で、run()ループ内にbar移動のコード書く。

(下記は知識不足のため正確ではない可能性がある)
理屈としては、おそらく
run()ループの中に書く → 移動がループする → 結果滑らかな移動に見える

ループ内に書かないと、ループしないのでカクカク(瞬間移動)に見える

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

細かな仕様が明記されていないので方法だけ書きます。
1-ACTION_DOWNの時にタッチされた位置を取得する。
2-現在のBarの位置と1で取得した位置との差分をとる
3-2の差分を任意の値で割る
4-任意の間隔で動作する別スレッドで2の値を加算しBarの位置を1の位置に近づけ描画更新を行う。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/10 16:15

    ご回答ありがとうございます。

    動作させたい内容を詳しく追記してみました。

    また、
    http://dev.classmethod.jp/smartphone/android/touch/
    を参考に、回答いただいた1,2,3をやってみました。
    リンク先ではImageViewの移動なので細かい部分は理解できていませんが。。。

    4の部分の「別スレッド作成」と「描画更新」「Barの位置を1の位置に近づけ」
    というのがわからないです。
    MainActivityの中にthreadクラス?を作って、その中で描画更新するメソッドを使うという感じでしょうか?

    キャンセル

  • 2016/05/10 16:27

    ボールの動きの様にや滑らかなどの表現は仕様として十分ではありません。あなたが言う滑らかは全員が納得する滑らかではないんですよ。

    例えば「ユーザーが触っている位置に何秒で移動するか」や「バーは何ミリ秒毎または何px毎に更新する」を決めないとルールがあるゲームは作れないです。

    4番についてはThreadクラスを使った定期実行を適切な場所に入れればいいですよ。

    また、参考URLはコメントではなく質問にリンクとして記述したほうがいいですよ。

    キャンセル

  • 2016/05/10 20:35

    知識不足のため言葉で説明できないので動画を追加しました。
    文章も修正しました。

    4番調べてやってみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る