不知道是否有人能指出我正确的方向。
我希望能够将一个对象(如子弹)从静态位置移动到屏幕上的任何区域。
我对简单的水平和垂直移动没有任何问题。 IE。 x +/- 1 或 y +/- 1。 但是,当涉及到像子弹这样的物体可以在任何程度上移动/动画时,我不太确定如何通过使动画看起来平滑来做到这一点。例如,在 18、45 或 33 度角时,像 y+1、x+1、y+1..... 这样的算法不会使动画非常平滑。
提前致谢
P.s 也许已经有一些文档了?
更新
感谢所有回复的人。
这是我迄今为止根据您的评论编写的代码。
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 SurfaceHolder 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);
}
}
}
}
}
}
绘图工作得很好,但有两个问题。
1. 与这个 java 示例 http://www.youtube.com/watch?v=-g5CyPQlIo4 相比,绘图相当缓慢且跳跃...
2.如果点击的是接近Y = 0的位置,那么由于ENDY/FRAME的值小于1,意味着向上舍入为0并且项目符号穿过屏幕顶部,而不是 Y 中偶尔的增量。
@SyntaxT3rr0r 你说得对,这可能是最好的方法。但是您知道有任何实现此类功能的文档吗?
再次感谢所有回复的人
最佳答案
我的理解是,您询问的是如何确定每帧移动子弹的 x&y 像素数,而不是询问 Android 上动画特定的实现细节。
简短的回答:用数学攻击它:P 以项目符号为例:
-您可以将动画切碎为“将动画分成 100 帧,尽可能快地播放它们”或“在大约 2 秒内播放动画,在这 2 秒内尽可能多地粉碎帧” ”。我将解释前者,因为这听起来像是您想要做的。
从起始 X 和 Y 以及结束 X 和 Y 开始:假设您想要从 0,0 移动到 200,400,并且想要在大约 100 帧动画中完成此操作。
将沿 X 轴行进的总距离除以帧数。对沿 Y 轴的总距离执行相同的操作。现在您就有了每一帧的 x 和 y 行进距离。对于本示例,您希望项目符号每帧横向移动 2 个像素(200 像素/100 帧),垂直每帧移动 4 个像素(400 像素/100 帧)。所以每一帧,添加 x +=2, y+=4。
关于Java/Android 子弹对象流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337389/