Java/Android bullet对象流

Java/Android bullet对象流,java,android,canvas,2d,bulletphysics,Java,Android,Canvas,2d,Bulletphysics,不知是否有人能给我指出正确的方向 我希望能够将一个对象(如子弹)从静态位置动画化到屏幕上的任何区域 我对简单的水平和垂直运动没有问题。即x+/-1或y+/-1。 但是,当涉及到像子弹这样的物体可以在任何程度上移动/设置动画时,我不太确定如何通过使动画看起来平滑来做到这一点。例如,在18度、45度或33度角时,使用类似于y+1、x+1、y+1….的算法。。。。。不会使动画非常平滑 提前谢谢 另外,可能已经有一些文件了 更新 感谢所有回复的人 这是我根据你的评论编写的代码 package com.

不知是否有人能给我指出正确的方向

我希望能够将一个对象(如子弹)从静态位置动画化到屏幕上的任何区域

我对简单的水平和垂直运动没有问题。即x+/-1或y+/-1。 但是,当涉及到像子弹这样的物体可以在任何程度上移动/设置动画时,我不太确定如何通过使动画看起来平滑来做到这一点。例如,在18度、45度或33度角时,使用类似于y+1、x+1、y+1….的算法。。。。。不会使动画非常平滑

提前谢谢

另外,可能已经有一些文件了


更新

感谢所有回复的人

这是我根据你的评论编写的代码

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示例相比

2.如果点击位置接近Y=0,则由于ENDY/FRAME的值小于1,这意味着取整为0,且子弹穿过屏幕顶部,而不是Y中的局部增量

@SyntaxT3rr0r您的权利,这可能是最好的方式去做。但是,您知道实现这种功能的任何文档吗


再次感谢所有回复的人

我建议您阅读以下文章:


而且

我认为目前的形式无法回答这个问题。首先,你是如何制作动画的?您正在使用图形API吗?德国劳埃德船级社?安德林

如果是图形API,我会将画布旋转适当的角度,并沿y轴向上移动项目符号

对于德国劳埃德船级社,你也可以做同样的事情


有关和引擎,请参阅

我的理解是,您询问的是如何确定每帧移动项目符号的x&y像素数,而不是询问Android上动画的具体实现细节

简单的回答是:用数学攻击它:p 以子弹为例:

-你可以将动画分割为“将动画分割成100帧,尽可能快地播放”或“在大约2秒钟内播放动画,在这2秒钟内尽可能多地粉碎帧”。我将解释前者,因为这听起来像你要做的

从开始的X&Y和结束的X&Y开始:让我们假设您想要从0,0移动到200400,并且您想要在大约100帧的动画中完成


将沿X轴行驶的总距离除以帧数。对沿Y轴的总距离执行相同操作。现在您有了每个帧的x&y移动距离。对于本例,您希望项目符号横向移动每帧2像素(200像素/100帧),垂直移动每帧4像素(400像素/100帧)。所以每一帧,加上x+=2,y+=4。

屏幕坐标!=世界坐标。游戏通常使用任意坐标系,然后将你的对象转换为屏幕坐标以适应你的屏幕(例如,你可以在线玩星际争霸2对一个对手,比如说1280x960或1600x1200,它不会改变你对手的yota:因为你仍然在同一个任意游戏坐标系中玩)。计算子弹在大于屏幕坐标的坐标系中的位置。这只是一个开始,并不是一个答案,因此评论。