【问题标题】:Java/Android bullet object flowJava/Android 项目符号对象流
【发布时间】:2011-06-13 22:59:46
【问题描述】:

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

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

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

提前致谢

P.s 也许已经有一些文档了?


更新

感谢所有回复的人。

这是我目前根据您的 cmets 编写的代码。

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

再次感谢所有回复的人

【问题讨论】:

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

标签: java android canvas 2d bulletphysics


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我建议你阅读以下文章:

    View AnimationProperty Animation

    【讨论】:

      【解决方案3】:

      我认为目前的形式无法回答这个问题。首先,你是如何制作动画的?你在使用图形 API 吗? GL? AndEngine?

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

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

      关于和引擎,请参考tutorials.

      【讨论】:

        猜你喜欢
        • 2014-09-21
        • 1970-01-01
        • 1970-01-01
        • 2020-07-08
        • 2012-11-22
        • 2023-03-17
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多