java - 绘制多个对象 - Android

标签 java android canvas touch-event 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() 仅触发一次。每次调用时,它都应该创建另一个黑洞,在屏幕上添加球。在这种情况下,每次触摸屏幕时。

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

<小时/>

编辑 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;
    }
}
<小时/>

应用图片

/image/erg5z.jpg

<小时/>

即使现在它可以工作,但感觉不是正确的方法。我的意思是,以面向对象的方式......是不是每次都重新绘制所有的球?!有什么提示、批评或建议吗?

最佳答案

像魅力一样工作!

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

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. 如果发生碰撞,则重新生成随机内容,如果没有,则将该圆圈添加到数组列表中

关于java - 绘制多个对象 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30541880/

相关文章:

java - 为什么在 Java 中迭代 Empty Map 不会抛出任何异常

java - 在 Android Studio 上调试 native 和 java-app 时出错

android - 如何签署一个android apk文件

javascript - 在 Three.js 中将 Material 包裹在立方体周围

Java通用通配符用法

java - 在字符串中搜索子字符串

java - Scala 抽象类翻译成 Java

iphone - 手机应用程序能否检测到周围哪些手机正在运行相同的应用程序?

javascript - 图像上的 Canvas

使用笔自由绘制时,JavaFX 在 Canvas 上的性能下降