2

想知道是否有人能指出我正确的方向。

我希望能够将像子弹一样的对象从静态位置动画到屏幕上的任何区域。

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

提前致谢

Ps 也许已经有一些文档了?


更新

感谢所有回复的人。

这是我迄今为止根据您的评论获得的代码。

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 你的权利,这可能是最好的方法。但是你知道任何实现这样的东西的文档吗?

再次感谢所有回复的人

4

3 回答 3

2

我的理解是,您问的是如何确定每帧移动子弹多少 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。

于 2011-06-13T23:44:58.673 回答
1

我建议你阅读以下文章:

查看动画属性动画

于 2011-06-13T23:26:49.033 回答
1

我认为这不能以目前的形式回答。首先,你是如何制作动画的?你在使用图形 API 吗?GL? 和引擎?

如果是图形 API,我会将画布旋转适当的角度并将子弹向上移动 y 轴。

对于 GL,您可以做同样的事情。

对于和引擎,请参阅教程。

于 2011-06-13T23:27:44.877 回答