W poprzednim programie narysowaliśmy słońce nad morzem za pomocą grafiki Canvas. Teraz wprowadzimy je w ruch.

Będzie to bardziej przypominać piłkę niż morze.

Niestety przy animacji nie działają dobrze stare metody znane z Appletów – tj. m. in. tworzenie wątków z zatrzymaniem ThreadSleep(). Zamiast tego tworzymy Handler i odroczone kolejne wywołania funkcji (podobnie jak w JavaScript).

Ale od początku.

  1. Robimy Activity
  2. Teraz wewnątrz niej tworzymy klasę typu Canvas (robiliśmy to w programie „Rysowanie 2d Android”)
  3. Wewnątrz tej klasy w metodzie move() tworzymy kolejną wewnętrzną klasę wątka z jedną metodą run()
  4. Trochę to zagmatwane, ale obrazowo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class MainActivity extends ActionBarActivity {
    ....
       public class Obraz2d extends View  {
            Handler m_handler;
            Runnable m_handlerTask;
            .......
             //konstruktor:
             public Obraz2d(Context context) {
                 ...

                    m_handler = new Handler();  
                    move(); //nasza funkcja wprawiamy w ruch
            }

             public void move()
            {

                m_handlerTask = new Runnable()
                {
                    @Override
                    public void run() {
                        ....
                         //tu zmienne związane z ruchem i na końcu dodajemy 2 linijki:
                        invalidate();
                        m_handler.postDelayed(m_handlerTask, 30); //tu delay 30 ms
                    }

                }; //koniec klasy w klasie w klasie :P
                      m_handlerTask.run();
           } //koniec metody move()

       ... //tu normalnie rysowanie onDraw
    };

    Kod skaczącej piłki (słońce) nad morzem:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    package com.fulara.fingerboardmaster;

    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.drawable.BitmapDrawable;
    import android.os.Handler;
    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;


    public class Grafika2d extends ActionBarActivity {
        program game;
        Obraz2d grafika;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            grafika = new Obraz2d(this);
            setContentView(grafika);
        }



        public class Obraz2d extends View  {
            Handler m_handler;
            Runnable m_handlerTask;
            int pozx, pozy, krok, srednica;

            public Obraz2d(Context context) {
             super(context);
             srednica=120;
             pozx=srednica+10;
             pozy=0;
             krok=10;
             m_handler = new Handler();
             move();
            }


            public void move()
            {

                m_handlerTask = new Runnable()
                {
                    @Override
                    public void run() {
                        //theta = theta + Math.toRadians(2);

                        int maxx = getWidth();
                        if (pozx>=maxx - srednica || pozx<=srednica) {
                            krok *= -1;
                            m_handler.removeCallbacks(m_handlerTask);
                        }
                        pozx= pozx+krok;
                        invalidate();
                        m_handler.postDelayed(m_handlerTask, 30);

                    }
                };
                m_handlerTask.run();

            }



            @Override
            protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                int x = getWidth();
                int y = getHeight();
                int radius;
                radius = srednica;
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(Color.BLACK);
                canvas.drawPaint(paint);
                paint.setColor(Color.parseColor("#FFFF00"));
                canvas.drawCircle(pozx, y / 2, radius, paint);
                paint.setColor(Color.rgb(0,255,255));
                canvas.drawText("Słońce nad morzem! :)",x/2 - 50,10, paint);
                paint.setColor(Color.BLUE);
                canvas.drawRect(0,y-20,x,y,paint);
            }
        }



        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();

            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }

            return super.onOptionsItemSelected(item);
        }
    }