I have a game where a ball is bounced.. I would like to replace the drawen ball with a soccer-ball in a png format.
I've tried lot of things but nothing worked.
Here is my code for drawing the ball :
public ball() {
position = new Vector(0.0f, 0.0f);
paused_velocity = velocity = new Vector(0.0f, 0.0f);
paused_acceleration = acceleration = new Vector(0.0f, gravity);
radius = 0.0f;
delta = 0;
ball_paint = PaintList.getRandPaint();
start_time = SystemClock.uptimeMillis();
}
public void draw(Canvas canvas) {
canvas.drawCircle(position.X(), position.Y(), radius, ball_paint);
}
thanks a lot
If you png is present a ball.png in your drawable directory..
public Bitmap getBallBitmap()
{
return BitmapFactory.decodeResource(getResources(),
R.drawable.ball);
}
#Override
protected void draw(Canvas canvas)
{
//ideally you should cache the value returned by getBallBitmap()
canvas.drawBitmap(getBallBitmap(),position.X(), position.Y(), null);
}
Note that you should use onDraw() method instead of draw() method as much as possible.
Related
I have an ImageView and I am trying to fade from one image to the next using this code:
Drawable bgs[] = new Drawable[2];
public void redraw(int[][] grid) {
bgs[0] = bgs[1];
bgs[1] = new GameDrawable(grid, prefs.colors);
if (bgs[0] == null) {
gameField.setImageDrawable(bgs[1]);
} else {
TransitionDrawable crossfader = new TransitionDrawable(bgs);
crossfader.setCrossFadeEnabled(true);
gameField.setImageDrawable(crossfader);
crossfader.startTransition(500);
}
}
gameField is correctly referenced as an ImageView.
gameDrawable simply extends Drawable and draws the grid.
On each move and action the new GameDrawable is being rendered correctly but there is no fading whatsoever. The new image is simply displayed instantaneously. I have tried lengthening the transition time and swapping the order of the drawables with no effect.
Any help on is appreciated.
Update: I have now set my transition to something ridiculously long like 500000. The first drawable shows for a few seconds and then suddenly the second drawable appears. So still no transition.
Update 2:
I think my Drawable might be implemented incorrectly, so I have attached the code.
public class GameDrawable extends Drawable {
private Paint paint = new Paint();
private float blockWidth = 1;
private int[][] myGrid;
private int myColor;
private List<Point> myPoints;
public GameDrawable(int[][] grid) {
super();
this.myGrid = grid;
this.myColor = colors[yourColor];
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.FILL);
paint.setAlpha(0);
this.myPoints = yourPoints;
}
#Override
public void draw(Canvas canvas) {
float height = getBounds().height();
float width = getBounds().width();
blockWidth = width / myGrid.length;
if (height / myGrid.length < blockWidth) {
blockWidth = height / myGrid.length;
}
for (int x = 0; x < myGrid.length; x++) {
for (int y = 0; y < myGrid[x].length; y++) {
paint.setColor(colors[myGrid[x][y]]);
canvas.drawRect(x * blockWidth, y * blockWidth, (x+1)*blockWidth, (y+1)*blockWidth, paint);
}
}
}
#Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
invalidateSelf();
}
#Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
invalidateSelf();
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
Looking at your code, I see a problem at the line
bgs[0] = bgs[1];
bgs[1] has not yet been defined before this line and so bgs[0] is null for the first method call. Because of this, (bgs[0] == null) is true, and so the later defined bgs[1] is directly set to the gameField ImageView.
Use corrected code below.
Drawable bgs[] = new Drawable[2];
Drawable firstDrawable = getResources().getDrawable(R.drawable.transparent);
public void redraw(int[][] grid) {
bgs[0] = firstDrawable;
bgs[1] = new GameDrawable(grid, prefs.colors);
firstDrawable = bgs[1];
TransitionDrawable crossfader = new TransitionDrawable(bgs);
crossfader.setCrossFadeEnabled(true);
gameField.setImageDrawable(crossfader);
crossfader.startTransition(500);
}
Note that TransitionDrawable does not work properly when the Drawable sizes are different. So you may need to resize firstDrawable beforehand.
EXTRA: I would avoid setCrossFadeEnabled(true) since the whole TransitionDrawable becomes translucent during the transition, revealing the background. Sometimes, this creates a "blinking" effect and destroys the smoothness of the transition.
EDIT: Looking at your custom Drawable implementation, I think the problem lies in the line
canvas.drawColor(Color.WHITE);
in the draw() method.
I looked at TransitionDrawable.java source and found that setAlpha is called on the drawables to get the cross fade effect. However, your canvas has a solid white color and setAlpha() only affects the paint. Hope this is your answer.
EDIT 2: The actual problem, as pointed out by Michael, was that TransitionDrawable's setAlpha() calls on the Drawables were rendered ineffective due to paint.setColor() in the GameDrawable's draw() method overriding the paint's alpha value set by the TransitionDrawable.
I have a function, y = 50sin(x/50) + 100.
Now what i want to do is to draw a curve for this function, but without any additional info from the graph plotters, I just need a wave on the screen. The X should correspond to my X parameter of the screen and Y to the Y parameter of the screen.
Here is the code of my current view.
public class Sinusoid extends View {
Paint paint = new Paint();
public Sinusoid(Context context) {
super(context);
paint.setColor(Color.RED);
}
#Override
public void onDraw(Canvas canvas) {
//todo draw the line using myFunction
}
private double myFunction(double x){
return 50 * Math.sin(x / 50) + 100;
}
}
Now the question is, what should i fill in my TODO?
Please help, any documentation or example will be very useful.
Thanks in advance.
The idea is to have something like this:
#Override
public void onDraw(Canvas canvas) {
for (int x=0; x<canvas.getWidth();x++) {
canvas.drawPoint(x,(float) myFunction(x),mPaint);
}
}
But you'll eventually need to adjust the value of your function given the canvas height.
Try something like this:
float xv=x0,yv= yo,x,y;
for (int i = 0; i < maxPoints; i++) {
x=i * scalex;
y=function(i)*scaley;
canvas.drawLine(xv, yv, x, y, paint);
xv=x;
yv=y;
}
The graphic will appears continuous.
Is there a better way of moving a canvas 600x3840 pixels left in a loop?
this is I've done so far
imagetwo = Bitmap.createBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.bckgr1));
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(imagetwo, x,y, null);
if (x==0){
x=x-3; y=0;}
else
{ x=x-3; y=0; }
if (x<-700)
{ x=0-3; y=0;}
else
{ x=x-3; y=0; }
invalidate();
}
Yes! Use an Animator:
http://developer.android.com/reference/android/animation/Animator.html
and a TranslateAnimation:
http://developer.android.com/reference/android/view/animation/TranslateAnimation.html
I want to make a small app. You will touch the screen and draw something and it will list points you pass and draw small green 3x3 rectangles for each fifth point. I use onTouchEvent for listing points using TextView and send it to setContentView. However, I have problem in drawing. I checked examples for drawing (onDraw) but I am not able to get it working for both printing point plus drawing green dots. Any help would be great, thanks.
Here you are, a quick sample of drawing on SurfaceView.
public class FunPanel extends SurfaceView {
class Point {
int X;
int Y;
public Point() {
X = Y = -1;
}
}
private ArrayList<Point> mPoints = new ArrayList<Point>();
private Point mCurPoint = new Point();
private Bitmap mBitmap = ....// your desired image
#Override
public void doDraw(Canvas canvas) {
if( !(mPoints.size() % 5) ) {
canvas.drawBitmap(mBitmap, mCurPoint.X, mCurPoint.Y, null);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mCurPoint.X = (int) event.getX() - mBitmap.getWidth() / 2;
mCurPoint.Y = (int) event.getY() - mBitmap.getHeight() / 2;
mPoints.add(mCurPoint);
return super.onTouchEvent(event);
}
}
It's not entirely clear what you're trying to do, but have a look at this It should get you started in the right direction. Basically extend a View and override the onDraw(Canvas) to draw the Rectangles and override the onTouchEvent(MotionEvent) to grab the touch points from the screen.
I would like to know if it's possible to select coordinates from a path to draw a bitmap over time, for example, I have an image of a sun, and I would like to move it, over time, along an arc path.
Is there some way to define a path like this and then move along it, so that I don't have to calculate it mathematically?
Thanks.
Yes, it's possible to move image along path. I will provide simple solution to show the principle. The following code will move and rotate your image. If you don't need rotation remove the TANGENT_MATRIX_FLAG flag.
import android.graphics.*;
//somewhere global
int iCurStep = 0;// current step
//don't forget to initialize
Path pathMoveAlong = new Path();
private static Bitmap bmImage = null;
#Override
protected void onDraw(Canvas canvas) {
Matrix mxTransform = new Matrix();
PathMeasure pm = new PathMeasure(pathMoveAlong, false);
float fSegmentLen = pm.getLength() / 20;//20 animation steps
if (iCurStep <= 20) {
pm.getMatrix(fSegmentLen * iCurStep, mxTransform,
PathMeasure.POSITION_MATRIX_FLAG + PathMeasure.TANGENT_MATRIX_FLAG);
canvas.drawBitmap(bmImage, mxTransform, null);
iCurStep++;
invalidate();
} else {
iCurStep = 0;
};
};
Here are the animators I use:
Purpose: Move View "view" along Path "path"
v21+:
ValueAnimator pathAnimator = ObjectAnimator.ofFloat(view, "x", "y", path)
v11+:
ValueAnimator pathAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
pathAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
float[] point = new float[2];
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float val = animation.getAnimatedFraction();
PathMeasure pathMeasure = new PathMeasure(path, true);
pathMeasure.getPosTan(pathMeasure.getLength() * val, point, null);
view.setX(point[0]);
view.setY(point[1]);
}
});
Similar requirement to: https://stackoverflow.com/a/30254715/4344057
I'm thinking of one solution:
_
/ \
If your arc has this kind of shape (meaning less than half a circle and positioned horizontaly) then you could iterate the x value and for that x get the y that's on the path. Then move your bitmap to that position.