Android绘制多条线

时间:2014-09-20 09:16:18

标签: java android multithreading canvas graphic

我想对超声波传感器的距离数据进行图形表示(尚未实现)

我想绘制一个代表gokart的矩形,前面有6行,后面有6行。 由于我的新手java知识,代码似乎被严重屠杀。 在测试线条绘制方法时,程序将无法启动。有什么想法吗?

package com.example.gokartdst;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback
{
    private RefreshThread drawThread;
    public static int screenWidth;
    public static int screenHeight;
    private float density;

    public static float tX;
    public static float tY;
    public int i;
    public int j;

    private GoKart[][] detectors;


    public GameView(Context context, float density) {
        super(context);

        this.density = density;
        detectors=new GoKart[1][5];
        for(i=0;i<=1;i++)
        {
            for(j=0;j<=5;j++)
            {
                detectors[i][j]=new GoKart(i,j);
            }
        }



        //detectors = new GoKart(Color.WHITE, 15.0, dpTodx(30));

        getHolder().addCallback(this);
        drawThread = new RefreshThread(getHolder(), this);
    }

    /*public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    */

    // Itt számolja újra a szükséges pozíciókat
    public void update(Canvas c) {

        if (c != null) {
            screenWidth = c.getWidth();
            screenHeight = c.getHeight();
        }

        //detectors.BallPosUpdate();

    }

    //Újrarajzolás
    @Override
    public void onDraw(Canvas canvas) {
        if (canvas != null) {
            canvas.drawColor(Color.BLACK);
            for(i=0;i<=1;i++)
                for(j=0;j<=5;j++)
                {
                    detectors[i][j].BallDraw(canvas);
                }

            //Log.i("onDraw", "onDraw");
        }
    }

    public int dpTodx(int dp) {
        int px = (int) (dp*density);
        return px;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if(drawThread!=null)
        {
          drawThread.setRunning(true);
          drawThread.start();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        if(drawThread!=null)
        {
            drawThread.setRunning(false);
            while (retry) {
                try {
                    drawThread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        }
    }

    // A RefreshThread a fő szál, hogy ne az UI szálon fusson. Így gyorsabb.
        class RefreshThread extends Thread {
            private SurfaceHolder mSurfaceHolder;
            private GameView gameView;
            private boolean enabled = false;

            public RefreshThread(SurfaceHolder surfaceHolder, GameView panel) {
                mSurfaceHolder = surfaceHolder;
                gameView = panel;
            }

            public void setRunning(boolean run) {
                enabled = run;
            }
            @Override
            public void run() {
                long lastTime = System.nanoTime();
                long timer = System.currentTimeMillis();
                final double ns = 1000000000.0 / 60.0;
                double delta = 0;
                int frames = 0;
                int updates = 0;
                Canvas c;
                while (enabled) {
                    c = null;
                    long now = System.nanoTime();
                    delta += (now - lastTime) / ns;
                    //Log.i("DELTA", Double.toString(delta));
                    lastTime = now;

                    try {
                        c = mSurfaceHolder.lockCanvas(null);
                        while (delta >= 1) {
                            synchronized (mSurfaceHolder) {
                                if (gameView != null) {
                                    gameView.update(c);
                                    updates++;
                                    delta--;
                                }
                            }
                        }
                        gameView.onDraw(c);
                        frames++;

                        if (System.currentTimeMillis() - timer > 1000) {
                            timer += 1000;
                            Log.i("Frames", "Frames: " + frames + " | Updates: " + updates);
                            updates = 0;
                            frames = 0;
                        }
                    } finally {
                        // igy biztos nem hagyjuk
                        // inkonzisztens állapotban a Surface-t
                        if (c != null) {
                            mSurfaceHolder.unlockCanvasAndPost(c);
                        }
                    }
                }
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // TODO Auto-generated method stub

        }   
}

Gokart对象:

package com.example.gokartdst;

import android.graphics.Canvas;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.Paint;

public class GoKart {

    private int i;
    private double j;

    private int dst;

    ShapeDrawable mLinesDrawable;
    Paint paint= new Paint();

    public GoKart(int ix, double jx) {

        this.i = ix;
        this.j = jx;
        mLinesDrawable = new ShapeDrawable(new RectShape());
    }

    public void BallDraw(Canvas canvas) {

        /*mLinesDrawable.setBounds(X - diameter / 2, Y - diameter / 2, X + diameter / 2, Y + diameter / 2);
        mLinesDrawable.getPaint().setColor(color);
        mLinesDrawable.draw(canvas);
        */
        if(i==0)
        {
            if(j==1)
            {
                canvas.drawLine(30, 30, 40, 30, paint);
            }
            if(j==2)
            {
                canvas.drawLine(40, 30, 50, 30, paint);
            }
        }
    }

和Logkat:

09-20 11:01:29.320: W/dalvikvm(5277): threadid=1: thread exiting with uncaught exception (group=0x415efba8)
09-20 11:01:29.320: E/AndroidRuntime(5277): FATAL EXCEPTION: main
09-20 11:01:29.320: E/AndroidRuntime(5277): Process: com.example.soccergame, PID: 5277
09-20 11:01:29.320: E/AndroidRuntime(5277): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.soccergame/com.example.gokartdst.GameActivity}: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.os.Handler.dispatchMessage(Handler.java:102)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.os.Looper.loop(Looper.java:136)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread.main(ActivityThread.java:5017)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at java.lang.reflect.Method.invokeNative(Native Method)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at java.lang.reflect.Method.invoke(Method.java:515)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at dalvik.system.NativeStart.main(Native Method)
09-20 11:01:29.320: E/AndroidRuntime(5277): Caused by: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
09-20 11:01:29.320: E/AndroidRuntime(5277):     at com.example.gokartdst.GameView.<init>(GameView.java:36)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at com.example.gokartdst.GameActivity.onCreate(GameActivity.java:17)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.Activity.performCreate(Activity.java:5231)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-20 11:01:29.320: E/AndroidRuntime(5277):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
09-20 11:01:29.320: E/AndroidRuntime(5277):     ... 11 more

2 个答案:

答案 0 :(得分:1)

因为你的for循环,它应该是

    for(i=0;i<1;i++)
    {
        for(j=0;j<5;j++)
        {
            detectors[i][j]=new GoKart(i,j);
        }
    }

注意我改变了外部和内部循环。两种停止条件都应该使用&lt;运算符不是&lt; =

每当你创建一个大小为N的数组(或者在这种情况下是2D数组)时,只要i(或j)小于N,你就应该迭代,因为如果你在i <= N时继续它也将继续i = N + 1,这将导致ArrayIndexOutOfBoundsException,它基本上表示你要求的值超出数组的范围。

答案 1 :(得分:1)

您的数组detectors长度为5

for(j = 0; j <= 5; j++) {
    detectors[i][j] = new GoKart(i, j);
}

当您将值分配到第6个索引时,for循环中的条件为j <= 5,使其为j < 5

应该是

for(j = 0; j < 5; j++) {
    detectors[i][j] = new GoKart(i, j);
}