How can I draw multiple circles in my canvas? - java

I can draw one circle but my problem is to know how can I draw multiple circles every time I clicked.
The center of the circle has to be the X and the Y coordinates that are clicked and I need to store that point on my Vector, and the vector cannot be destroyed everytime I click the View.
If I don't have the invalidate on the end of if (figure == 1) it doesn't draw the circle at all.
My center is a Point2D which has int x, int y stored.
package com.example.soalr.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.Vector;
public class MyView extends View {
Paint paint = null;
int figure;
int lados_poly;
int cor;
int deletar;
Circulo cir;
Circulo raio;
int CursorX, CursorY;
int nrCliques;
Vector<Ponto2D> ptsCirc = new Vector<Ponto2D>();
public MyView(Context context) {
super(context);
paint = new Paint();
figure = 0;
cor = 0;
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setStrokeWidth(10);
figure = 0;
cor = 0;
Ponto2D centroCirc = new Ponto2D();
centroCirc.x = CursorX;
centroCirc.y = CursorY;
cir = new Circulo(centroCirc);
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
figure = 0;
cor = 0;
}
public void clickEcra() {
setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
nrCliques++;
case MotionEvent.ACTION_UP:
CursorX = (int)event.getX();
CursorY = (int)event.getY();
if (figure == 1) {
Ponto2D centroCirc = new Ponto2D();
centroCirc.x = CursorX;
centroCirc.y = CursorY;
ptsCirc.add(centroCirc);
invalidate();
}
default:
return false;
}
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
clickEcra();
Ponto2D p3 = new Ponto2D();
p3.x = 600;
p3.y = 150;
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
paint.setColor(Color.parseColor("#3F5866"));
//cores
if (cor == 1) {
paint.setColor(Color.parseColor("#393E46"));
} else if (cor == 2){
paint.setColor(Color.parseColor("#00ADB5"));
} else if (cor == 3) {
paint.setColor(Color.parseColor("#F8B500"));
} else if (cor == 4) {
paint.setColor(Color.parseColor("#FC3C3C"));
}
//figuras
if (figure == 1) {
if (ptsCirc.size() > 0) {
for (int a = 0; a <= ptsCirc.size(); a++) {
Circulo raio = new Circulo(ptsCirc.get(a));
raio.radius = 100;
canvas.drawCircle(ptsCirc.get(a).x, ptsCirc.get(a).y, raio.radius, paint);
}
}
}
else if (figure == 2) {
clickEcra();
Ponto2D p1 = new Ponto2D();
Ponto2D p2 = new Ponto2D();
Reta retinha = new Reta(p1, p2);
if (nrCliques == 1) {
p1.x = CursorX;
p1.y = CursorY;
System.out.println("x1: " + p1.x + " y1: " + p1.y);
} else if (nrCliques == 2) {
p2.x = CursorX;
p2.y = CursorY;
System.out.println("x2: " + p2.x + " y2: " + p2.y);
}
System.out.println("x2_: " + retinha.pfinal.x + " y2_: " + retinha.pfinal.y);
System.out.println("x1_: " + retinha.pinicial.x + " y1_: " + retinha.pinicial.y);
canvas.drawLine(retinha.pinicial.x, retinha.pinicial.y, retinha.pfinal.x, retinha.pfinal.y, paint);
} else if (figure == 3) {
Poligono poly = new Poligono(lados_poly);
if (lados_poly >= 3) {
for (int i = 0; i <= lados_poly - 1; i++) {
Ponto2D ponto4 = new Ponto2D(poly.pontosPolig.get(i).x, poly.pontosPolig.get(i).y);
Ponto2D ponto5 = new Ponto2D();
if (i < lados_poly) {
ponto5.x = poly.pontosPolig.get(i + 1).x;
ponto5.y = poly.pontosPolig.get(i + 1).y;
Reta retaPoli = new Reta(ponto4, ponto5);
int var_lados = lados_poly - 1;
if (i != var_lados) {
canvas.drawLine(retaPoli.pinicial.x, retaPoli.pinicial.y, retaPoli.pfinal.x, retaPoli.pfinal.y, paint);
} else {
canvas.drawLine(poly.pontosPolig.firstElement().x, poly.pontosPolig.firstElement().y, retaPoli.pinicial.x, retaPoli.pinicial.y, paint);
}
}
}
}
}
if (deletar == 2){
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
nrCliques = 0;
}
}
public void setfigure(int a) {
this.figure = a;
}
public void Cor1_mudar(int text_cor) {
this.cor = text_cor;
}
public void verLados (int lados){
this.lados_poly = lados;
}
public void Resetar(int delete){
this.deletar = delete;
}
}
This is Circle.java:
package com.example.soalr.myapplication;
public class Circulo {
int radius;
Ponto2D centro;
public Circulo(Ponto2D c) {
radius = 0;
centro = c;
}
}

You have two problems here:
You only see 1 circle. This is probably because nrCliques is not the value you expect. Instead of iterating from 0 to nrCliques, consider iterating from 0 to ptsCirc.size(), or using a for..each loop. For problems like this, the debugger is your friend.
You don't see any circles unless you have that invalidate() call in onDraw(). Calling invalidate() from onDraw() causes the framework to call onDraw() repeatedly, as fast as it can. This doesn't hurt anything but it uses a lot of processor power for no good reason. It's better to "cue" your View to redraw at the moment that its attendant data changes. In this case, this means putting the invalidate() call after that call to ptsCirc.add(). Then, you'll only get roughly 1 call to onDraw() each time you tap the screen.

This is working code, the problem was I wasn't verifying if the Vector had anything inside him.
public class MyView extends View {
Paint paint = null;
int figure;
int lados_poly;
int cor;
int deletar;
int CursorX, CursorY;
int nrCliques;
Vector<Ponto2D> ptsCirc = new Vector<Ponto2D>();
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
figure = 0;
cor = 0;
}
public void clickEcra() {
setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
CursorX = (int)event.getX();
CursorY = (int)event.getY();
if (figure == 1) {
Ponto2D centroCirc = new Ponto2D();
centroCirc.x = CursorX;
centroCirc.y = CursorY;
ptsCirc.add(centroCirc);
invalidate();
}
default:
return false;
}
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
clickEcra();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
paint.setColor(Color.parseColor("#3F5866"));
//cores
if (cor == 1) {
paint.setColor(Color.parseColor("#393E46"));
} else if (cor == 2){
paint.setColor(Color.parseColor("#00ADB5"));
} else if (cor == 3) {
paint.setColor(Color.parseColor("#F8B500"));
} else if (cor == 4) {
paint.setColor(Color.parseColor("#FC3C3C"));
}
//figuras
if (figure == 1) {
if (ptsCirc.size() > 0) {
for (int a = 0; a < ptsCirc.size(); a++) {
Circulo raio = new Circulo(ptsCirc.get(a));
raio.radius = 100;
canvas.drawCircle(ptsCirc.get(a).x, ptsCirc.get(a).y, raio.radius, paint);
}
}
}
if (deletar == 2){
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
nrCliques = 0;
ptsCirc.removeAllElements();
ptsReta.removeAllElements();
}
}
public void setfigure(int a) {
this.figure = a;
}
public void Cor1_mudar(int text_cor) {
this.cor = text_cor;
}
public void Resetar(int delete){
this.deletar = delete;
}
}

Related

Draw Line in View using Vector (in Android Studio)

I'm trying to draw a line, I managed to do it before but the first point somehow was always 0, 0. Now my logic is, there are two Vectors, one to store each point that is clicked, and another to store the Line, which is made by two points clicked by the user. I do the verifications to see if the Vector is not empty and only then I draw the line. I don't really know what's going on, I've tried everything, hope some of you can help, I'm in real need. Thank you.
Here it goes the code from MyView.java:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.Vector;
public class MyView extends View {
Paint paint = null;
int figure;
int lados_poly;
int cor;
int deletar;
int CursorX, CursorY;
int nrCliques;
Vector<Ponto2D> ptsReta = new Vector<Ponto2D>();
Vector<Reta> guardaRetas = new Vector<Reta>();
public MyView(Context context) {
super(context);
paint = new Paint();
figure = 0;
cor = 0;
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setStrokeWidth(10);
figure = 0;
cor = 0;
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
figure = 0;
cor = 0;
}
public void clickEcra() {
setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
CursorX = (int)event.getX();
CursorY = (int)event.getY();
if (figure == 2){
Ponto2D ptReta = new Ponto2D();
ptReta.x = CursorX;
ptReta.y = CursorY;
ptsReta.add(ptReta);
if (ptsReta.size()> 0) {
for (int c = 0; c < ptsReta.size(); c++)
System.out.println("ptRetaX: " + ptsReta.get(c).x + " ptRetaY: " + ptsReta.get(c).y + " size " + ptsReta.size());
}
invalidate();
}
default:
return false;
}
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
clickEcra();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
paint.setColor(Color.parseColor("#3F5866"));
//cores
if (cor == 1) {
paint.setColor(Color.parseColor("#393E46"));
} else if (cor == 2){
paint.setColor(Color.parseColor("#00ADB5"));
} else if (cor == 3) {
paint.setColor(Color.parseColor("#F8B500"));
} else if (cor == 4) {
paint.setColor(Color.parseColor("#FC3C3C"));
}
if (figure == 2) {
if (ptsReta.size() >= 2) {
for (int b = 0; b < ptsReta.size(); b = b + 2) {
Reta retinha = new Reta(ptsReta.get(b), ptsReta.get(b + 1));
guardaRetas.add(retinha);
System.out.println("pts: " + ptsReta.get(b) + ptsReta.get(b + 1));
}
}
if (guardaRetas.size() > 0) {
for (int r = 0; r < guardaRetas.size(); r++) {
canvas.drawLine(guardaRetas.get(r).pinicial.x, guardaRetas.get(r).pinicial.y, guardaRetas.get(r).pfinal.x, guardaRetas.get(r).pfinal.y, paint);
}
}
}
//clear canvas
if (deletar == 2){
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#F5F1E0"));
canvas.drawPaint(paint);
nrCliques = 0;
ptsCirc.removeAllElements();
ptsReta.removeAllElements();
}
}
public void setfigure(int a) {
this.figure = a;
}
public void Cor1_mudar(int text_cor) {
this.cor = text_cor;
}
public void Resetar(int delete){
this.deletar = delete;
}
}
And now the code from Line.java:
public class Reta {
Ponto2D pinicial;
Ponto2D pfinal;
public Reta(){
pinicial = new Ponto2D();
pfinal = new Ponto2D();
}
public Reta(Ponto2D a, Ponto2D b) {
pinicial = a;
pfinal = b;
}
}
Update: It draws one line, and when I try to do another one, on the third click, it closes and I need to draw multiple lines in my canvas.
This were my changes, the following inside onDraw() method:
if (figure == 2) {
if (ptsReta.size() %2 == 0) {
for (int b = 0; b < ptsReta.size(); b = b + 2) {
Reta retinha = new Reta(ptsReta.get(b), ptsReta.get(b + 1));
guardaRetas.add(retinha);
}
if (guardaRetas.size() > 0) {
for (int r = 0; r < guardaRetas.size(); r++) {
canvas.drawLine(guardaRetas.get(r).pinicial.x, guardaRetas.get(r).pinicial.y, guardaRetas.get(r).pfinal.x, guardaRetas.get(r).pfinal.y, paint);
}
}
}
}
And this ones inside the click method:
public void clickEcra() {
setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
CursorX = (int)event.getX();
CursorY = (int)event.getY();
if (figure == 2){
Ponto2D ptReta = new Ponto2D();
ptReta.x = CursorX;
ptReta.y = CursorY;
ptsReta.add(ptReta);
invalidate();
}
default:
return false;
}
}
});
}

Collision Detection is Not Working

Basically I have been making a simple game in which I now want to create collision detection between the Player and the Enemy. I have made both a class of the player and the enemy and then also a separate GameView class. My issue is that there is simply no collision happening and I just don't understand why, I have changed the code various times but I still can't seem to crack it. I will leave my code below and if anyone sees where I have gone wrong it would be great help. Thank you.
GameView Class:
public class GameView extends SurfaceView implements Runnable {
Canvas canvas;
SurfaceHolder surfaceHolder;
Thread thread = null;
volatile boolean playing;
Paint paint;
Context context;
Player player;
int screenX, screenY, numberOfEnemies = 4, distanceBetweenEnemies;
int enemyX [] = new int[numberOfEnemies];
int enemyY [] = new int[numberOfEnemies];
private boolean paused = true;
Enemy enemy;
Enemy [] enemies;
Random random;
Rect [] enemyRectangle;
public GameView (Context context, int x, int y) {
super(context);
this.context = context;
surfaceHolder = getHolder();
paint = new Paint();
thread = new Thread();
screenX = x;
screenY = y;
player = new Player (context, screenX, screenY);
enemies = new Enemy[numberOfEnemies];
enemyRectangle = new Rect[numberOfEnemies];
enemy = new Enemy (context, screenX);
distanceBetweenEnemies = screenX * 3 / 4;
for (int i = 0; i < numberOfEnemies; i ++) {
enemies[i] = new Enemy(context, screenX);
enemyX[i] = screenX / 2 - enemy.getEnemyBitmap().getWidth() / 2 + i * distanceBetweenEnemies;
random = new Random();
enemyY[i] = random.nextInt(screenY - enemy.getEnemyBitmap().getHeight() / 2);
}
}
#Override
public void run() {
while (playing) {
draw();
if(!paused){
update();
}
}
}
private void draw () {
if (surfaceHolder.getSurface().isValid()) {
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.argb(255, 26, 128, 182));
canvas.drawBitmap(player.getPlayerBitmap(), player.getX(), player.getY(), null);
for (int i = 0; i < numberOfEnemies; i ++) {
canvas.drawBitmap(enemies[i].getEnemyBitmap(), enemyX[i], enemyY[i], null);
enemyRectangle [i] = new Rect(enemyX[i], enemyY[i], enemy.getEnemyBitmap().getWidth(),
enemy.getEnemyBitmap().getHeight());
enemyX[i] += enemy.getEnemySpeed();
}
update ();
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
private void update () {
player.updatePlayerPosition();
player.noLeaveScreen();
for (int i = 0; i < numberOfEnemies; i ++) {
if (enemyX[i] < 0 - enemy.getEnemyBitmap().getWidth()) {
enemyY[i] = random.nextInt(screenY);
enemyRectangle [i] = new Rect(enemyX[i], enemyY[i], enemy.getEnemyBitmap().getWidth(),
enemy.getEnemyBitmap().getHeight());
enemyX[i] += numberOfEnemies * distanceBetweenEnemies;
} else {
enemyX[i] += enemy.getEnemySpeed();
}
if (Rect.intersects(player.getPlayerRectangle(), enemyRectangle[i])) {
Log.e("COLLISION:", "Detected");
enemyX[i] = - 200;
}
}
}
public void pause () {
playing = false;
try {
thread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
}
public void resume () {
playing = true;
thread = new Thread(this);
thread.start();
}
#Override
public boolean onTouchEvent (MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
player.playerJump();
break;
}
return true;
}
}
Player Class:
public class Player {
Bitmap playerBitmap;
Rect playerRectangle;
int x, y, playerJumpSpeed, gravity, screenY;
boolean playerIsMoving;
public Player (Context context, int screenX, int screenY) {
this.screenY = screenY;
gravity = 2;
playerBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
x = screenX/2 - playerBitmap.getWidth()/2;
y = screenY/2 - playerBitmap.getHeight()/2;
playerRectangle = new Rect(x, y, playerBitmap.getWidth(), playerBitmap.getHeight());
playerJumpSpeed = - 1000;
playerIsMoving = true;
}
public void updatePlayerPosition () {
while (playerIsMoving) {
y += gravity;
break;
}
}
public void playerJump () {
while (playerIsMoving) {
y += playerJumpSpeed;
break;
}
}
public void noLeaveScreen () {
if (y < 0) {
playerJumpSpeed = 0;
} else {
playerJumpSpeed = - 40;
}
if (getY() > (screenY - playerBitmap.getHeight())) {
gravity = 0;
} else {
gravity = 2;
}
}
public int getX () {
return x;
}
public int getY () {
return y;
}
public Bitmap getPlayerBitmap () {
return playerBitmap;
}
public Rect getPlayerRectangle () {
return playerRectangle;
}
}
Enemy Class:
public class Enemy {
Bitmap enemyBitmap;
int enemySpeed, screenX;
boolean isEnemyMoving;
Random random;
public Enemy (Context context, int screenX) {
this.screenX = screenX;
enemyBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
random = new Random();
isEnemyMoving = true;
enemySpeed = - 3;
}
public int getEnemySpeed () {
return enemySpeed;
}
public Bitmap getEnemyBitmap () {
return enemyBitmap;
}
}
There are the classes, any help appreciated!

My onTouch method is not doing its proper fucntion

I am making a Android app. The objective is to make circles that when touched something happens. Here is the onTouch method
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
}else {
}
return true;
}
This part of the code is the thing that is not functioning properly here is the entire class below.
public class DrawingView extends View{
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
RectF rectf = new RectF(0, 0, 200, 0);
private static final int w = 100;
public static int lastColor = Color.BLACK;
private final Random random = new Random();
private final Paint paint = new Paint();
private final int radius = 230;
private final Handler handler = new Handler();
public static int redColor = Color.RED;
public static int greenColor = Color.GREEN;
int randomWidth = 0;
int randomHeight = 0;
public static int addPoints = 0;
private final Runnable updateCircle = new Runnable() {
#Override
public void run() {
lastColor = random.nextInt(2) == 1 ? redColor : greenColor;
paint.setColor(lastColor);
invalidate();
handler.postDelayed(this, 1000);
}
};
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
handler.post(updateCircle);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
handler.removeCallbacks(updateCircle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// your other stuff here
if(random == null){
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}else {
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}
canvas.drawCircle(randomWidth, randomHeight + radius/2f, radius, paint);
paint.setColor(Color.BLACK);
paint.setTextSize(150);
canvas.drawText("Score: " + addPoints, 120, 300, paint);
}
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
}else {
}
return true;
}
public boolean isInsideCircle(int x, int y){
if ((((x - randomWidth)*(x - randomWidth)) + ((y - randomHeight)*(y - randomHeight))) < ((radius)*(radius)))
return true;
return false;
}
}

Background moves farther and faster than anything else

OK, So Im drawing a bitmap beneath everything else for my background. Whenever the player moves it moves the enemy array 1 px and its supposed to do the same for the background. But whenever I move the background goes way faster and farther than everything else in the game. Can anyone tell me whats causing this? Heres the code. The code that moves everything is at the bottom in the set direction method.
package com.gametest;
import java.util.concurrent.CopyOnWriteArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class GameSurfaceView extends Activity implements OnTouchListener {
double ran;
int touchX, touchY, screenWidth, screenHeight, objX, objY;
static int bgx, bgy, bgW, bgH, enemyCount, score, playerHealth;
static boolean canUpdate;
static MyView v;
static Bitmap orb, orb2, explosion, bg;
static CopyOnWriteArrayList<Sprite> copy = new CopyOnWriteArrayList<Sprite>();
static String hpString;
static Player player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
v = new MyView(this);
v.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent me) {
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
return true;
case MotionEvent.ACTION_MOVE:
return true;
case MotionEvent.ACTION_UP:
touchX = (int) me.getX();
touchY = (int) me.getY();
for (Sprite sprite : copy) {
sprite.checkTouch(touchX, touchY);
return true;
}
}
return true;
}
});
canUpdate = true;
screenWidth = v.getWidth();
screenHeight = v.getHeight();
playerHealth = 250;
hpString = "Health " + playerHealth;
ran = 0;
score = 0;
orb = BitmapFactory.decodeResource(getResources(), R.drawable.blue_orb);
orb2 = BitmapFactory.decodeResource(getResources(), R.drawable.red_orb);
bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg1);
bgx = bg.getHeight()/2;
bgy = bg.getHeight()/2;
bgH = bg.getHeight();
bgW = bg.getWidth();
explosion = BitmapFactory.decodeResource(getResources(), R.drawable.explosion);
player = new Player(v, orb2, explosion, screenWidth, screenHeight);
createEnemies();
setContentView(v);
}
private void createEnemies() {
if (enemyCount < 5) {
screenWidth = v.getWidth();
screenHeight = v.getHeight();
copy.add(new Sprite(v, orb, explosion, screenWidth, screenHeight, copy.size()));
enemyCount++;
}
}
public static void checkECount(int id) {
canUpdate = false;
copy.remove(id);
enemyCount--;
CopyOnWriteArrayList<Sprite> c = new CopyOnWriteArrayList<Sprite>();
int index = 0;
for (Sprite s : copy) {
s.ID = index;
c.add(s);
index++;
}
score = score + 10;
copy = c;
canUpdate = true;
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
public class MyView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isItOk = false;
public MyView(Context context) {
super(context);
holder = getHolder();
}
#Override
public void run() {
while (isItOk == true) {
if (!holder.getSurface().isValid()) {
continue;
}
Canvas c = holder.lockCanvas();
if (canUpdate) {
canvas_draw(c);
}
holder.unlockCanvasAndPost(c);
try {
t.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void canvas_draw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Rect bgRec = new Rect(bgx, bgy, bgx+bgW, bgy+bgH);
canvas.drawBitmap(bg, null, bgRec, null);
ran = Math.random() * 5;
if (ran > 4.5) {
createEnemies();
}
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(15);
canvas.drawText(hpString, 10, 25, paint);
for (Sprite sprite : copy) {
sprite.sprite_draw(canvas);
}
Player.sprite_draw(canvas, copy);
}
public void pause() {
isItOk = false;
while (true) {
try {
t.join();
} catch (InterruptedException e) {
}
break;
}
t = null;
}
public void resume() {
isItOk = true;
t = new Thread(this);
t.start();
}
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
public static void damagePlayer() {
hpString = "Health " + playerHealth;
playerHealth = playerHealth - 5;
if (playerHealth < 0) {
hpString = "game over";
}
}
public static void setDirection(int i, int j) {
if (i == 0 && j == -1) {
for (Sprite s : copy) {
s.y++;
bgy++;
}
}
if (i == 0 && j == 1) {
for (Sprite s : copy) {
s.y--;
bgy--;
}
}
if (i == -1 && j == 0) {
for (Sprite s : copy) {
s.x++;
bgx++;
}
}
if (i == 1 && j == 0) {
for (Sprite s : copy) {
s.x--;
bgx--;
}
}
}
}
You are changing bgx based on the number of sprites you have in your copy Iterable. in your setDirection method, please move the bgy, bgx outside of the enhanced for loops, like in:
if (i == 0 && j == -1) {
for (Sprite s : copy) {
s.y++;
}
bgy++;
}

Signatures in Android

I want to make a class which captures a human signature for my Android app. I have this code so far:
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
List<Point> points = new ArrayList<Point>();
Paint paint = new Paint();
long oldTime = 0;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// paint.setColor(Color.BLACK);
// paint.setAntiAlias(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
Path path = new Path();
if (points.size() > 1) {
for (int i = points.size() - 2; i < points.size(); i++) {
if (i >= 0) {
Point point = points.get(i);
if (i == 0) {
Point next = points.get(i + 1);
point.dx = ((next.x - point.x) / 3);
point.dy = ((next.y - point.y) / 3);
} else if (i == points.size() - 1) {
Point prev = points.get(i - 1);
point.dx = ((point.x - prev.x) / 3);
point.dy = ((point.y - prev.y) / 3);
} else {
Point next = points.get(i + 1);
Point prev = points.get(i - 1);
point.dx = ((next.x - prev.x) / 3);
point.dy = ((next.y - prev.y) / 3);
}
}
}
}
boolean first = true;
for (int i = 0; i < points.size(); i++) {
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else {
Point prev = points.get(i - 1);
path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x
- point.dx, point.y - point.dy, point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_UP) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}
return super.onTouchEvent(event);
}
public boolean checkTime() {
//Check if there was an input 400 ms ago
long newTime = System.currentTimeMillis();
long diffirence = newTime - oldTime;
if (oldTime == 0) {
oldTime = System.currentTimeMillis();
return true;
} else if (diffirence <= 400) {
oldTime = System.currentTimeMillis();
return true;
}
return false;
}
}
class Point {
float x, y;
float dx, dy;
#Override
public String toString() {
return x + ", " + y;
}
}
The problem is that the line will connect to the latest point when I start drawing again, even when I stop drawing for a while. This is of course not very useful for capturing human signatures, that's why I created the checkTime method. If you stop drawing for 400ms it returns false, when you start drawing again it will start a new line which is not connected to the old line. I only just don't know how I can implement my method, I tried a lot but the line keeps connecting to the latest point, maybe someone can help me.
It's probably faster to create the path in onTouch and only draw it in onDraw.
Replace onTouch with
Path path = new Path();
int prevx=0;
int prevy=0;
int prevdx=0;
int prevdy=0;
public boolean onTouch(View view, MotionEvent event)
{
int x = event.getX();
int y = event.getY();
int dx = (x-prevx)/3;
int dy = (y-prevy)/3;
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
path.moveTo(x, y);
}
if(event.getAction() == MotionEvent.ACTION_MOVE)
{
path.cubicTo(prevx + prevdx, prevy + prevdy, x - dx, y - dy, x, y);
}
prevx=x;
prevy=y;
prevdx=dx;
prevdy=dy;
invalidate();
return true;
}
onDraw will be just
public void onDraw(Canvas canvas)
{
canvas.drawPath(path, paint);
}
I used this post from Lars Vogel, but many thanks to Marc Van Daele!
This is code wich paints the View:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
public SingleTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}
}
You have to call this activity to start paiting:
import android.app.Activity;
import android.os.Bundle;
public class SingleTouchActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SingleTouchEventView(this, null));
}
}

Categories

Resources