Issue
I have to make an event when I touch cards with diamonds. This because the aim is to get a score when I touch them. Nothing has to happen if I touch out of the card (eg. background or card with the oval).
I have gone through the onTouchEvent()
method but it is general on all over the screen, not only a single 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);
}
}
Solution
As @CommonsWare suggested you need to keep track of all the cards positions currently present on the screen(or just all of them) and in onTouchEvent()
check whether the event took place on diamond card
Track cards like this:
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)
}
//...
}
and then in 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++;
}
//...
}
Also you may adjust the usage to score points for one card only once by introducing some boolean
value(to check whether it was clicked) and card id(to distinguish it from other cards) and storing them along with the card rectangle and Drawable
.
Or you may just clean the column from cards from the position of the clicked diamond card and till the end of the column(so it won't be redrawn on next frame)
Hope it helps
Answered By - Pavlo Ostasha
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.