美文网首页
Android之鱼塘开发笔记

Android之鱼塘开发笔记

作者: CarlosLynn | 来源:发表于2021-04-02 18:43 被阅读0次

    1,需求开发一个按照固定轨迹游泳的鱼池

    2,实现思路

    ViewGroup + ImageView组合,通过定时刷新,不断对子view位置进行摆放处理

    • 2.1,定时刷新采用Handler定时发送消息
    • 2.2,收到消息后调用ViewGrouprequestLayout()触发回调onLayout(boolean changed, int left, int top, int right, int bottom)函数
    • 2.3,重写ViewGroup的onLayout方法,调用子View的layout()函数不断进行位置放.最终形成鱼宠不断游动效果.

    3,鱼宠游动轨迹图

    device-2021-04-02-103933.png

    4,坐标点的测试

    P0,
    x:990,y:1065
    P0x:990, P0y:1065
    
    P1,
    x:540,y:572
    P1x:540, P1y:572
    
    P2,
    x:90,y:572
    P2x:90, P2y:572
    
    P3,
    x:990,y:80
    P3x:990, P3y:80
    
    P4,
    x:990,y:572
    P4x:990, P4y:572
    
    P5,
    x:990,y:80
    P5x:990, P5y:990
    
    P6,
    x:90,y:80
    P6x:90, P6y:80
    
    P7,
    x:990,y:572
    P7x:990, P7y:572
    
    P8,
    x:540,y:572
    P8x:540, P8y:572
    
    P9,
    x:90,y:1065
    P9x:90, P9y:1065
    
    P10,
    x:90,y:572
    P10x:90, P10y:572
    
    P11,
    x:90,y:1065
    P11x:90, P11y:1065
    
    P12,
    x:990,y:1065
    P12x:990, P12y:1065
    

    5,鱼宠游动状态的定义

    /**
     * 鱼儿的游动状态
     */
    @IntDef({
            FishStatus.UN_KNOW,
            FishStatus.TURN_LEFT,
            FishStatus.TURN_RIGHT,
            FishStatus.MOVE_LEFT,
            FishStatus.MOVE_RIGHT,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface FishStatus {
        /**
         * 未知状态
         */
        int UN_KNOW = -1;
        /**
         * 向左转
         */
        int TURN_LEFT = 0;
        /**
         * 向右转
         */
        int TURN_RIGHT = 1;
        /**
         * 向左正常游动
         */
        int MOVE_LEFT = 2;
        /**
         * 向右正常游动
         */
        int MOVE_RIGHT = 3;
    }
    

    5,对鱼宠游动过程坐标点进行监听,当游动到了路线轨迹坐标点处进行处理并且修改游动状态

    • 5.1坐标点对应鱼宠游动状态分析

    • P0和P12坐标重合
      P0开始向左游动,P12开始向左转身

    • P1和P8坐标重合
      P1,P8分别停留1秒钟

    • P2和P10坐标重合
      P2开始向右转身,P10向下游

    • P3和P5坐标重合
      P3向下游,P5开始向左转身

    • P4和P7坐标重合
      P4开始向上游动,P7开始向左转身,

    • P9和P11坐标重合
      P9开始向上游动,P11开始向右转身

    -P6单独坐标点
    P6开始向右转身

    • 5.2相邻两坐标点的轨迹的游动状态分析

    • 1,P0--->P1
      向左上方移动

    • 2,P1--->P2
      向左方移动

    • 3,P2--->P3
      向右上方移动

    • 3,P3--->P4
      向下方移动

    • 4,P4--->P5
      向上方移动

    • 5,P5--->P6
      向左方移动

    • 6,P6--->P7
      向右下方移动

    • 7,P7--->P8
      向左方移动

    • 8,P8--->P9
      向左下方移动

    • 9,P9--->P10
      向上方移动

    • 10,P10--->P11
      向下方移动

    • 10,P11--->P12
      向右方移动

    • 5.3如何判断鱼宠坐标点是否在指定的坐标处.

    • 1,鱼宠坐标和P0坐标相等,也和P12坐标相等,不同时刻的路线坐标值存在相同情况,根据坐标值无法判定是否处于指定的坐标处.

    • 2,鱼宠游动方向向左,游动方向由坐标点驱动,无法用于判断是否处于坐标点处.

    • 3,定义private var progress = 0.0F变量,表示移动路线的进度,每个坐标点对应一个进度值.

      • P0,progress=0
      • P12,progress=1
    • 4,如何建立坐标点和路线进度的映射关系

      这里我们采用,keyvalue键值对形式来保存映射关系,用key来表示进度值progress,用value来表示指定坐标点容器索引posotion,
      (0.0,0),(1.0,12),综合分析无法建立较完善的映射关系,该方式无法用来判定是否处于指定坐标处.

    • 5,根据坐标点距离起点的总长度来判定坐标点

      P0:pLength = 0,P1:pLength = (P1.x-P0.x) * (P1.x-P0.x) + (P1.y-P0.y) * (P1.y-P0.y)开根号.

    • 6,根据坐标点范围以及游动状态组合判断

    /**
     * 根据移动的坐标点和轨迹坐标点来修改小鱼的游动状态.
     * @param x
     * @param y
     * @param distance 距离起点的直线距离.
     */
    private fun onSwimming(x: Float, y: Float, distance: Float) {
        if (pointList.isEmpty()) return
    
        if (distance == 0F || progress == 0F) {
            //P0,点处开始向左上游动.
            changeSwimming(FishStatus.TURN_LEFT)
            changeSwimming(FishStatus.MOVE_TOP_LEFT)
        }
    
        if (isInPointRect(pointList[1], x, y)) {
            //P1,P8处停留
            changeSwimming(FishStatus.REST)
        } else {
            when (lastFishStatus) {
                FishStatus.MOVE_TOP_LEFT -> {
                    if (fishStatus == FishStatus.REST) {
                        changeSwimming(FishStatus.MOVE_LEFT)
                    }
                }
    
                FishStatus.MOVE_LEFT -> {
                    if (fishStatus == FishStatus.REST) {
                        changeSwimming(FishStatus.MOVE_BOTTOM_LEFT)
                    }
                }
    
                else -> {
                    when {
                        //P2,P10
                        //P2点处向右转身,开始向右游动.
                        isInPointRect(pointList[2], x, y) -> {
                            //判定该点位于此P2
                            if (fishStatus == FishStatus.MOVE_LEFT) {
                                if (fishStatus != FishStatus.MOVE_TOP_RIGHT) {
                                    changeSwimming(FishStatus.TURN_RIGHT)
                                    changeSwimming(FishStatus.MOVE_TOP_RIGHT)
                                }
                            }
                            //P10->p11,下游
                            if (fishStatus == FishStatus.MOVE_TOP_ON_LEFT) {
                                changeSwimming(FishStatus.MOVE_BOTTOM_ON_LEFT)
                            }
                        }
    
                        //P3,P5,
                        isInPointRect(pointList[3], x, y) -> {
                            //P3,下游
                            if (fishStatus == FishStatus.MOVE_TOP_RIGHT) {
                                changeSwimming(FishStatus.MOVE_BOTTOM_ON_RIGHT)
                            }
                            //P5点处向左转身,开始向左游动.
                            if (fishStatus == FishStatus.MOVE_TOP_ON_RIGHT) {
                                changeSwimming(FishStatus.TURN_LEFT)
                                changeSwimming(FishStatus.MOVE_LEFT)
                            }
                        }
    
                        //P4,P7,
                        isInPointRect(pointList[4], x, y) -> {
                            //P4,上游
                            if (fishStatus == FishStatus.MOVE_BOTTOM_ON_RIGHT) {
                                changeSwimming(FishStatus.MOVE_TOP_ON_RIGHT)
                            }
                            //P7点处向左转身,开始向左游动.
                            if (fishStatus == FishStatus.MOVE_BOTTOM_RIGHT) {
                                changeSwimming(FishStatus.TURN_LEFT)
                                changeSwimming(FishStatus.MOVE_LEFT)
                            }
                        }
    
                        //P6,
                        isInPointRect(pointList[6], x, y) -> {
                            //P6点处向右转身,开始向右游动.
                            if (fishStatus == FishStatus.MOVE_LEFT) {
                                changeSwimming(FishStatus.TURN_RIGHT)
                                changeSwimming(FishStatus.MOVE_BOTTOM_RIGHT)
                            }
                        }
    
                        //P9,P11,
                        isInPointRect(pointList[9], x, y) -> {
                            //P9,垂直向上游
                            if (fishStatus == FishStatus.MOVE_BOTTOM_LEFT) {
                                changeSwimming(FishStatus.MOVE_TOP_ON_LEFT)
                            }
                            //P11,向右转身,向右移动
                            if (fishStatus == FishStatus.MOVE_BOTTOM_ON_LEFT) {
                                changeSwimming(FishStatus.TURN_RIGHT)
                                changeSwimming(FishStatus.MOVE_RIGHT)
                            }
                        }
                    }
                }
            }
        }
    }
    
    • 5.4鱼宠还正在向左游动就向边转身了的视觉异常处理

    • 6采用SurfaceView方案来增加动画的流畅性.

    • 7动画运行相关参考资料

    https://github.com/blipinsk/ViewPropertyObjectAnimator

    一款强大的属性动画操作集合
    https://github.com/paulyung541/ActionAnimatorSet

    小船游动效果
    https://github.com/WANZIzZ/RowingView

    方块移动,飞机移动
    https://github.com/Jetpack-Missionary/MotionChallenge

    赛车动画
    https://github.com/VKOOY/AnimationRacingCarForKotlin

    SurfaceView实现墨迹天气的风车效果
    https://blog.csdn.net/xyz_lmn/article/details/20483709

    SurfaceView实现下雨与下雪动画效果(Kotlin语法)
    https://www.jb51.net/article/123687.htm

    SurfaceView实现鱼儿游动动画
    https://www.jb51.net/article/138961.htm

    SurfaceView实现红包雨平移动画
    http://www.zyiz.net/tech/detail-62558.html

    Android自定义View实现抖音飘动红心效果
    https://www.jb51.net/article/187575.htm

    Android十个小案例动画,自定义View动画实现,ValueAnimator
    https://blog.csdn.net/u012835548/article/details/53887607

    Android属性动画 - 平移动画
    https://blog.csdn.net/u010349644/article/details/101151809

    https://github.com/heqiangflytosky/AndroidAnimationDemo

    相关文章

      网友评论

          本文标题:Android之鱼塘开发笔记

          本文链接:https://www.haomeiwen.com/subject/rjmfkltx.html