image movement along a defined path in android - android

I am making a learning game for teaching numbers to kindergarten kids. It requires some animation like this but I am failing in achieving this animation smoothly in canvas.
I want exactly the same animation appearing using this dotted line.
Please guide me to perform exactly this type of animation.

What you need is:
a loop
path definition
The loop should update current image position and rotation. Then draw the updated animation on a screen. You can just override dispatchDraw method and call invalidate at the very end of it. You can update position right before drawing. Your case is similar to game programming, so you can look for articles about game loops.
Path definition should allow you to calculate position depending on time. Fo example you can use Bezier curves. Bezier curve equation is parametric and the parameter is 'time'. Using the animation time gives you smooth movement along the path.
Example of a generic game loop: http://www.gameprogblog.com/generic-game-loop/
Bezier curve: http://en.wikipedia.org/wiki/B%C3%A9zier_curve
long time = System.currentTimeMillis();
protected void dispatchDraw(Canvas canvas) {
PointF pos = getBezierPos(System.currentTimeMillis() - time);
drawImage(pos);
invalidate();
}

Related

Simultaneously move six points in circular paths around their own orbital centers

Suppose I have six points drawn in a Canvas along the circumference of a circle, in the pattern of a hexagon.
I want to simultaneously move and re-draw each of these six points in a small circular path - for example, each point moves along the circumference of a circle with 1/10th the radius of the larger circle.
I'm a little lost on how to do this with Canvas and onDraw and I don't know if better solutions exist. How would you do this?
Some answers have at least pointed me toward this which shows how a point might move along a circular path, but I don't know how to implement it for this situation:
for (double t = 0; t < 2*Pi; t += 0.01)
{
x = R*cos(t) + x_0;
y = R*sin(t) + y_0;
}
Thank you!
Here's one approach:
Start with a custom view that extends View and overrides onDraw. You are on the right track with using the drawing functions of Canvas.
Give your custom view a field to hold the current angle:
private float mTheta;
Then add a method like:
public void setTheta(float radians) {
mTheta = radians;
invalidate();
}
Then in onDraw, use the current value of mTheta to calculate the position of your points.
Of course, with the custom view you might need to handle sizing with an onMeasure override and possibly some layout with an onLayout override. If you set the dimensions of the view to an absolute dp value, the default behavior should work for you.
Doing it this way will set you up to override onTouch and allow user interaction to move the graphics, or use a ValueAnimator to cycle from 0 to 2π calling setTheta from within your AnimatorUpdateListener.
Put some code together and when you get stuck, post another question. If you add a comment to this answer with a link to the new question, I'll take a look at it.

Android libGDX moving object and detect

I just started experimenting libgdx and understanding... I looked sample projects... My problem :
The 1 and 6 originial ball number. And other balls, the ball's(1 and 6) will go randomly other places. (speed 1). ex . If a i am torch on the any ball, its speed up to 3...
The GameObjects should be in while loop. Ball images sometimes (randomly), the balls should be retun own 360 degrees. And get picture on TectureRegion.
Is there a similar example ? or
How can I do this ?
(Sorry for bad english)
Thanks...
As much as i understood you want your ball objects to move arround until you quit the game. Also you want to speed them up on touch right? Also you want to texture them and maybe they should detect collision with the screen borders and other balls to?
Libgdx has a main loop. This loop calls render(delta) every renderloop. The delta depends on the time ellapsed since last call of render. So on fast devices this delta is smaller then on slow devices (most times). This time is given in seconds. To move your objects you can add a value to their position in every render loop. In your case you want to add 1 (hopefully not pixel, as it then would seem slower on big screens):
for(BallObject ball : ballObjects) {
ball.setPositionX(ball.getPositionX() + ball.getSpeed() * delta * direction.x);
ball.setPositionY(ball.getPositionY() + ball.getSpeed() * delta * direction.y);
}
In this case a BallObject has a positionX and positionY describing his current position, a direction.x and direction.y, describing his movement in x and y direction (for 45° it would be direction.x=0.5 and direction.y=0.5), as well as a speed describing movement per second. This speed will be set to 3 on touch.
To speed the ball up on touch, you first need to implement InputProcessor in the class, which manages the movement of all ballobjects. Next you have to set it as the InputProcessor of the game: Gdx.input.setInputProcessor(this);. The InputProcessor has a method touchDown(int x, int y) or something like that. The x and y value are giving the coordinates in pixels, on the screen.
If you are using a camera or viewport in the new Libgdx version (you should do that) you have to use camera.unproject(x,y) or the viewport version of that (idk the exact method name). This method gives you the touchposition in your world coordinate system. Then you can simply check which ball is on this touchpos and set its speed to 3.
To texture the ball you have to use SpriteBatch for drawing. Look at the different draw() methods in the API and use the one which fits best for you. Just load a Texture, which should be a ".png" with a circle texture and the rest of it should be transparent (alpha = 0). With blending enabled (default) it will then only render the ball, even if it is actually a rectangle shaped Texture.
I hope it helps

How do i animate an image in android so it follows a path made of several coordinate?

I found out that the movement of an image between two point can be achieved with this simple code:
ImageView image_to_move = (ImageView) findViewById(R.id.image_to_move);
TranslateAnimation animation = new TranslateAnimation(50, 100, 50, 100);
animation.setDuration(5000);
image_to_move.startAnimation(animation);
The image is an ImageView set initially in position (0,0) inside a FrameLayout and the code move it from the point (50,50) to (100,100).
What if i have to move it on a path, made of several point, in the form of absolute coordinate (x,y)? For example, move from (50,50) to (75,75) then to (100,100)
There's a way to pass to the translating function an array of coordinate or i have simply to iterate the animation for every couple of points?
Btw, i saw that if i don't initially locate the image in (0,0) the function moves the image in a weird way, like the coordinate i give are not read as absolute. Am i missing something?
EDIT: The last thing happens when i pass as parameters to the TranslateAnimation something like "n92.getX()" where n92 is a button on my frame layout, from which position i want the animation to start.
DETAIL: Just to understand better the problem: I am implementing the animation of a point moving on a map, to show the user how to get from one point to another of a map. That's why i have absolute coordinate (the reachable points) that must be followed (you can't arrive from one point to another without following a precise path on the map)
to do so you need to Calculate the position on a quadratic bezier curve. try this answer it might be work for you

How to keep the same speed of object when number of object increase?

Im doing a game and I'm using SurfaceView. In the game I have 25 small dots that are moving around. The goal is to make a game where the player draw a circle around some of the dots with the same color. My problem is that while I draw this circle and after I have lift my finger from the screen, all the dots are moving very, very slow! I guess the reason for this is all the line segmets that are being drawn constantly together with all the dots.
Is it possible to have the same moving speed of the dots all the time? I tested with SystemClock.Sleep(1) but it didn't helped much.
// Method to draw objects
private void drawObjects(Canvas canvas) {
SystemClock.sleep(1);
synchronized (this) {
// Clear screen with black color
canvas.drawRGB(0, 0, 0);
// Draw line
if(startDrawLine) {
// Set properties to Paint object
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
// Draw path
path.moveTo(touchDownX, touchDownY);
for(Point point: points) {
path.lineTo(point.x, point.y);
canvas.drawPath(path, paint);
}
path.reset();
}
}
// Call method draw() in CircleManager to draw all circles in list
circleManager.drawCirclesInList(canvas);
}
Slow drawing is caused by to many points in your path.
If you are handling Touch event, you can expect hundreds and thousands of touches (your points) in short period of time.
You need to interpolate your points somehow - take averages, ignore same and close points or something else.
When you animate the "dots" your ANIMATION MUST BE BASED ON TIME, and not on the actual speed of the drawing on hardware.
To base your animation on time, you should calculate time passed since previous frame and use this time in function which calculates new position of the dot.
Here is a great article on the subject:
http://www.koonsolo.com/news/dewitters-gameloop/
EDIT - Response to a comment:
Suppose that your "dot" (I will call it a ball) needs to move horizontally (by X) from left to right at a constant speed of 100 units per second.
If you are doing your calculation WITH ASSUMPTION that your game will be running at 25 FPS, you simply add 4 to X on each frame.
The problem with this approach is that getting constant FPS is very hard to achieve.
On the fast hardware you will be sacrificing smoothness by limiting FPS,
on slow hardware you will be forced to skip drawing (drop) some frames (which can be jumpy with constant FPS).
Timer in Android is not very precise and also thread sleep functions are inaccurate.
In your case, instead of trying to force the constant FPS or calculate current FPS, try to wrap your head around and rethink of your problem
in a context of time.
When you think about time, it does not matter how fast is the game
running (how many FPS) and what happened before.
You just need to ask a question "Where the ball should be in this
moment, right now?"
If you, for example, know that ball movement stared at origin position X0 at origin time T0 then at the current moment TC ball position should be X = (TC - T0) * 100
Second approach is to measure time passed TD since last ball position update. Then the ball position should be updated like this: X = X + TD * 100
Once you get used to this approach, you will see that vast majority of animations is really trivial to implement with a great level of accuracy.

Collision Detection working half the time

I am trying to check collisions between two arrays, one of moving rectangles and the other of stationery boundaries (trying to get the rectangles to bounce off the walls).
The problem is that I wrote a nested for loop that seems to work for 2 out of 4 boundaries. Is my loop not reaching all possible combinations?
Here is my loop:
for(int n=0;n<_f;n++){
for(int m=0;m<_b;m++){
if(farr[n].inter(barr[m]))
farr[n].setD();
}
}
_f counts the moving rectangles (starts at 0 and increases after each one is added) and _b counts the boundaries. The inter() is a method I am using to detect collisions and it has worked in all other parts of my program.
Any help would be greatly appreciated,
Thanks in advace!!!
public boolean inter(Rect rect){
if(Rect.intersects(rect, rec))
return true;
else
return false;
}
The setD() method:
public void setD(){
if(_d==0)
_d=2;
if(_d==1)
_d=3;
if(_d==2)
_d=0;
if(_d==3)
_d=1;
}
The move method where _d is used:
public void moveF(){
if(_d==0){_l+=_s;_r+=_s;}
if(_d==1){_t+=_s;_b+=_s;}
if(_d==2){_l-=_s;_r-=_s;}
if(_d==3){_t-=_s;_b-=_s;}
}
_l is left side, _t is top, _r is right, and _b is bottom, and _s is how many pixels it moves per iteration(set to 1 in all cases)
Assuming _f, _b, farr, and barr do not change during the execution of the loop, your loop checks all combinations exactly once. So how is it that you "check some collisions twice"? Does setD() do something sneaky? Do you mean that once a rectangle collides there is no need to check more boundaries? If so, that can be fixed with a simple break statement. Otherwise, there likely is a problem with your inter() method, independent as to whether or not it appears to work elsewhere. Can you post your inter implementation?
There is a possibility of another problem, that of assuming continuous properties in a discrete space. As my amazing ascii art (titled: ball and wall) skills demonstrate...
Frame 1:
o__|_
Frame 2:
_o_|_
Frame 3:
__o|_
Frame 4:
___|o
Notice that the ball passed through the wall! In no frame did the ball intersect the wall. This happens if your distance moved per frame can be roughly the same or larger than the characteristic size of your moving object. This is difficult to check for with a simple intersection check. You actually need to check the path that the ball occupied between frames.
If your rectangles and barriers are oriented without rotation, this is still a fairly easy check. Use the bounding rectangle of the moving rectangle between the two frames and intersect that with the barriers.
Other ideas:
You are double colliding, switching the direction twice.
Your rectangles are in two different coordinate spaces.
Some other thread is screwing with your rects.
But basically, your code looks good. How many rectangles do you have? Can you make them distinct colors? Then, in your loop, when you collide, call setD and output the color of the rectangle that collided, and where it was. Then, when you notice a problem, kill the code and look at the output. If you see two collisions in a row (causing the rect to switch directions twice), you'll have caught your bug. Outputting the coordinates might also help, on the off chance that you are in two different coordinate spaces.
If it's a threading issue, then it's time to brush up on critical sections.
Found your mistake:
public void setD(){
if(_d==0)
_d=2;
if(_d==1)
_d=3;
if(_d==2)
_d=0;
if(_d==3)
_d=1;
}
Each of these needs to be else if, otherwise you update 0 to become 2 and then 2 to become 0 in the same call.

Categories

Resources