IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 安卓精灵图 -> 正文阅读

[移动开发]安卓精灵图

安卓精灵图
今天找到了一个很好的安卓上播放精灵图的控件
https://www.wanandroid.com/blog/show/2551

在这里插入图片描述
然后我把它改写了一下 加入了一个pause方法,这样一开始也可以显示出来了,虽然一开始就调用一个叫做pause的方法让他初始化,感觉有点语义不明,反正能跑就算成功。。。

  public void pause() {
        mIsPause=true;
   
        mRunning = true;
        mRenderThread = new Thread(this);
        mRenderThread.start();
    }

于是他整个代码是这样的,并不是我写的 我只是加了一句 pause

package com.example.whatrubbish.util;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.example.whatrubbish.R;

public class SpriteAnimationView extends SurfaceView implements Runnable {
    private static final String TAG = "AnimationView";

    private static final String LEFT_TO_RIGHT = "left-to-right";
    private static final String RIGHT_TO_LEFT = "right-to-left";

    private Thread mRenderThread;

    private SurfaceHolder mSurfaceHolder;

    private volatile boolean mRunning;

    private boolean mIsPlaying;
    private boolean mIsPause;

    private Canvas mCanvas;

    private Paint mPaint;

    private Bitmap mBitmap;

    // Used to record last frame change time
    private long mLastFrameChangeTime;

    // Used to record current frame rate
    private long mFps;

    // Source frame rect (on the sprite sheet)
    private Rect mSrcFrameRect;

    // Destination frame rect (to be drawn)
    private RectF mDstFrameRect;

    // ---------------- user configurable parameters ----------------
    // Sprite sheet resource ID (e.g. R.drawable.rabbit)
    private int mSpriteSheet;

    // Each frame's width
    private int mFrameWidth = 300;

    // Each frame's height
    private int mFrameHeight = 150;

    // Frame count
    private int mFrameCount = 3;

    // Sprite sheet's row count
    private int mRowCount = 1;

    // Indicate which row of the sprite sheet should be used
    private int mRowIndex = 0;

    // Current frame index
    private int mCurrentFrame = 0;

    // Display duration of each frame (ms)
    private int mFrameDuration = 100;

    // Current offset on the sprite sheet
    private float mOffset = 0;

    // Moved offset per second
    private float mOffsetPerSecond = 250;

    // Play animation in place or not
    private boolean mInPlace = true;

    // Trigger the animation via touch event or not
    private boolean mTouchToMove = false;

    // Play animation in loop or not
    private boolean mPlayOnce = false;

    // Move direction (left-to-right or right-to-left)
    private String mDirection = LEFT_TO_RIGHT;

    public SpriteAnimationView(Context context) {
        this(context, null);
    }

    public SpriteAnimationView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SpriteAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        parseAttributes(context, attrs, defStyleAttr);

        mPaint = new Paint();
        mSurfaceHolder = getHolder();

        // Set transparent background
        mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
        setZOrderOnTop(true);

        // Load the Sprite bitmap
        mBitmap = BitmapFactory.decodeResource(this.getResources(), mSpriteSheet);

        // Scale the bitmap
        mBitmap = Bitmap.createScaledBitmap(mBitmap,
                mFrameWidth * mFrameCount,
                mFrameHeight * mRowCount,
                false);

        // Initialize frame rectangles
        mSrcFrameRect = new Rect(
                0,
                mFrameHeight * mRowIndex,
                mFrameWidth,
                mFrameHeight * (mRowIndex + 1));

        mDstFrameRect = new RectF();
    }

    private void parseAttributes(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.SpriteAnimationView, defStyleAttr, 0);
        //TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
        //        R.styleable.Spri, defStyleAttr, 0);
        for (int i = 0; i < a.getIndexCount(); i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.SpriteAnimationView_sprite_sheet:
                    mSpriteSheet = a.getResourceId(attr, mSpriteSheet);
                    break;
                case R.styleable.SpriteAnimationView_frame_width:
                    mFrameWidth = a.getDimensionPixelSize(attr, mFrameWidth);
                    break;
                case R.styleable.SpriteAnimationView_frame_height:
                    mFrameHeight = a.getDimensionPixelSize(attr, mFrameHeight);
                    break;
                case R.styleable.SpriteAnimationView_frame_count:
                    mFrameCount = a.getInteger(attr, mFrameCount);
                    break;
                case R.styleable.SpriteAnimationView_row_count:
                    mRowCount = a.getInteger(attr, mRowCount);
                    break;
                case R.styleable.SpriteAnimationView_row_index:
                    mRowIndex = a.getInteger(attr, mRowIndex);
                    break;
                case R.styleable.SpriteAnimationView_start_frame:
                    mCurrentFrame = a.getInteger(attr, mCurrentFrame);
                    break;
                case R.styleable.SpriteAnimationView_frame_duration:
                    mFrameDuration = a.getInteger(attr, mFrameDuration);
                    break;
                case R.styleable.SpriteAnimationView_offset_per_second:
                    mOffsetPerSecond = a.getDimensionPixelSize(attr, (int) mOffsetPerSecond);
                    break;
                case R.styleable.SpriteAnimationView_position:
                    mOffset = a.getDimensionPixelSize(attr, (int) mOffset);
                    break;
                case R.styleable.SpriteAnimationView_in_place:
                    mInPlace = a.getBoolean(attr, mInPlace);
                    break;
                case R.styleable.SpriteAnimationView_touch_to_move:
                    mTouchToMove = a.getBoolean(attr, mTouchToMove);
                    break;
                case R.styleable.SpriteAnimationView_play_once:
                    mPlayOnce = a.getBoolean(attr, mPlayOnce);
                    break;
                case R.styleable.SpriteAnimationView_direction:
                    mDirection = (a.getString(attr) != null ? a.getString(attr) : mDirection);
                    break;
            }
        }
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mOffset = (mDirection.equals(LEFT_TO_RIGHT) ? 0 : getMeasuredWidth() - mFrameWidth);
    }

    @Override
    public void run() {
        while (mRunning) {

            // Capture the current time in milliseconds in startFrameTime
            long frameStartTime = System.currentTimeMillis();

            // Update the frame
            updateFrame();

            // Draw the frame
            drawFrame();

            // Calculate fps based on frame drawing time
            long frameDrawingTime = System.currentTimeMillis() - frameStartTime;
            if (frameDrawingTime >= 1) {
                mFps = 1000 / frameDrawingTime;
                if (!mTouchToMove && !mIsPlaying) {
                    mIsPlaying = true;
                }
            }
        }

    }

    public void getCurrentFrame(){
        long time = System.currentTimeMillis();
        if (mIsPlaying) {
            if (time > mLastFrameChangeTime + mFrameDuration) {
                mLastFrameChangeTime = time;
                mCurrentFrame = (mCurrentFrame + 1) % mFrameCount;
            }
        }

        if(!mIsPause){
            // Update source frame rect
            mSrcFrameRect.left = mCurrentFrame * mFrameWidth;
            mSrcFrameRect.right = mSrcFrameRect.left + mFrameWidth;
        }

    }

    /**
     * 只能画出两种类型 左到右 或者右到左 ,如果精灵图不是 平着的一系列 就不行
     */
    public void updateFrame() {
        if (mIsPlaying && !mInPlace) {
            if (getMeasuredWidth() > 0) {
                switch (mDirection) {
                    case LEFT_TO_RIGHT:
                        // Update the offset based on fps
                        mOffset += (mOffsetPerSecond / mFps);
                        if (!mPlayOnce) {
                            // Wrap the offset to play animation repeatedly
                            mOffset %= getMeasuredWidth();
                        }
                        break;
                    case RIGHT_TO_LEFT:
                        // Update the offset based on fps
                        mOffset -= (mOffsetPerSecond / mFps);
                        if (!mPlayOnce) {
                            // Wrap the offset to play animation repeatedly
                            mOffset = mOffset > -mFrameWidth ? mOffset : mOffset + getMeasuredWidth();
                        }
                        break;
                }
            }
        }
    }

    public  void doDraw(){
        mCanvas = mSurfaceHolder.lockCanvas();

        // Clear background color
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        // Get source frame rect
        getCurrentFrame();

        // Set destination frame rect
        mDstFrameRect.set(mOffset,
                0,
                mOffset + mFrameWidth,
                mFrameHeight);

        // Draw bitmap from source to destination
        mCanvas.drawBitmap(mBitmap,
                mSrcFrameRect,
                mDstFrameRect, mPaint);

        mSurfaceHolder.unlockCanvasAndPost(mCanvas);
    }

    public void drawFrame() {
        if (mSurfaceHolder.getSurface().isValid()) {
            doDraw();
            //Log.d(TAG, "drawFrame: isValid");
            //mCanvas = mSurfaceHolder.lockCanvas();
            //
             Clear background color
            //mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            //
             Get source frame rect
            //getCurrentFrame();
            //
             Set destination frame rect
            //mDstFrameRect.set(mOffset,
            //        0,
            //        mOffset + mFrameWidth,
            //        mFrameHeight);
            //
             Draw bitmap from source to destination
            //mCanvas.drawBitmap(mBitmap,
            //        mSrcFrameRect,
            //        mDstFrameRect, mPaint);
            //
            //mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    public void stop() {
        mIsPlaying = false;
        mRunning = false;
        try {
            mRenderThread.join();
        } catch (InterruptedException e) {
            Log.e(TAG, "joining thread");
        }

    }

    public void pause() {
        mIsPause=true;
        //start();
        mRunning = true;
        mRenderThread = new Thread(this);
        mRenderThread.start();
    }
    public void start() {
        mIsPause=false;
        mRunning = true;
        mRenderThread = new Thread(this);
        mRenderThread.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent motionEvent) {
        if (mTouchToMove) {
            switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mIsPlaying = true;
                    break;
                case MotionEvent.ACTION_UP:
                    mIsPlaying = false;
                    break;
            }

            return true;
        } else {
            return super.onTouchEvent(motionEvent);
        }
    }

}

 <com.example.whatrubbish.util.SpriteAnimationView
        android:id="@+id/personWalk"
        app:frame_count="4"
        app:offset_per_second="@dimen/dp_32"
        app:frame_height="@dimen/dp_48"
        app:frame_width="@dimen/dp_32"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_48"
        app:sprite_sheet="@mipmap/miku_walk_left_to_right_whole_nb" />

因为我现在只要从左往右走的 第三行,所以ps了一下
然而其实不用ps 主要是我之前没有把他的文档看全,其实他是有 这种东西的,所以也就是说,我只要指定他是第三行就行了。。
不过这个我还没试过。。有机会试一试吧

app:row_count="2"                     // Sprite sheet的行数 (默认值为1)
app:row_index="1"                     // 播放sprite sheet的哪一行 (默认值为0)
<com.xinxin.spritesheetanimation.SpriteAnimationView
    android:id="@+id/animation_view"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    app:sprite_sheet="@drawable/antelope" // Sprite sheet的资源ID
    app:frame_count="4"                   // 帧数量 (默认值为3)
    app:frame_width="80dp"                // 每一帧的宽度 (默认值为300)
    app:frame_height="80dp"               // 每一帧的高度 (默认值为150)
    app:frame_duration="100"              // 每一帧的停留时长 (默认值为100ms)
    app:start_frame="0"                   // 起始帧的索引号 (默认值为0)
    app:row_count="2"                     // Sprite sheet的行数 (默认值为1)
    app:row_index="1"                     // 播放sprite sheet的哪一行 (默认值为0)
    app:offset_per_second="250"           // 每秒钟移动的偏移量 (默认值为250)
    app:position="0"                      // Sprite sheet的初始偏移量 (默认值为0)
    app:in_place="false"                  // 是否循环播放动画 (默认值为true)
    app:touch_to_move="false"             // 是否通过touch事件驱动动画 (默认值为false)
    app:direction="right-to-left"         // 移动方向 (默认值为left-to-right)
/>

以下是ps
在这里插入图片描述
ctrl j 新建图层
在这里插入图片描述
拖入素材
在这里插入图片描述
双击图片 取消自由变换,先在右边ctrl j 复制一个图层,防止错误操作导致事情变得可怕,然后选中我们要的第三行
在这里插入图片描述
再次ctrl j,然后下面两个图层不可见,发现只剩下这个图层,而这个图层是我们刚才选择的那部分。现在这个图层留作备用素材
在这里插入图片描述

再次新建一个文件
在这里插入图片描述

在这里插入图片描述
要根据这张图去计算他的参数
这里有四行 那么一个人的宽度是 128/4==32
高度是 192/4=48
宽度是四个人 128
高度 一个人的高度 48
在这里插入图片描述

alt 鼠标滚轮,放大一下
在这里插入图片描述
ctrl j 新建图层
在这里插入图片描述
在这里插入图片描述
把刚才剪辑好的图片拉进来
在这里插入图片描述
背景不可见 这样png 背景就是透明的
在这里插入图片描述
在这里插入图片描述
储存为 png 才会有背景透明效果
在这里插入图片描述
复制图片到 mipmap

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:11:02  更:2022-01-16 13:13:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:34:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码