绘制多个对象 - Android

时间:2015-05-30 03:20:33

标签: java android canvas ontouchevent ondraw

所以我得到了这个在屏幕上创建DarkHole对象的工作类。它是一个带有随机颜色,位置和半径的实心圆圈。

public class DarkHole extends View
{
    private ShapeDrawable mDarkHole;

    // instance variables
    private int x, y, Xt, Yt;        // position
    private double forca;        // velocity
    private int raio;  // radius

    private int minRaio = 30;
    private int maxRaio = 200;

    private WindowManager wm;
    private Display display;
    private int width;
    private int height;

    int r,g,b ;
    int randomColor;

    Point size;

    private Random rand;

    // constructor
    public DarkHole(Context context)
    {
        super(context);

        mDarkHole = new ShapeDrawable(new OvalShape());

        rand = new Random();

        //Get Screen Size
        size = new Point();
        wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
        display = wm.getDefaultDisplay();
        display.getSize(size);
        width = (size.x);
        height = (size.y);

        //Set a random color
        r = rand.nextInt(255);
        g = rand.nextInt(255);
        b = rand.nextInt(255);
        randomColor = Color.rgb(r, g, b);

        CriarDarkHole();
    }
    public void CriarDarkHole()
    {
        x = rand.nextInt(width + 1);
        y = rand.nextInt(height + 1);

        raio = rand.nextInt(maxRaio - minRaio + 1) + minRaio;

        mDarkHole.getPaint().setColor(randomColor);
        mDarkHole.setBounds(x, y, x + raio, y + raio);
    }

    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        //mDarkHole.draw(canvas);
        //for(int i = 0; i <100; i++)
        // {
        mDarkHole.draw(canvas);
        //}
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        Xt = (int) event.getX();
        Yt = (int) event.getY();

        int evento = event.getAction();

        switch (evento)
        {
        case MotionEvent.ACTION_DOWN:
            CriarDarkHole();
            //isTouch = true;
            break;

        case MotionEvent.ACTION_MOVE:
            //coords.setText("X: " + X + ", Y: " + Y);
            break;

        case MotionEvent.ACTION_UP:
            //Toast.makeText(this, "Saiu da tela em: X: " + X + ", Y: " + Y, Toast.LENGTH_SHORT);
            //isTouch = false;
            break;
        }
        return true;
    }

}

我的问题是:

  1. CriarDarkHole()只触发一次。它应该在每次调用时创建另一个黑洞,在屏幕上添加球。在这种情况下,每次触摸屏幕。

    为什么它不起作用?应该如何做?

  2. 编辑1 - 尝试添加一个ShapeDrawable数组并将其绘制

        public class DarkHole extends View
    {
    
        private ShapeDrawable mDarkHole;
    
        // instance variables
        private int x, y, Xt, Yt;        // position
        private double forca;        // velocity
        private int raio;  // radius
    
        private int minRaio = 30;
        private int maxRaio = 200;
    
        List<ShapeDrawable> holescreated;
    
        private WindowManager wm;
        private Display display;
        private int width;
        private int height;
    
        int r,g,b ;
        int randomColor;
    
        Point size;
    
        private Random rand;
    
        // constructor
        public DarkHole(Context context)
        {
            super(context);
    
            rand = new Random();
            holescreated = new ArrayList<ShapeDrawable>();
    
            //Get Screen Size
            size = new Point();
            wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
            display = wm.getDefaultDisplay();
            display.getSize(size);
            width = (size.x);
            height = (size.y);
    
    
    
            CriarDarkHole();
    
        }
        public void CriarDarkHole()
        {
            //mDarkHole = new ShapeDrawable(new OvalShape());
            holescreated.add(new ShapeDrawable(new OvalShape()));
    
            //Set a random color
            r = rand.nextInt(255);
            g = rand.nextInt(255);
            b = rand.nextInt(255);
            randomColor = Color.rgb(r, g, b);
    
            x = rand.nextInt(width + 1);
            y = rand.nextInt(height + 1);
    
            raio = rand.nextInt(maxRaio - minRaio + 1) + minRaio;
    
            for(ShapeDrawable m: holescreated)
            {
                m.getPaint().setColor(randomColor);
                m.setBounds(x, y, x + raio, y + raio);
            }
    
        }
    
        protected void onDraw(Canvas canvas)
        {
            super.onDraw(canvas);
            //mDarkHole.draw(canvas);
            for(ShapeDrawable m: holescreated)
            {
                m.draw(canvas);
            }
            invalidate();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            Xt = (int) event.getX();
            Yt = (int) event.getY();
    
            int evento = event.getAction();
    
            switch (evento)
            {
            case MotionEvent.ACTION_DOWN:
                CriarDarkHole();
                //isTouch = true;
                break;
    
            case MotionEvent.ACTION_MOVE:
                //coords.setText("X: " + X + ", Y: " + Y);
                break;
    
            case MotionEvent.ACTION_UP:
                //Toast.makeText(this, "Saiu da tela em: X: " + X + ", Y: " + Y, Toast.LENGTH_SHORT);
                //isTouch = false;
                break;
            }
            return true;
        }
    
    
    
    }
    

    现在,当我点击显示屏时,它会绘制一个新球,但会删除旧球。 怎么画所有的球?我在哪里错过了?

    编辑2 - 现在它正在运作,但感觉没有正确的代码方式

    public class DarkHole extends View
    {
    
        private ShapeDrawable mDarkHole;
    
        // instance variables
        private int x, y, Xt, Yt;        // position
        private double forca;        // velocity
        private int raio;  // radius
    
        private int minRaio = 30;
        private int maxRaio = 100;
    
        List<ShapeDrawable> holescreated;
    
        private WindowManager wm;
        private Display display;
        private int width;
        private int height;
    
        int r,g,b ,cont;
        int randomColor;
        Paint cor;;
    
        Point size;
    
        private Random rand;
    
        // constructor
        public DarkHole(Context context)
        {
            super(context);
    
            cor = new Paint();
    
            rand = new Random();
            holescreated = new ArrayList<ShapeDrawable>();
            cont = 0;
            //Get Screen Size
            size = new Point();
            wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
            display = wm.getDefaultDisplay();
            display.getSize(size);
            width = (size.x);
            height = (size.y);
    
    
    
            CriarDarkHole();
    
        }
        public void CriarDarkHole()
        {
            cor.setColor(Color.BLACK);
            cor.setTextSize(70);
            cor.setAntiAlias(true);
            cor.setDither(true);
            //mDarkHole = new ShapeDrawable(new OvalShape());
            holescreated.add(new ShapeDrawable(new OvalShape()));
    
            //Set a random color
            r = rand.nextInt(255);
            g = rand.nextInt(255);
            b = rand.nextInt(255);
            randomColor = Color.rgb(r, g, b);
    
    
            raio = rand.nextInt(maxRaio - minRaio + 1) + minRaio;
    
            x = rand.nextInt((width-raio)  + 1) ;
            y = rand.nextInt((height-raio)  + 1) ;
    
    
    
            for(ShapeDrawable m: holescreated)
            {
                holescreated.get(cont).getPaint().setColor(randomColor);
                holescreated.get(cont).setBounds(x, y, x + raio, y + raio);
            }
            cont++;
        }
    
        protected void onDraw(Canvas canvas)
        {
            super.onDraw(canvas);
            //mDarkHole.draw(canvas);
            for(ShapeDrawable m: holescreated)
            {
                m.draw(canvas);
                canvas.drawText("Bolas: " + holescreated.size(),10,50, cor);
            }
            invalidate();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            Xt = (int) event.getX();
            Yt = (int) event.getY();
    
            int evento = event.getAction();
    
            switch (evento)
            {
            case MotionEvent.ACTION_DOWN:
                CriarDarkHole();
                //isTouch = true;
                break;
    
            case MotionEvent.ACTION_MOVE:
                CriarDarkHole();
                //coords.setText("X: " + X + ", Y: " + Y);
                break;
    
            case MotionEvent.ACTION_UP:
                //Toast.makeText(this, "Saiu da tela em: X: " + X + ", Y: " + Y, Toast.LENGTH_SHORT);
                //isTouch = false;
                break;
            }
            return true;
        }
    }
    

    应用图片

    http://imgur.com/j2kmSSj

    即使它现在有效,它也没有感觉到正确的方法。我的意思是以OOP方式......每次都重新绘制所有球吗?!任何提示,评论或建议?

1 个答案:

答案 0 :(得分:1)

工作就像一个魅力!

现在我在触摸时绘制了多个球,我甚至可以测试它们的碰撞

public class DarkHole extends View {

    public static final int maxDiameter = 250;

    public static final int minDiameter = 240;

    /**
    * This class log tag.
    */
    private static final String LOG_TAG = DarkHole.class.getSimpleName();

    private static List<ShapeDrawable> mHoles;

    private int mWindowWidth;

    private int mWindowHeight;

    private Random random;

    /**
    * The constructor;
    *
    * @param context application context.
    */
    public DarkHole(Context context) {
        super(context);
        mHoles = new ArrayList<ShapeDrawable>();
        random = new Random();

        //Get Screen Size
        Point point = new Point();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        display.getSize(point);

        // Get screen max x and y.
        mWindowWidth = point.x;
        mWindowHeight = point.y;
    }

    /**
    * Draw random hole.
    */
    private void generateRandomHole() {
        while(true) {
            ShapeDrawable hole = new ShapeDrawable(new OvalShape());

            // Generate random color.
            int r = random.nextInt(255);
            int g = random.nextInt(255);
            int b = random.nextInt(255);
            int randomColor = Color.rgb(r, g, b);

            // Generate random position.
            int diameter = random.nextInt(maxDiameter - minDiameter + 1) + minDiameter;
            int x = random.nextInt((mWindowWidth - diameter) + 1);
            int y = random.nextInt((mWindowHeight - diameter) + 1);

            hole.getPaint().setColor(randomColor);
            hole.setBounds(x, y, x + diameter, y + diameter);

            if (checkDrawContains(hole)) {
                hole = null;
            } else {
                mHoles.add(hole);
                break;
            }
        }
    }

    /**
    * Draw informative text.
    *
    * @param canvas canvas object.
    */
    private void generateText(Canvas canvas) {
        Paint color = new Paint();
        color.setColor(Color.BLACK);
        color.setTextSize(70);
        color.setAntiAlias(true);
        color.setDither(true);
        canvas.drawText("Bolas: " + mHoles.size(), 10, 50, color);
    }


    private boolean checkDrawContains(ShapeDrawable newHole) {
        long newCenterX = newHole.getBounds().left + (newHole.getBounds().width()/2);
        long newCenterY = newHole.getBounds().top + (newHole.getBounds().height()/2);

        for(ShapeDrawable hole: mHoles) {
            long centerX = hole.getBounds().left + (hole.getBounds().width()/2);
            long centerY = hole.getBounds().top + (hole.getBounds().height()/2);
            long x = centerX - newCenterX;
            long y = centerY - newCenterY;
            long aux = (long) ((Math.pow(Math.abs(x),2)) + (Math.pow(Math.abs(y),2)));
            long distance = (long) Math.sqrt(aux);
            long sRads = (newHole.getBounds().width()/2) + (hole.getBounds().width()/2);

            if(distance <=  sRads ) {
                return true;
            }
        }
        return false;
    }

    /** {@inheritDoc} */
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        generateText(canvas);
        for (ShapeDrawable hole : mHoles) {
            hole.draw(canvas);
        }

        invalidate();
    }

    /** {@inheritDoc} */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            generateRandomHole();
            return true;
        }
        return super.onTouchEvent(event);
    }
}

意思是:

  1. 生成具有随机直径,颜色和位置的圆

  2. 测试该圆圈是否与已绘制的任何其他圆圈相撞

  3. 如果是碰撞,请重新生成随机内容,如果不是将该圈添加到arraylist