从一点到另一点移动精灵

时间:2014-03-03 21:10:40

标签: java android

我想在两点之间移动一个精灵。

第一个点是x=0y=0,第二个点是用户触摸屏幕的点。

要移动,我想使用等式来检验y=ax+b这两个点。

我在方法move()中尝试过此操作,但精灵不会移动。

请帮忙。

班级显示:

package com.example.name;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Display extends SurfaceView {
private Bitmap bmp;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private Sprite sprite;
private long lastClick;
private float x = 0.0F;
private float y = 0.0F;

public Display(Context context) {
    super(context);

    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.gonia);
    sprite = new Sprite(this, bmp, x, y, x, y);

    gameLoopThread = new GameLoopThread(this);
    holder = getHolder();
    holder.addCallback(new SurfaceHolder.Callback() {

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            boolean retry = true;
            gameLoopThread.setRunning(false);
            while (retry) {
                try {
                    gameLoopThread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            gameLoopThread.setRunning(true);
            gameLoopThread.start();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,
                int width, int height) {
        }
    });

}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.BLACK);
    sprite.onDraw(canvas);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (System.currentTimeMillis() - lastClick > 500) {
        lastClick = System.currentTimeMillis();
        x = (float) sprite.ostatniaWartoscX();
        y = (float) sprite.ostatniaWartoscY();
        float gotox = (float) event.getX();
        float gotoy = (float) event.getY();
        synchronized (getHolder()) {
            sprite = new Sprite(this, bmp, x, y, gotox, gotoy);

        }
    }
    return true;
}

}

Class Sprite:

package com.example.name;

import android.graphics.Bitmap;
import android.graphics.Canvas;


public class Sprite {


private float a;
private float b;

private float x;
private float y;
private float gotox;
private float gotoy;
private int executeMove = 0;
private Display display;
private Bitmap bmp;


public Sprite(Display display, Bitmap bmp, float x, float y, float gotox,
        float gotoy) {
    this.display = display;
    this.bmp = bmp;
    this.x = x;
    this.y = y;
    this.gotox = gotox;
    this.gotoy = gotoy;
}

void update() {

    if (x < gotox) {x++;executeMove = 1;}
    if (x > gotox) {x--;executeMove = 1;}

    if (executeMove == 1) {move();}
    executeMove = 0;


}

void move() {
    float x1 = x;
    float y1 = y;
    float x2 = gotox;
    float y2 = gotoy;

    a = (y2-y1)/(x2-x1);
    b = y1 - x1*a;
    y = x1 * a + b;


}


public float ostatniaWartoscX() {
    return x;
}

public float ostatniaWartoscY() {
    return y;
}

public void onDraw(Canvas canvas) {
    update();
    canvas.drawBitmap(bmp, x, y, null);
}

}

谢谢!

2 个答案:

答案 0 :(得分:3)

您需要 Bresenham's line algorithm才能移动播放器。您甚至可以缩短它,只需要计算下一个动作(而不是整行)。这是一种简单/简单,低卡路里的算法。

您必须根据自己的需要进行调整。

public static ArrayList<Point> getLine(Point start, Point target) {
    ArrayList<Point> ret = new ArrayList<Point>();

    int x0 =  start.x;
    int y0 =  start.y;

    int x1 = target.x;
    int y1 = target.y;

    int sx = 0;
    int sy = 0;

    int dx =  Math.abs(x1-x0);
    sx = x0<x1 ? 1 : -1;
    int dy = -1*Math.abs(y1-y0);
    sy = y0<y1 ? 1 : -1; 
    int err = dx+dy, e2; /* error value e_xy */

    for(;;){  /* loop */
        ret.add( new Point(x0,y0) );
        if (x0==x1 && y0==y1) break;
        e2 = 2*err;
        if (e2 >= dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
        if (e2 <= dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
    }

    return ret;
}

答案 1 :(得分:2)

以下是我用于在两点之间移动对象的代码示例。

Math.atan2计算θ角度(-pi到+ pi),这是物体需要行进的轨迹。 Delta是此更新与上次更新之间的时间,速度是对象的所需速度。这些都需要相乘,然后加到当前位置以获得新的位置。

@Override
protected void update(float delta) {
        double theta = Math.atan2(targetPos.y - pos.y, targetPos.x - pos.x);

        double valX = (delta * velocity) * Math.cos(theta);
        double valY = (delta * velocity) * Math.sin(theta);

        pos.x += valX;
        pos.y += valY;
}