如何处理安卓国际象棋应用程序中的拖动?

8
我刚开始学习开发Android应用(使用Java,在Android Studio中),并且正在进行一个小项目,只是为了好玩。我想创建自己的国际象棋应用程序,目前为止我已经做了很多事情。我设置了一个菜单来切换到另一个活动,即游戏本身,我还制作了一个自定义视图和一个自绘棋盘,我认为我的模型也几乎完成了。唯一我不明白的是如何处理拖动。因此,当您使用拖动手势从一个位置移动一枚棋子到另一个位置时,如何获得起点和终点?
如上所述,我已经在我的模型中实现了移动(使用函数move(Position start, Position end)),并且它也检查该移动是否对于某个棋子有效,但我仍然需要的是让我在实际棋盘上拖动一枚棋子的东西。
我曾考虑在我的控制器类中放置一个onDrag方法,但我不知道如何解决它,并且在互联网上找不到好的示例。我已经着手解决这个问题了,但不知道它是否有用。
你能帮我实现拖拽吗?
谢谢!
附注: 如果需要,我还会在我的问题中添加自定义视图和(尚未完成的)控制器的代码。如果您需要更多我的代码来回答这个问题,我也会将其放在这里,请让我知道。
public class ChessView extends View implements Observer {
    private Game game;
    private static final Paint WHITE_PAINT = new Paint(), BLACK_PAINT = new Paint();

    public ChessView(Context context) {
        super(context);
        init();
    }

    public ChessView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ChessView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void init() {
        WHITE_PAINT.setColor(Color.rgb(200, 159, 77));
        BLACK_PAINT.setColor(Color.rgb(61, 34, 18));
    }

    public void setGame(Game game) {
        if (this.game != null)
            this.game.deleteObserver(this);

        this.game = game;
        this.game.addObserver(this);
    }

    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (game == null)
            return;

        drawBoard(canvas);
        drawPieces(canvas);
    }

    public void drawBoard(Canvas canvas) {
        int tilesize = Math.min(getWidth(), getHeight())/8;

        for (int i = 0; i < 8; i++)
            for (int j = 0; j < 8; j++) {
                Paint paint = ((i + j) % 2 == 0) ? WHITE_PAINT : BLACK_PAINT;

                canvas.drawRect(i*tilesize, j*tilesize,(i+1)*tilesize, (j+1)*tilesize, paint);
            }
    }

    public void drawPieces(Canvas canvas) {
        for (int i = 0; i < game.getBoard().boardSize(); i++)
            for (int j = 0; j < game.getBoard().boardSize(); j++) {
                Position pos = new Position(i, j);
                Piece p = game.getBoard().getPiece(pos);

                if (p != null)
                    drawPiece(canvas, p, pos);
                else
                    clearPos(canvas, pos);
            }
    }

    public void drawPiece(Canvas canvas, Piece piece, Position position) {
        switch (game.getBoard().getPiece(position).getId()) {
            case ("wpawn"): drawPicture(canvas, position, R.drawable.wpawn); break;
            case ("bpawn"): drawPicture(canvas, position, R.drawable.bpawn); break;
            case ("wrook"): drawPicture(canvas, position, R.drawable.wrook); break;
            case ("brook"): drawPicture(canvas, position, R.drawable.brook); break;
            case ("wknight"): drawPicture(canvas, position, R.drawable.wknight); break;
            case ("bknight"): drawPicture(canvas, position, R.drawable.bknight); break;
            case ("wbishop"): drawPicture(canvas, position, R.drawable.wbishop); break;
            case ("bbishop"): drawPicture(canvas, position, R.drawable.bbishop); break;
            case ("wqueen"): drawPicture(canvas, position, R.drawable.wqueen); break;
            case ("bqueen"): drawPicture(canvas, position, R.drawable.bqueen); break;
            case ("wking"): drawPicture(canvas, position, R.drawable.wking); break;
            case ("bking"): drawPicture(canvas, position, R.drawable.bking); break;
            default: break;
        }
    }

    public void drawPicture(Canvas canvas, Position position, int picture) {
        int tilesize = Math.min(getHeight(), getWidth())/8, x = position.getY(), y = position.getX();
        Drawable d = ResourcesCompat.getDrawable(getResources(), picture, null);
        Bitmap b = ((BitmapDrawable) d).getBitmap();

        canvas.drawBitmap(b, null, new Rect(x*tilesize, y*tilesize,(x + 1)*tilesize, (y + 1)*tilesize), null);
    }

    public void clearPos(Canvas canvas, Position position) {
        int tilesize = Math.min(getWidth(), getHeight())/8, x = position.getY(), y = position.getX();

        Paint paint = ((position.getX() + position.getY()) % 2 == 0) ? WHITE_PAINT : BLACK_PAINT;

        canvas.drawRect(x*tilesize, y*tilesize, (x + 1)*tilesize, (y + 1)*tilesize, paint);
    }

    @Override
    public void update(Observable observable, Object data) {
        this.postInvalidate();
    }
}

public class Controller extends Observable implements View.OnDragListener {
    private Game game;

        public Controller(Game game) {
            this.game = game;
        }

        @Override
        public boolean onDrag(View v, DragEvent event) {

            float startx = event.getX();
            float starty = event.getY();

            if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {

            }

            return false;
        }
    }

如果你正在开发游戏,那么可以尝试使用像AndEngine、libGdx等游戏引擎。 - darwin
1个回答

1
希望这样的东西能够给你一个想法:
@Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ...               
            view.startDrag(clipData, dsb, view, 0);
            ...
            return true;
        } else {
            return false;
        }
    }

 @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        int dragAction = dragEvent.getAction();
        View dragView = (View) dragEvent.getLocalState();
        if (dragAction == DragEvent.ACTION_DRAG_EXITED) {
            containsDragable = false;
        } else if (dragAction == DragEvent.ACTION_DRAG_ENTERED) {
            containsDragable = true;
        } else if (dragAction == DragEvent.ACTION_DROP && containsDragable){
            //your function to move and check valid moves
            dragView.setVisibility(View.VISIBLE);
        }
        return true;
    }

参考:https://www.javacodegeeks.com/2011/12/android-drag-and-drop-tutorial.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接