I have created a custom view so that i can draw shapes on clicks and preform some action
and i have created a method called fillOnTouch(); which is supposed to take a paint and canvas as parameters then draw colored circles on the canvas when i call this method from TouchEvent it doesn't draw on the canvas so I tried to create a path called coloredCircles and have added shapes to it on Touchevent then draw this path on onDraw method but the result is the same the shapes aren't drawen in the canvas as it's supposed to be
onTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(x, y);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
checkStrokeInRightPath(x, y);
FillLetters.fillCircleOnTouch(x, y, fillCircles, dataLists, mCanvas);
coloredCircles.addCircle(x, y, 20, Path.Direction.CW);
invalidate();
break;
}
return true;
}
fillOnTouch Method
public static void fillCircleOnTouch(float x, float y, Paint paint, List<List<Integer>> circleList, Canvas canvas) {
List<Integer> xPoints, yPoints, circleCount;
int r = DrawLetters.radius;
float xStart, xEnd, yStart, yEnd;
if (!circleList.isEmpty()) {
xPoints = circleList.get(0);
yPoints = circleList.get(1);
circleCount = circleList.get(2);
if (iterationCount < xPoints.size()) {
float nextCircleX = xPoints.get(iterationCount);
float nextCircleY = yPoints.get(iterationCount);
paint.setColor(blendColors("#FFFF00", "#0000FF", (circleCount.get(iterationCount)) * ((float) (1.0 / xPoints.size()))));
xStart = nextCircleX - r;
xEnd = nextCircleX + r;
yStart = nextCircleY - r;
yEnd = nextCircleY + r;
Range<Float> xRange = new Range<>(xStart, xEnd);
Range<Float> yRange = new Range<>(yStart, yEnd);
if (xRange.contains(x) && yRange.contains(y)) {
canvas.drawCircle(nextCircleX, nextCircleY, r, paint);
iterationCount++;
}
}
}
}
onDraw Method
#Override
protected void onDraw(Canvas canvas) {
// save the current state of the canvas before,
// to draw the background of the canvas
canvas.save();
// DEFAULT color of the canvas
int backgroundColor = Color.WHITE;
mCanvas.drawColor(backgroundColor);
// now, we iterate over the list of paths
// and draw each path on the canvas
for (Stroke fp : paths) {
mPaint.setColor(fp.color);
mPaint.setStrokeWidth(fp.width);
mCanvas.drawPath(fp.path, mPaint);
}
if (coloredCircles != null && !coloredCircles.isEmpty()) {
canvas.drawPath(coloredCircles, mPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
}
Related
I have a Surfaceview Class called ChickenView and I'm trying to make my bMapEgg have a touchevent. I tried using this bMapEgg.setOnTouchListener(this);
but it didn't work. Any ideas?
public void drawCourt() {
if (ourHolder.getSurface().isValid()) {
canvas = ourHolder.lockCanvas();
//Paint paint = new Paint();
canvas.drawColor(Color.BLACK);//the background
paint.setColor(Color.argb(255, 255, 255, 255));
paint.setTextSize(45);
canvas.drawText("Score:" + score + " Lives:" + lives + " fps:" + fps, 20, 40, paint);
Bitmap bMapEgg = BitmapFactory.decodeResource(getResources(), R.drawable.egg);
bMapEgg = scaleDown(bMapEgg,180,true);
Bitmap bMapBackground = BitmapFactory.decodeResource(getResources(), R.drawable.backgrounddd);
canvas.drawBitmap(bMapBackground, 0, 0, paint);
canvas.drawBitmap(bMapEgg, ballPosition.x, ballPosition.y, paint);
ourHolder.unlockCanvasAndPost(canvas);
}
}
First, you need to setup a touch listener for the whole SurfaceView. Next, to check whether the bitmap was touched you need to do something like this:
float x = touchEvent.getX();
float y = touchEvent.gety();
// Replace these with the correct values (bitmap x, y, width & height)
float x1 = bitmapPositionX;
float x2 = x1 + bitmapWidth;
float y1 = bitmapPositionY;
float y2 = y1 + bitmapHeight;
// Test to see if touch is inside the bitmap
if (x > x1 && x < x2 && y > y1 && y < y2) {
// Bitmap was touched
switch (touchEvent.getAction()) {
case TouchEvent.ACTION_DOWN: (bitmap was just touched) break;
case TouchEvent.ACTION_DOWN: (user lifted finger from bitmap) break;
}
}
if i draw two lines using pathshape in shapedrawble that both have the same starting point, they appear to be drawn at different starting points on the screen. when i draw two lines at the same starting point but at different angles they can in the right circumstances appear to be drawn at different starting points as seen below. This is driving me crazy, any help would be appreciated.
public class drawtest extends View {
private ShapeDrawable mDrawable;
Canvas can = null;
float startx;
float starty;
float endx;
float endy;
float width = 0;
float canvasWidth = 0;
float canvasHeight = 0;
private Paint mBitmapPaint;
float height;
Bitmap bm = null;
Path p;
public drawtest(Context context) {
super(context);
endy=0;
endx=0;
startx=0;
starty=0;
width = 0;
height = 0;
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(0, 0, 0, 0);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
canvasHeight = h;
canvasWidth = w;
super.onSizeChanged(w, h, oldw, oldh);
bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
can = new Canvas(bm);
}
public void test(){
setStart(canvasWidth/2, canvasHeight/2);
double r = 125;
double tempx = 236;
double h = startx;
double k = starty;
//(x-h)^2 + (y-k)^2 = r^2
//y = sqrt(r^2 - (x-h)^2) + k
for(int i = 0; i < 2; ++i){
double tempy = Math.sqrt((r*r) - Math.pow((tempx - h),2)) + k;
setEnd((float) tempx, (float) tempy);
draw();
invalidate();
newCanvas();
tempx+=56;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.drawBitmap(bm, 0, 0, mBitmapPaint);
mDrawable.draw(canvas);
canvas.restore();
}
void newCanvas(){
mDrawable.draw(can);
can.save();
}
public void setStart(float X, float Y){
startx = X;
starty = Y;
}
public void setEnd(float X, float Y){
endx = X;
endy = Y;
width = Math.abs(endx - startx);
height = Math.abs(endy - starty);
}
private void getnewshape() {
p = new Path();
p.moveTo(startx, starty);
p.lineTo(endx, endy);
mDrawable = new ShapeDrawable(new PathShape(p, width, height));
}
public void draw() {
getnewshape();
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.getPaint().setStyle(Paint.Style.STROKE);
mDrawable.setBounds(0, 0, (int) width, (int) height);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
test();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
return true;
}
}
So far I have a java app where I draw a circle(player) and then draw a green rectangle on top(gun barrel). I have it so when the player moves, the barrel follows with it. I want it to find where the mouse is pointing and then rotate the barrel accordingly. For an example of what I mean look at this video I found http://www.youtube.com/watch?v=8W7WSkQq5SU See how the player image reacts when he moves the mouse around?
Here's an image of what the game looks like so far:
So how do I rotate it like this? Btw I don't like using affinetransform or Graphics2D rotation. I was hoping for a better way. Thanks
Using the Graphics2D rotation method is indeed the easiest way. Here's a simple implementation:
int centerX = width / 2;
int centerY = height / 2;
double angle = Math.atan2(centerY - mouseY, centerX - mouseX) - Math.PI / 2;
((Graphics2D)g).rotate(angle, centerX, centerY);
g.fillRect(...); // draw your rectangle
If you want to remove the rotation when you're done so you can continue drawing normally, use:
Graphics2D g2d = (Graphics2D)g;
AffineTransform transform = g2d.getTransform();
g2d.rotate(angle, centerX, centerY);
g2d.fillRect(...); // draw your rectangle
g2d.setTransform(transform);
It's a good idea to just use Graphics2D anyway for anti-aliasing, etc.
Using AffineTransform, sorry, only way I know how :P
public class RotatePane extends javax.swing.JPanel {
private BufferedImage img;
private Point mousePoint;
/**
* Creates new form RotatePane
*/
public RotatePane() {
try {
img = ImageIO.read(getClass().getResource("/MT02.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double rotation = 0f;
int width = getWidth() - 1;
int height = getHeight() - 1;
if (mousePoint != null) {
int x = width / 2;
int y = height / 2;
int deltaX = mousePoint.x - x;
int deltaY = mousePoint.y - y;
rotation = -Math.atan2(deltaX, deltaY);
rotation = Math.toDegrees(rotation) + 180;
}
int x = (width - img.getWidth()) / 2;
int y = (height - img.getHeight()) / 2;
g2d.rotate(Math.toRadians(rotation), width / 2, height / 2);
g2d.drawImage(img, x, y, this);
x = width / 2;
y = height / 2;
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.RED);
g2d.drawLine(x, y, x, y - height / 4);
g2d.dispose();
}
}
Will produce this effect
The red line (point out from the center) will want to follow the cursor.
I am making a tictactoe android application . After making on customview called TicTacToeGFX I tried to make an onTouchEvent which (after taking into account) the coordinates of the touch , it would fill the corresponding rectangle with the bitmap circle or cross. The Problem is that in the onTouchEvent I cannot redraw the canvas with the desired Bitmap. So my question is How to I re-draw a canvas after an onTouchEvent?
public class NewGame extends Activity {
TicTacToeGFX Game;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Game = new TicTacToeGFX(this);
setContentView(Game);
}
}
public class TicTacToeGFX extends View {
int x, y;
int rectanglescounter = 0;
public Rect[] rectangles = new Rect[9];
// BitMap
Bitmap cross = BitmapFactory.decodeResource(getResources(),
R.drawable.cross1);
Bitmap circle = BitmapFactory.decodeResource(getResources(),
R.drawable.circle1);
Bitmap empty = BitmapFactory.decodeResource(getResources(),
R.drawable.empty1);
Paint paint = new Paint();
Canvas canvas = new Canvas();
public TicTacToeGFX(Context context) {
super(context);
setFocusable(true);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// -------------------------------------------calculate
// screen------------------------------------------------------
x = (int) ((getWidth()) / 3);
y = (int) ((getHeight()) / 3);
// //------------------------------------------- calculate rectangle
// positions on
// screen------------------------------------------------------
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rectangles[rectanglescounter] = new Rect((x * j), (y * i),
((x * j) + x), ((y * i) + y));
if (rectanglescounter < 8)
rectanglescounter++;
else
break;
}
}
// ------------------------------------------- draw the canvas with
// empty Bitmap
// ------------------------------------------------------
int counter = 0;
canvas.drawRGB(0, 0, 0);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
canvas.drawBitmap(empty, null, rectangles[counter], null);
counter++;
}
}
// ------------------------------------------- draw
// LinesS------------------------------------------------------
paint.setColor(Color.WHITE);
canvas.drawLine(x, 0, x, 3 * y, paint);// 1h
canvas.drawLine(2 * x, 0, 2 * x, 3 * y, paint);// 2h
canvas.drawLine(0, y, 3 * x, y, paint);// 3h
canvas.drawLine(0, 2 * y, 3 * x, 2 * y, paint);// 4h
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
x = (int) event.getX();
y = (int) event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
Toast.makeText(getContext(), "Hello", 1).show();
canvas.drawRGB(0, 0, 0);
invalidate();
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
// move the balls the same as the finger
break;
}
return true;
}
}
I have a problem with canvas.drawBitmap and canvas.drawRect when i use canvas.drawRect everything works fine but when i use canvas.drawBitmap that when thing start to get strange. The size of the object drawn on the screen are not the same size for DrawRect as for DrawProcentObject. I haven't been able to find a problem with the math in my code so i guess the problem lies in how canvas.drawBitmap works.
I would be grateful if someone could tell me what the problem is and how to solve it.
The width, height is the size of the object here, bmp is a bitmap.
DrawRect(canvas, width, height, x, y, Color.BLACK);
DrawProcentObject(canvas, bmp, x, y, width, height);
the width, height in this method are the screen resolution.
public void DrawObject(Canvas canvas, Bitmap bmp, int X, int Y) {
canvas.save();
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
canvas.drawBitmap(bmp, X, Y, paint);
canvas.restore();
}
public void DrawProcentObject(Canvas canvas, Bitmap bmp, int X, int Y, int SizeWidth, int SizeHeight)
{
double x = width * ((double)X/1000);
double y = height * ((double)Y/1000);
double sizeWidth = width * ((double)SizeWidth/1000);
double sizeHeight = height * ((double)SizeHeight/1000);
bmp = Bitmap.createScaledBitmap(bmp, (int) sizeWidth, (int) sizeHeight, true);
DrawObject(canvas, bmp, (int) x, (int) y);
}
public void DrawRect(Canvas canvas, int SizeWidth, int SizeHeight, int X, int Y, int rectColer)
{
canvas.save();
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setColor(rectColer);
canvas.drawRect(ProcentRect(SizeWidth, SizeHeight, X, Y), paint);
canvas.restore();
}
public Rect ProcentRect(int SizeWidth, int SizeHeight, int X, int Y)
{
double x = width * ((double)X/1000);
double y = height * ((double)Y/1000);
double sizeWidth = width * ((double)SizeWidth/1000);
double sizeHeight = height * ((double)SizeHeight/1000);
Rect rect = new Rect((int)x, (int)y, (int)x + (int)sizeWidth, (int)y + (int)sizeHeight);
return rect;
}