Wonder if anyone could point me in the right direction.
I want to be able to animate an object like a bullet from a static position to any area on the screen.
I have no problem with simple horizontal and vertical movements. I.e. x +/- 1 or y +/- 1. But when it comes to an object like a bullet could move/animate at any degree I'm not quite sure how to do this by making the animation look smooth. For example at 18, 45, or 33 degree angle an algorithm like y+1, x+1, y+1..... Is not going to make the animation very smooth.
Thanks in advance
P.s maybe there is some documentation out there already?
Update
Thanks to everyone who has replied.
This is the code I have so far based on your comments.
package com.bullet;
//imports go here
public class canvas extends SurfaceView implements OnTouchListener, SurfaceHolder.Callback{
private Bitmap bullet;
private int bulletStartX, bulletStartY;
private int bulletX, bulletY;
private int bulletEndX = -1;
private int bulletEndY = -1;
private int incX = 0;
private int incY = 0;
private SurfaceHold开发者_开发知识库er holder;
private Thread t;
public canvas(Context context) {
super(context);
this.setBackgroundColor(Color.WHITE);
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);
bulletStartX = 0;
bulletStartY = 0;
bulletX = bulletStartX;
bulletY = bulletStartY;
bullet = BitmapFactory.decodeResource(getResources(), R.drawable.bullet);
holder = getHolder();
holder.addCallback(this);
}
public void onDraw(Canvas canvas){
if(bulletEndX != -1 && bulletEndY != -1){
Log.e("here", "drawing bullet");
Log.e("here", "x: " + bulletX + ", y: " + bulletY);
canvas.drawBitmap(bullet, bulletX, bulletY, null);
}
}
public void updateBullet(){
Log.e("here", "inc bullet");
bulletX += incX;
bulletY += incY;
if(bulletX > bulletEndX){
bulletEndX = -1;
}
if(bulletY > bulletEndY){
bulletEndY = -1;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int[] coordinates = {(int) event.getX(), (int) event.getY()};
int motion = event.getAction();
switch(motion){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
bulletX = bulletStartX;
bulletY = bulletStartY;
bulletEndX = (int) event.getX();
bulletEndY = (int) event.getY();
incX = (int) bulletEndX / 50;
incY = (int) bulletEndY / 50;
Log.e("here", "touch up");
break;
}
return true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
t = new GameThread(this, holder);
t.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
//Thread class
class GameThread extends Thread{
private canvas canvas;
private SurfaceHolder holder;
private boolean run = false;
long delay = 70;
public GameThread(canvas canvas, SurfaceHolder holder){
this.holder = holder;
this.canvas = canvas;
startThread(true);
}
public boolean isRunning(){
return this.run;
}
private void startThread(boolean run){
this.run = run;
}
public void stopThread(){
this.run = false;
}
@Override
public void run(){
while(run){
Canvas c = null;
try {
//lock canvas so nothing else can use it
c = holder.lockCanvas(null);
synchronized (holder) {
//clear the screen with the black painter.
//This is where we draw the game engine.
//Log.e("drawthread", "running");
if(bulletEndX != -1 && bulletEndY != -1){
updateBullet();
canvas.postInvalidate();
}
canvas.onDraw(c);
//Log.e("drawthread", "ran");
try {
sleep(32);
//Log.e("slept", "sleeping");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
}
}
}
}
The drawing works pretty well, however there are two problems.
1. the drawing is fairly slow and jumpy... compared to something like this java example http://www.youtube.com/watch?v=-g5CyPQlIo4
2. If the click is on a position to close to Y = 0 then due to the value of ENDY / FRAME being less that 1, means that the round up is to 0 and the bullet travels across the top of the screen, rather than the ocassionaly increment in Y.
@SyntaxT3rr0r your right, that is prob the best way to go about it. But do you know of any documentation for implementing something like this?
Thanks again to everyone who replied
My understanding is that you're asking how to determine how many x&y pixels to move the bullet per frame, as opposed to asking about implementation details specific to animating on Android.
The short answer: Attack it with Math :P With the example of the bullet:
-You can either chop up the animation as "divide up the animation into 100 frames, play them as fast as we can" or "Play the animation in about 2 seconds, smash as many frames in those 2 seconds as you can." I'm going to explain the former, because that sounds like what you're trying to do.
Start out with a starting X & Y, and an ending X & Y: Let's pretend you want to move from 0,0 to 200,400, and you want to do it in about 100 frames of animation.
Divide up the total distance travelled along the X axis by the number of frames. Do the same with total distance along Y axis. Now you have the distance to travel x & y for each frame. For this example, you want the bullet to move 2 pixels per frame (200 pixels / 100 frames) sideways, and 4 pixels per frame (400 pixels / 100 frames) vertically. So every frame, add x +=2, y+=4.
I suggest you to read the following articles:
View Animation and Property Animation
I don't think this can be answered in it's current form. First how are you animating? are you using the graphics API? GL? AndEngine?
If is graphics API I would rotate the canvas the appropriate degree and move the bullet up the y axis.
For GL you can do the same thing.
For and engine, refer to the tutorials.
精彩评论