Android 推箱子人物移动


实现

MainActivity.java

    /**
     * 划动方向即工人移动方向
     * */
    class Controller implements View.OnTouchListener {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                oldX = (int) motionEvent.getX();
                oldY = (int) motionEvent.getY();
                return true;
            }
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                newX = (int) motionEvent.getX();
                newY = (int) motionEvent.getY();

                if (newX - oldX > threshold) {
                    gameView.menMove(1,0);      // right
                } else if (oldX - newX > threshold) {
                    gameView.menMove(-1,0);     // left
                } else if (newY - oldY > threshold) {
                    gameView.menMove(0,1);      // up
                } else if (oldY - newY > threshold) {
                    gameView.menMove(0,-1);     // down
                }

                gameView.invalidate();
                return true;
            }
            return false;
        }
    }

GameView.java

  • 因为地图大小是20*20,而示例中没有统一变量定义,所以直接使用魔法数字
  • 该段代码可以拓展进行障碍物和通关检测
    /**
     * 移动坐标
     * */
    public void menMove(int menMoveX, int menMoveY) {
        int testX = menX + 2 * menMoveX, testY = menY + 2 * menMoveY;
        // 边缘检测
        if (testY < 20 && testX < 20 && testX >= 0 && testY >= 0) {
            int nextAttr = mymap[menY + menMoveY][menX + menMoveX];
            // 用绿地覆盖当前工人位置(无障碍检查)
            mymap[menY][menX] = 2;
            // 如果下一个单位是 箱子, 则移动的再下一个位置为箱子(无障碍检查)
            if (nextAttr == 3) {
                mymap[menY + 2 * menMoveY][menX + 2 * menMoveX] = 3;
            }
            // 下一个位置为工人
            menX += menMoveX;
            menY += menMoveY;
            mymap[menY][menX] = 5;
        }
    }

效果

推箱子1
推箱子2

基于示例代码修改

说明

  • drawable目录:放置图标 box.gif、greenbox.gif、men.gif
  • raw目录:放置map0.map
  • 地图说明:2表示绿地、5表示人物、3表示箱子

地图map0.map示例

22222222222222222222222222222222222222222252222222222222222222222222222222222222222223222222222222222222222223222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

修改后MainActivity.java示例

  • 需要根据屏幕大小修改绘图坐标坐标值
  • 以监听自定义图形组件的划动方向,明确人物移动
public class MainActivity extends AppCompatActivity {
    GameView gameView; // 自定义图形组件
    int initX = 70;  //绘图时第一个图像的坐标
    int initY = 50;
    int oldX, oldY, newX, newY, threshold = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBitmap();
    }
    public void initBitmap()
    {
        gameView = new GameView(this);
        this.setContentView(gameView);
        gameView.setOnTouchListener(new Controller());
    }
    /**
     * 划动方向即工人移动方向
     * */
    class Controller implements View.OnTouchListener {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                oldX = (int) motionEvent.getX();
                oldY = (int) motionEvent.getY();
                return true;
            }
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                newX = (int) motionEvent.getX();
                newY = (int) motionEvent.getY();

                if (newX - oldX > threshold) {
                    gameView.menMove(1,0);      // right
                } else if (oldX - newX > threshold) {
                    gameView.menMove(-1,0);     // left
                } else if (newY - oldY > threshold) {
                    gameView.menMove(0,1);      // up
                } else if (oldY - newY > threshold) {
                    gameView.menMove(0,-1);     // down
                }

                gameView.invalidate();
                return true;
            }
            return false;
        }
    }
}

修改后GameView.java示例

  • 需要根据屏幕大小修改箱子坐标值,以及该tx = 2 + 60 * j、ty = 2 + 60 * i的值(60的大小)
  • 通过初始化条件initflag判断人物移动后将重绘图像,不再获取地图文件数据进行绘制
public class GameView extends View {
    int[][] mymap = new int[20][20]; //存放地图文件中图片位置坐标
    int[] map;           //存放地图文件中的图片编号
    String mapstr;       //存放地图文件数据
    Bitmap men;   //工人
    Bitmap greenBox;  //草地
    Bitmap box;    //箱子
    Paint paint;
    int tx = 120;  //箱子的坐标
    int ty = 120;
    int menX, menY; // 工人移动坐标
    boolean initFlag = true;

    public GameView(Context context) {
        super(context);
        paint = new Paint();
        men = BitmapFactory.decodeResource(getResources(), R.drawable.men);  //工人
        greenBox = BitmapFactory.decodeResource(getResources(), R.drawable.greenbox); //草地
        box = BitmapFactory.decodeResource(getResources(), R.drawable.box); //箱子
    }
    /**
     * 移动坐标
     * */
    public void menMove(int menMoveX, int menMoveY) {
        int testX = menX + 2 * menMoveX, testY = menY + 2 * menMoveY;
        // 边缘检测
        if (testY < 20 && testX < 20 && testX >= 0 && testY >= 0) {
            int nextAttr = mymap[menY + menMoveY][menX + menMoveX];
            // 用绿地覆盖当前工人位置(无障碍检查)
            mymap[menY][menX] = 2;
            // 如果下一个单位是 箱子, 则移动的再下一个位置为箱子(无障碍检查)
            if (nextAttr == 3) {
                mymap[menY + 2 * menMoveY][menX + 2 * menMoveX] = 3;
            }
            // 下一个位置为工人
            menX += menMoveX;
            menY += menMoveY;
            mymap[menY][menX] = 5;
        }
    }

    String map()  //读取地图文件
    {
        String mapdata = "";
        try {
            InputStream in_file = getResources().openRawResource(R.raw.map0);  //输入流对象读取地图文件
            int length = in_file.available();    //获取数据流的字节数
            byte[] buffer = new byte[length];
            int bytes = in_file.read(buffer);   //产生读取数据的动作
            mapdata = new String(buffer, 0, bytes);  //把地图文件数据转换为字符串存放到mapdata中
        } catch (IOException e) {
        }
        return mapdata;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.CYAN);//设置背景颜色
        paint.setColor(Color.argb(255, 220, 220, 220)); //灰白色
        this.myDraw(canvas);
    }

    public void myDraw(Canvas canvas)  //绘制图形
    {
        if (initFlag) {
            initFlag = false;
            mapstr = map();   //获取地图文件数据
            byte[] d = mapstr.getBytes();  //把字符串生成字节数组
            int len = mapstr.length();
            int[] map = new int[len];
            for (int i = 0; i < mapstr.length(); i++) {
                map[i] = d[i] - 48;   //字节数组中存放的ASCII码值,转换为数字要减48
                //数字0所对应的ASCII码值为48,数字1的ASCII码值为49,…………
            }
            int k = 0;
            for (int i = 0; i < 10; i++)  //将地图中的数据与图片编号对应
            {
                for (int j = 0; j < 20; j++) {
                    mymap[i][j] = map[k];
                    if (mymap[i][j] == 2)  //草地
                    {
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(greenBox, tx, ty, paint);  //绘制图形
                    }
                    if (mymap[i][j] == 3)  //箱子
                    {
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(box, tx, ty, paint);  //绘制图形
                    }
                    if (mymap[i][j] == 5)  //工人
                    {
                        menX = j;
                        menY = i;
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(men, tx, ty, paint);  //绘制图形
                    }
                    k++;
                }
            }
        } else {
            for (int i = 0; i < 10; i++)  //将地图中的数据与图片编号对应
            {
                for (int j = 0; j < 20; j++) {
                    if (mymap[i][j] == 2)  //草地
                    {
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(greenBox, tx, ty, paint);  //绘制图形
                    }
                    if (mymap[i][j] == 3)  //箱子
                    {
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(box, tx, ty, paint);  //绘制图形
                    }
                    if (mymap[i][j] == 5)  //工人
                    {
                        menX = j;
                        menY = i;
                        tx = 2 + 60 * j;
                        ty = 2 + 60 * i;
                        canvas.drawBitmap(men, tx, ty, paint);  //绘制图形
                    }
                }
            }
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值