Android卡牌翻转动画效果实现

Android卡牌翻转动画效果实现

简述

之前项目有个需求,需要实现卡牌翻转效果,自己试着写过,效果不是很好,后来找到了一个Rotatable-master的项目,使用里面提供的类实现了卡牌翻转的效果。默认情况下,翻转动画卡牌在动画进行中的拉伸变形幅度会很大,可以通过setCameraDistance方法来改变控件的应该说是观察点距离吧,让观察点远一点,这样反转动画看起来会舒服一点。

效果图

效果图

代码

.java 旋转工具类
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.support.annotation.IntDef;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.DisplayMetrics;
import android.util.Property;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.CycleInterpolator;

import java.util.ArrayList;

/**
 * 旋转工具类
 * Created by Yahya Bayramoglu on 01/12/15.
 */
public class Rotatable implements View.OnTouchListener {
   

    private static final int NULL_INT = -1;
    private final int FIT_ANIM_TIME = 300;

    public static final int DEFAULT_ROTATE_ANIM_TIME = 500;
    public static final int ROTATE_BOTH = 0;
    public static final int ROTATE_X = 1;
    public static final int ROTATE_Y = 2;

    @IntDef({ROTATE_X, ROTATE_Y, ROTATE_BOTH})
    public @interface Direction {
   
    }

    public static final int FRONT_VIEW = 3;
    public static final int BACK_VIEW = 4;

    @IntDef({FRONT_VIEW, BACK_VIEW})
    public @interface Side {
   
    }

    private RotationListener rotationListener;
    private View rootView, frontView, backView;

    private boolean touchEnable = true;
    private boolean shouldSwapViews = false;

    private int rotation;
    private int screenWidth = NULL_INT, screenHeight = NULL_INT;
    private int currentVisibleView = FRONT_VIEW;

    private float rotationCount;
    private float rotationDistance;
    private float oldX, oldY, currentX, currentY;
    private float currentXRotation = 0, currentYRotation = 0;
    private float maxDistanceX = NULL_INT, maxDistanceY = NULL_INT;
    private float defaultPivotX = NULL_INT, defaultPivotY = NULL_INT;

    private Rotatable(Builder builder) {
        this.rootView = builder.root;
        this.defaultPivotX = rootView.getPivotX();
        this.defaultPivotY = rootView.getPivotY();
        this.rotationListener = builder.listener;

        if (builder.pivotX != NULL_INT) {
            this.rootView.setPivotX(builder.pivotX);
        }

        if (builder.pivotY != NULL_INT) {
            this.rootView.setPivotY(builder.pivotY);
        }

        if (builder.frontId != NULL_INT) {
            this.frontView = rootView.findViewById(builder.frontId);
        }

        if (builder.backId != NULL_INT) {
            this.backView = rootView.findViewById(builder.backId);
        }

        this.rotation = builder.rotation;
        this.rotationCount = builder.rotationCount;
        this.rotationDistance = builder.rotationDistance;
        this.shouldSwapViews = frontView != null && backView != null;

        rootView.setOnTouchListener(this);
    }

    /**
     * This method needs to be call, if only you need to reset and
     * rebuild a view as rotatable with different configurations
     */
    public void drop() {
        rootView.setPivotX(defaultPivotX);
        rootView.setPivotY(defaultPivotY);
        rootView.setOnTouchListener(null);
        rootView = null;
        frontView = null;
        backView = null;
    }

    /**
     * You can specify rotation direction as axis X, Y or BOTH
     */
    public void setDirection(@Direction int direction) {
        if (!isRotationValid(direction)) {
            throw new IllegalArgumentException("Cannot specify given value as rotation direction!");
        }
        this.rotation = direction;
    }

    /**
     * You may need to enable / disable touch interaction at some point,
     * so it is possible to do it so anytime by rotatable object
     */
    public void setTouchEnable(boolean enable) {
        this.touchEnable = enable;
    }

    /**
     * To determine rotatable object is currently touchable or not
     */
    public boolean isTouchEnable() {
        return touchEnable;
    }

    /**
     * If your application can be used multi orientated, then you have to declare
     * orientation changes to rotatable object, so it can recalculate its maxDistances.
     * <p>
     * You only need to inform rotatable object about orientation changes, when you specified
     * {@link Builder#rotationCount(float)} or {@link Builder#rotationDistance(float)}
     */
    public void orientationChanged(int newOrientation) {
        
  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
实现这个效果,你需要使用Unity中的DoTween插件和卡牌的2D图片。以下是实现步骤: 1. 将卡牌的2D图片导入到Unity中,并在场景中创建一个空物体来作为卡牌的父物体。 2. 在卡牌父物体上添加一个Box Collider 2D组件,用来检测鼠标点击事件。 3. 创建两个子物体,一个用于显示卡牌的正面,另一个用于显示卡牌的反面,将它们分别作为卡牌父物体的子物体,并将它们的位置和大小设置为相同。 4. 在正面和反面子物体上添加Sprite Renderer组件,并分别将卡牌正面和反面的精灵设置到Sprite Renderer的Sprite属性中。 5. 使用DoTween库中的DOTween.Sequence()方法创建一个序列,将卡牌旋转到反面并缩放到0,然后再次旋转到正面并缩放回原大小。这个序列应该绑定到卡牌父物体的鼠标点击事件。 6. 在代码中,使用一个bool变量来记录卡牌当前是否是正面。在鼠标点击事件中,根据卡牌是否是正面来判断应该播放哪个动画序列。 以下是示例代码: ``` using UnityEngine; using System.Collections; using DG.Tweening; public class CardFlip : MonoBehaviour { public Sprite cardFront; public Sprite cardBack; private bool isFront = true; void OnMouseDown() { if (isFront) { // Play flip to back animation DOTween.Sequence() .Append(transform.DOScaleX(0, 0.25f)) .AppendCallback(() => { GetComponent<SpriteRenderer>().sprite = cardBack; }) .Append(transform.DOScaleX(1, 0.25f)); isFront = false; } else { // Play flip to front animation DOTween.Sequence() .Append(transform.DOScaleX(0, 0.25f)) .AppendCallback(() => { GetComponent<SpriteRenderer>().sprite = cardFront; }) .Append(transform.DOScaleX(1, 0.25f)); isFront = true; } } } ``` 在这个示例代码中,我们假设卡牌的父物体上挂载了一个名为CardFlip的脚本,并将卡牌正面和反面的2D图片分别赋值给cardFront和cardBack变量。在OnMouseDown()方法中,我们使用DOTween.Sequence()方法创建了两个动画序列,一个用于将卡牌翻转到反面,另一个用于将卡牌翻转回正面。每次点击卡牌时,根据isFront变量的值来判断应该播放哪个动画序列,并更新isFront的值以记录卡牌当前是否是正面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值