Android自定义控件绘制鱼,并且模拟鱼游动

本文详细介绍了如何使用Android的自定义Drawable实现一条游动的鱼动画。通过绘制路径、贝塞尔曲线和动画更新,创建了鱼的头部、身体、鱼鳍和尾巴,并实现了鱼的摆动效果。文章中还展示了相关的代码实现,包括鱼的游动角度调整、身体摆动等关键功能。通过对Path、Canvas和动画API的运用,加深了对Android图形绘制和动画的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整体代码鱼的游动还是不太明白,抄的享学老师的代码,先这样吧
先上效果图:
在这里插入图片描述

在这里插入图片描述
画鱼的代码

package com.lgj.xxkt.ui;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import retrofit2.http.HEAD;

public class FishDrawable extends Drawable {
    public FishDrawable() {
        init();
    }

    private Path mPath;
    private Paint mPaint;
    private int OTHER_ALPHA = 110;
    // 鱼头的半径
    private float HEAD_RADIUS = 50;
    // 鱼的开始角度
    private float fishMainAngle = 90;
    // 身体长度
    private float BODY_LENGTH = HEAD_RADIUS * 3.2f;
    // 寻找鱼鳍的起始点坐标的线长
    private float find_fins_length = 0.9f * HEAD_RADIUS;
    // 鱼鳍的长度
    private float fins_length = 1.3f * HEAD_RADIUS;
    // 大圆的半径
    private float big_radius = 0.7f * HEAD_RADIUS;
    // 中圆的半径
    private float middle_radius = 0.6f * big_radius;
    // 小圆的半径
    private float small_radius = 0.4f * middle_radius;
    // --寻找尾部中圆圆心的线长
    private final float FIND_MIDDLE_CIRCLE_LENGTH = big_radius * (0.6f + 1);
    // --寻找尾部小圆圆心的线长
    private final float FIND_SMALL_CIRCLE_LENGTH = middle_radius * (0.4f + 2.7f);
    // --寻找大三角形底边中心点的线长
    private final float FIND_TRIANGLE_LENGTH = middle_radius * 2.7f;

    private float currentValue;

    private PointF middlePoint;
    PointF headPoint;
    public PointF getCenterPoint(){
        return middlePoint;
    }
    public PointF getControlOne(){
        return headPoint;
    }
    public float getHeadRadius(){
        return HEAD_RADIUS;
    }
    private float frequence = 1f;
    public void setFrequence(float frequence) {
        this.frequence = frequence;
    }

    public float getFishMainAngle() {
        return fishMainAngle;
    }

    public void setFishMainAngle(float fishMainAngle) {
        this.fishMainAngle = fishMainAngle;
    }

    private void init() {
        mPath = new Path();
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setARGB(OTHER_ALPHA, 244, 92, 71);
        // 鱼的中心,PointF 和 Point 的区别是,PointF是float类型
        middlePoint = new PointF(4.19f * HEAD_RADIUS, 4.19f * HEAD_RADIUS);
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 3600f);
        animator.setDuration(15 * 1000);
        // 重复的模式: 重新开始
        animator.setRepeatMode(ValueAnimator.RESTART);
        // 重复的次数,无限次
        animator.setRepeatCount(ValueAnimator.INFINITE);
        // 插值器,匀速
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentValue = (float) valueAnimator.getAnimatedValue();
                invalidateSelf();
            }
        });
        animator.start();
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        // 每一个部分都以鱼的中心位置的相对坐标来的
        // 鱼头的计算坐标,x = cosA * c   y = sinA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值