Reputation: 175
So I got this working class that creates a DarkHole object in the screen. Its a filled circle with random color, position and radius.
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;
}
}
My problem is:
CriarDarkHole() is only triggered once. It should create another darkhole every time its called, adding balls on the screen. In the case, every time the screen is touched.
Why it's not working? How it should be done?
EDIT 1 - Tried to add a ShapeDrawable array an draw it
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;
}
}
Now when i Tap the display it draws a new ball but erasing the old one. How draw all the balls ? Where am I missing?
EDIT 2 - Now it's working but doesn't feel the right way to code
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;
}
}
App Image
https://i.sstatic.net/erg5z.jpg
Even now that it working, it doesn't feel the right way to do it. I mean in an OOP way... Is it re-drawing all the balls every time?! Any tips, critics or suggestions?
Upvotes: 0
Views: 1694
Reputation: 175
WORKING LIKE A CHARM!
Now I draw multiple balls on touch and I can even test their collisions
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);
}
}
The ideia is:
Generate a circle with random diameter, color, and position
Test if that circle is colliding with any other circle already drawn
If it is colliding, re-generate random stuff, if not add that circle to the arraylist
Upvotes: 1