Как создать событие для уточнения c Drawable? - PullRequest
1 голос
/ 13 апреля 2020

Я должен сделать событие, когда я касаюсь карт с бриллиантами. Это потому, что цель - набрать очки, когда я их трогаю. Ничего не должно произойти, если я коснусь карты (например, фона или карты с овалом).

Я прошел метод onTouchEvent(), но он является общим на всем экране, а не только один Drawable.

GameView. java

package com.example.game;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.Arrays;
import java.util.Random;

public class GameView extends View {

    private static final String TAG = "TAG_GameView";
    private final Drawable diamond;
    private final Drawable circle;

    private final boolean[] columnFree;
    private final Paint background;

    int column;
    int a;
    int b;

    int[] x;
    int[] y;
    int[] speed;
    int[] type;

    public GameView(Context context) {
        super(context);
        diamond = context.getResources().getDrawable(R.drawable.diamond);
        circle = context.getResources().getDrawable(R.drawable.circle);

        background = new Paint();

        column = 4;
        x = new int[column];
        y = new int[10*column];
        speed = new int[column];
        type = new int[10*column];
        columnFree = new boolean[column];

        Arrays.fill(y, 9999);
        Arrays.fill(type, 0);
        for (int i=0; i<speed.length; i++) {
            speed[i]=10*(1+(new Random().nextInt(2)));
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        background.setShader(new LinearGradient(0,0,0,getHeight(),Color.BLUE,Color.CYAN, Shader.TileMode.CLAMP));
        canvas.drawPaint(background);

        a = getWidth()*8/(9*column+1);
        b = a*diamond.getIntrinsicHeight()/diamond.getIntrinsicWidth();

        for (int i = 0; i < x.length; i++) {
            x[i] = a/8*(i+1) + a*i;
            columnFree[i] = true;
        }

        for (int i = 0; i < y.length; i++) {
            y[i] += speed[i%column];
            if (y[i]<b) {
                columnFree[i%column]=false;
            }
        }

        for (int i = 0; i < y.length; i++) {
            if ((y[i] > getHeight() && columnFree[i % column]) == true) {
                //For 40% chance of true
                if (new Random().nextInt(50) < 1) {
                    y[i] = -b;
                    columnFree[i%column] = false;
                    type[i] = new Random().nextInt(2);
                    Log.i(TAG, String.valueOf(type[i]));
                }
            } else {
                if (type[i]==0){
                    diamond.setBounds(x[i%column], y[i],x[i%column]+a,y[i]+b);
                    diamond.draw(canvas);
                } else {
                    circle.setBounds(x[i%column], y[i],x[i%column]+a,y[i]+b);
                    circle.draw(canvas);
                }
            }
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Arrays.fill(speed, 0);
        }
        return super.onTouchEvent(event);
    }
}

enter image description here

1 Ответ

1 голос
/ 17 апреля 2020

Как подсказал @CommonsWare, вам нужно отслеживать все позиции карт, присутствующие в данный момент на экране (или только все), и в onTouchEvent() проверять, произошло ли событие на алмазной карте

Отслеживать карты вроде этого:

Map<RectF, Drawable> cards = new HashMap();

// in onDraw method when you draw card also add it to that map

@Override
protected void onDraw(Canvas canvas){
//...

    if (type[i]==0){
        diamond.setBounds(x[i%column], y[i],x[i%column]+a,y[i]+b);
        diamond.draw(canvas);
        cards.put(new RectF(x[i%column], y[i],x[i%column]+a,y[i]+b), diamond)
    } else {
        circle.setBounds(x[i%column], y[i],x[i%column]+a,y[i]+b);
        circle.draw(canvas);
        cards.put(new RectF(x[i%column], y[i],x[i%column]+a,y[i]+b), diamond)
    }
//...
}

, а затем в onTouchEvent()

int points = 0;

@Override
public boolean onTouchEvent(MotionEvent event) {
    //...
    float x = event.getX();
    float y = event.getY();
    for (Map.Entry<RectF, Drawable> entry : cards.entrySet()) {
        if (entry.getKey().contains(x, y) && entry.getValue() == diamond) 
            points++;
    }
    //...
}

Также вы можете настроить использование, чтобы набирать очки за одну карту только один раз, введя некоторое значение boolean ( проверить, была ли нажата кнопка) и идентификатор карты (чтобы отличить guish его от других карт) и сохранить их вместе с прямоугольником карты и Drawable.

Или вы можете просто очистить столбец от карт с позиции алмазной карты, по которой щелкнули, и до конца столбца (чтобы он не перерисовывался в следующем кадре)

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...